• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_basic.h"
8 #if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
9 #include <sys/types.h>
10 #include <dirent.h>
11 #else
12 #include <direct.h>
13 #endif
~CFX_PrivateData()14 CFX_PrivateData::~CFX_PrivateData()
15 {
16     ClearAll();
17 }
FreeData()18 void FX_PRIVATEDATA::FreeData()
19 {
20     if (m_pData == NULL) {
21         return;
22     }
23     if (m_bSelfDestruct) {
24         delete (CFX_DestructObject*)m_pData;
25     } else if (m_pCallback) {
26         m_pCallback(m_pData);
27     }
28 }
AddData(FX_LPVOID pModuleId,FX_LPVOID pData,PD_CALLBACK_FREEDATA callback,FX_BOOL bSelfDestruct)29 void CFX_PrivateData::AddData(FX_LPVOID pModuleId, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback, FX_BOOL bSelfDestruct)
30 {
31     if (pModuleId == NULL) {
32         return;
33     }
34     FX_PRIVATEDATA* pList = m_DataList.GetData();
35     int count = m_DataList.GetSize();
36     for (int i = 0; i < count; i ++) {
37         if (pList[i].m_pModuleId == pModuleId) {
38             pList[i].FreeData();
39             pList[i].m_pData = pData;
40             pList[i].m_pCallback = callback;
41             return;
42         }
43     }
44     FX_PRIVATEDATA data = {pModuleId, pData, callback, bSelfDestruct};
45     m_DataList.Add(data);
46 }
SetPrivateData(FX_LPVOID pModuleId,FX_LPVOID pData,PD_CALLBACK_FREEDATA callback)47 void CFX_PrivateData::SetPrivateData(FX_LPVOID pModuleId, FX_LPVOID pData, PD_CALLBACK_FREEDATA callback)
48 {
49     AddData(pModuleId, pData, callback, FALSE);
50 }
SetPrivateObj(FX_LPVOID pModuleId,CFX_DestructObject * pObj)51 void CFX_PrivateData::SetPrivateObj(FX_LPVOID pModuleId, CFX_DestructObject* pObj)
52 {
53     AddData(pModuleId, pObj, NULL, TRUE);
54 }
RemovePrivateData(FX_LPVOID pModuleId)55 FX_BOOL CFX_PrivateData::RemovePrivateData(FX_LPVOID pModuleId)
56 {
57     if (pModuleId == NULL) {
58         return FALSE;
59     }
60     FX_PRIVATEDATA* pList = m_DataList.GetData();
61     int count = m_DataList.GetSize();
62     for (int i = 0; i < count; i ++) {
63         if (pList[i].m_pModuleId == pModuleId) {
64             m_DataList.RemoveAt(i);
65             return TRUE;
66         }
67     }
68     return FALSE;
69 }
GetPrivateData(FX_LPVOID pModuleId)70 FX_LPVOID CFX_PrivateData::GetPrivateData(FX_LPVOID pModuleId)
71 {
72     if (pModuleId == NULL) {
73         return NULL;
74     }
75     FX_PRIVATEDATA* pList = m_DataList.GetData();
76     int count = m_DataList.GetSize();
77     for (int i = 0; i < count; i ++) {
78         if (pList[i].m_pModuleId == pModuleId) {
79             return pList[i].m_pData;
80         }
81     }
82     return NULL;
83 }
ClearAll()84 void CFX_PrivateData::ClearAll()
85 {
86     FX_PRIVATEDATA* pList = m_DataList.GetData();
87     int count = m_DataList.GetSize();
88     for (int i = 0; i < count; i ++) {
89         pList[i].FreeData();
90     }
91     m_DataList.RemoveAll();
92 }
FX_atonum(FX_BSTR strc,FX_BOOL & bInteger,void * pData)93 void FX_atonum(FX_BSTR strc, FX_BOOL& bInteger, void* pData)
94 {
95     if (FXSYS_memchr(strc.GetPtr(), '.', strc.GetLength()) == NULL) {
96         bInteger = TRUE;
97         int cc = 0, integer = 0;
98         FX_LPCSTR str = strc.GetCStr();
99         int len = strc.GetLength();
100         FX_BOOL bNegative = FALSE;
101         if (str[0] == '+') {
102             cc++;
103         } else if (str[0] == '-') {
104             bNegative = TRUE;
105             cc++;
106         }
107         while (cc < len) {
108             if (str[cc] < '0' || str[cc] > '9') {
109                 break;
110             }
111             integer = integer * 10 + str[cc] - '0';
112             if (integer < 0) {
113                 break;
114             }
115             cc ++;
116         }
117         if (bNegative) {
118             integer = -integer;
119         }
120         *(int*)pData = integer;
121     } else {
122         bInteger = FALSE;
123         *(FX_FLOAT*)pData = FX_atof(strc);
124     }
125 }
FX_atof(FX_BSTR strc)126 FX_FLOAT FX_atof(FX_BSTR strc)
127 {
128     if (strc.GetLength() == 0) {
129         return 0.0;
130     }
131     int cc = 0;
132     FX_BOOL bNegative = FALSE;
133     FX_LPCSTR str = strc.GetCStr();
134     int len = strc.GetLength();
135     if (str[0] == '+') {
136         cc++;
137     } else if (str[0] == '-') {
138         bNegative = TRUE;
139         cc++;
140     }
141     while (cc < len) {
142         if (str[cc] != '+' && str[cc] != '-') {
143             break;
144         }
145         cc ++;
146     }
147     FX_FLOAT value = 0;
148     while (cc < len) {
149         if (str[cc] == '.') {
150             break;
151         }
152         value = value * 10 + str[cc] - '0';
153         cc ++;
154     }
155     static const FX_FLOAT fraction_scales[] = {0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f,
156                                                0.0000001f, 0.00000001f, 0.000000001f, 0.0000000001f, 0.00000000001f
157                                               };
158     int scale = 0;
159     if (cc < len && str[cc] == '.') {
160         cc ++;
161         while (cc < len) {
162             value += fraction_scales[scale] * (str[cc] - '0');
163             scale ++;
164             if (scale == sizeof fraction_scales / sizeof(FX_FLOAT)) {
165                 break;
166             }
167             cc ++;
168         }
169     }
170     return bNegative ? -value : value;
171 }
FX_IsDigit(FX_BYTE ch)172 static FX_BOOL FX_IsDigit(FX_BYTE ch)
173 {
174     return (ch >= '0' && ch <= '9') ? TRUE : FALSE;
175 }
FX_IsXDigit(FX_BYTE ch)176 static FX_BOOL FX_IsXDigit(FX_BYTE ch)
177 {
178     return (FX_IsDigit(ch) || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f')) ? TRUE : FALSE;
179 }
FX_MakeUpper(FX_BYTE ch)180 static FX_BYTE FX_MakeUpper(FX_BYTE ch)
181 {
182     if (ch < 'a' || ch > 'z') {
183         return ch;
184     }
185     return ch - 32;
186 }
FX_HexToI(FX_BYTE ch)187 static int FX_HexToI(FX_BYTE ch)
188 {
189     ch = FX_MakeUpper(ch);
190     return FX_IsDigit(ch) ? (ch - '0') : (ch - 55);
191 }
192 static const unsigned char url_encodeTable[128] = {
193     1,  1,  1,  1,		1,  1,  1,  1,
194     1,  1,  1,  1,		1,  1,  1,  1,
195     1,  1,  1,  1,		1,  1,  1,  1,
196     1,  1,  1,  1,		1,  1,  1,  1,
197     1,  0,  1,  1,		0,  1,  0,  0,
198     0,  0,  0,  0,		0,  0,  0,  0,
199     0,  0,  0,  0,		0,  0,  0,  0,
200     0,  0,  0,  0,		1,  0,  1,  0,
201     0,  0,  0,  0,		0,  0,  0,  0,
202     0,  0,  0,  0,		0,  0,  0,  0,
203     0,  0,  0,  0,		0,  0,  0,  0,
204     0,  0,  0,  1,		1,  1,  1,  0,
205     1,  0,  0,  0,		0,  0,  0,  0,
206     0,  0,  0,  0,		0,  0,  0,  0,
207     0,  0,  0,  0,		0,  0,  0,  0,
208     0,  0,  0,  1,		1,  1,  1,  1,
209 };
FX_UrlEncode(const CFX_WideString & wsUrl)210 CFX_ByteString FX_UrlEncode(const CFX_WideString& wsUrl)
211 {
212     const char arDigits[] = "0123456789ABCDEF";
213     CFX_ByteString rUrl;
214     int nLength = wsUrl.GetLength();
215     for (int i = 0; i < nLength; i++) {
216         FX_DWORD word = wsUrl.GetAt(i);
217         if (word > 0x7F || url_encodeTable[word] == 1) {
218             CFX_ByteString bsUri = CFX_ByteString::FromUnicode((FX_WORD)word);
219             int nByte = bsUri.GetLength();
220             for (int j = 0; j < nByte; j++) {
221                 rUrl += '%';
222                 FX_BYTE code = bsUri.GetAt(j);
223                 rUrl += arDigits[code >> 4];
224                 rUrl += arDigits[code & 0x0F];
225             }
226         } else {
227             rUrl += CFX_ByteString::FromUnicode((FX_WORD)word);
228         }
229     }
230     return rUrl;
231 }
FX_UrlDecode(const CFX_ByteString & bsUrl)232 CFX_WideString FX_UrlDecode(const CFX_ByteString& bsUrl)
233 {
234     CFX_ByteString rUrl;
235     int nLength = bsUrl.GetLength();
236     for (int i = 0; i < nLength; i++) {
237         if (i < nLength - 2 && bsUrl[i] == '%' && FX_IsXDigit(bsUrl[i + 1]) && FX_IsXDigit(bsUrl[i + 2])) {
238             rUrl += (FX_HexToI(bsUrl[i + 1]) << 4 | FX_HexToI(bsUrl[i + 2]));
239             i += 2;
240         } else {
241             rUrl += bsUrl[i];
242         }
243     }
244     return CFX_WideString::FromLocal(rUrl);
245 }
FX_EncodeURI(const CFX_WideString & wsURI)246 CFX_ByteString FX_EncodeURI(const CFX_WideString& wsURI)
247 {
248     const char arDigits[] = "0123456789ABCDEF";
249     CFX_ByteString rURI;
250     CFX_ByteString bsUri = wsURI.UTF8Encode();
251     int nLength = bsUri.GetLength();
252     for (int i = 0; i < nLength; i++) {
253         FX_BYTE code = bsUri.GetAt(i);
254         if (code > 0x7F || url_encodeTable[code] == 1) {
255             rURI += '%';
256             rURI += arDigits[code >> 4];
257             rURI += arDigits[code & 0x0F];
258         } else {
259             rURI += code;
260         }
261     }
262     return rURI;
263 }
FX_DecodeURI(const CFX_ByteString & bsURI)264 CFX_WideString FX_DecodeURI(const CFX_ByteString& bsURI)
265 {
266     CFX_ByteString rURI;
267     int nLength = bsURI.GetLength();
268     for (int i = 0; i < nLength; i++) {
269         if (i < nLength - 2 && bsURI[i] == '%' && FX_IsXDigit(bsURI[i + 1]) && FX_IsXDigit(bsURI[i + 2])) {
270             rURI += (FX_HexToI(bsURI[i + 1]) << 4 | FX_HexToI(bsURI[i + 2]));
271             i += 2;
272         } else {
273             rURI += bsURI[i];
274         }
275     }
276     return CFX_WideString::FromUTF8(rURI);
277 }
278 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
279 class CFindFileData : public CFX_Object
280 {
281 public:
~CFindFileData()282     virtual ~CFindFileData() {}
283     HANDLE				m_Handle;
284     FX_BOOL				m_bEnd;
285 };
286 class CFindFileDataA : public CFindFileData
287 {
288 public:
~CFindFileDataA()289     virtual ~CFindFileDataA() {}
290     WIN32_FIND_DATAA	m_FindData;
291 };
292 class CFindFileDataW : public CFindFileData
293 {
294 public:
~CFindFileDataW()295     virtual ~CFindFileDataW() {}
296     WIN32_FIND_DATAW	m_FindData;
297 };
298 #endif
FX_OpenFolder(FX_LPCSTR path)299 void* FX_OpenFolder(FX_LPCSTR path)
300 {
301 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
302 #ifndef _WIN32_WCE
303     CFindFileDataA* pData = FX_NEW CFindFileDataA;
304     if (!pData) {
305         return NULL;
306     }
307 #ifdef _FX_WINAPI_PARTITION_DESKTOP_
308     pData->m_Handle = FindFirstFileA(CFX_ByteString(path) + "/*.*", &pData->m_FindData);
309 #else
310     pData->m_Handle = FindFirstFileExA(CFX_ByteString(path) + "/*.*", FindExInfoStandard, &pData->m_FindData, FindExSearchNameMatch, NULL, 0);
311 #endif
312 #else
313     CFindFileDataW* pData = FX_NEW CFindFileDataW;
314     if (!pData) {
315         return NULL;
316     }
317     pData->m_Handle = FindFirstFileW(CFX_WideString::FromLocal(path) + L"/*.*", &pData->m_FindData);
318 #endif
319     if (pData->m_Handle == INVALID_HANDLE_VALUE) {
320         delete pData;
321         return NULL;
322     }
323     pData->m_bEnd = FALSE;
324     return pData;
325 #else
326     DIR* dir = opendir(path);
327     return dir;
328 #endif
329 }
FX_OpenFolder(FX_LPCWSTR path)330 void* FX_OpenFolder(FX_LPCWSTR path)
331 {
332 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
333     CFindFileDataW* pData = FX_NEW CFindFileDataW;
334     if (!pData) {
335         return NULL;
336     }
337 #ifdef _FX_WINAPI_PARTITION_DESKTOP_
338     pData->m_Handle = FindFirstFileW(CFX_WideString(path) + L"/*.*", &pData->m_FindData);
339 #else
340     pData->m_Handle = FindFirstFileExW(CFX_WideString(path) + L"/*.*", FindExInfoStandard, &pData->m_FindData, FindExSearchNameMatch, NULL, 0);
341 #endif
342     if (pData->m_Handle == INVALID_HANDLE_VALUE) {
343         delete pData;
344         return NULL;
345     }
346     pData->m_bEnd = FALSE;
347     return pData;
348 #else
349     DIR* dir = opendir(CFX_ByteString::FromUnicode(path));
350     return dir;
351 #endif
352 }
FX_GetNextFile(void * handle,CFX_ByteString & filename,FX_BOOL & bFolder)353 FX_BOOL FX_GetNextFile(void* handle, CFX_ByteString& filename, FX_BOOL& bFolder)
354 {
355     if (handle == NULL) {
356         return FALSE;
357     }
358 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
359 #ifndef _WIN32_WCE
360     CFindFileDataA* pData = (CFindFileDataA*)handle;
361     if (pData->m_bEnd) {
362         return FALSE;
363     }
364     filename = pData->m_FindData.cFileName;
365     bFolder = pData->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
366     if (!FindNextFileA(pData->m_Handle, &pData->m_FindData)) {
367         pData->m_bEnd = TRUE;
368     }
369     return TRUE;
370 #else
371     CFindFileDataW* pData = (CFindFileDataW*)handle;
372     if (pData->m_bEnd) {
373         return FALSE;
374     }
375     filename = CFX_ByteString::FromUnicode(pData->m_FindData.cFileName);
376     bFolder = pData->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
377     if (!FindNextFileW(pData->m_Handle, &pData->m_FindData)) {
378         pData->m_bEnd = TRUE;
379     }
380     return TRUE;
381 #endif
382 #elif defined(__native_client__)
383     abort();
384     return FALSE;
385 #else
386     struct dirent *de = readdir((DIR*)handle);
387     if (de == NULL) {
388         return FALSE;
389     }
390     filename = de->d_name;
391     bFolder = de->d_type == DT_DIR;
392     return TRUE;
393 #endif
394 }
FX_GetNextFile(void * handle,CFX_WideString & filename,FX_BOOL & bFolder)395 FX_BOOL FX_GetNextFile(void* handle, CFX_WideString& filename, FX_BOOL& bFolder)
396 {
397     if (handle == NULL) {
398         return FALSE;
399     }
400 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
401     CFindFileDataW* pData = (CFindFileDataW*)handle;
402     if (pData->m_bEnd) {
403         return FALSE;
404     }
405     filename = pData->m_FindData.cFileName;
406     bFolder = pData->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
407     if (!FindNextFileW(pData->m_Handle, &pData->m_FindData)) {
408         pData->m_bEnd = TRUE;
409     }
410     return TRUE;
411 #elif defined(__native_client__)
412     abort();
413     return FALSE;
414 #else
415     struct dirent *de = readdir((DIR*)handle);
416     if (de == NULL) {
417         return FALSE;
418     }
419     filename = CFX_WideString::FromLocal(de->d_name);
420     bFolder = de->d_type == DT_DIR;
421     return TRUE;
422 #endif
423 }
FX_CloseFolder(void * handle)424 void FX_CloseFolder(void* handle)
425 {
426     if (handle == NULL) {
427         return;
428     }
429 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
430     CFindFileData* pData = (CFindFileData*)handle;
431     FindClose(pData->m_Handle);
432     delete pData;
433 #else
434     closedir((DIR*)handle);
435 #endif
436 }
FX_GetFolderSeparator()437 FX_WCHAR FX_GetFolderSeparator()
438 {
439 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
440     return '\\';
441 #else
442     return '/';
443 #endif
444 }
445