Merge XFA to PDFium master at 4dc95e7 on 10/28/2014
[pdfium.git] / xfa / src / fgas / src / crt / fx_system.cpp
1 // Copyright 2014 PDFium Authors. All rights reserved.\r
2 // Use of this source code is governed by a BSD-style license that can be\r
3 // found in the LICENSE file.\r
4 \r
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com\r
6 \r
7 #include "../fgas_base.h"\r
8 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN32_MOBILE_ || _FX_OS_ == _FX_WIN64_\r
9 #include <io.h>\r
10 #elif _FX_OS_ == _FX_LINUX_DESKTOP_ || _FX_OS_ == _FX_LINUX_Mini_\r
11 #include <sys/times.h>\r
12 #endif\r
13 #ifdef __cplusplus\r
14 extern "C" {\r
15 #endif\r
16 FX_FLOAT FX_tan(FX_FLOAT a)\r
17 {\r
18     return (FX_FLOAT)tan(a);\r
19 }\r
20 FX_FLOAT FX_log(FX_FLOAT b, FX_FLOAT x)\r
21 {\r
22     return FXSYS_log(x) / FXSYS_log(b);\r
23 }\r
24 FX_LPWSTR FX_wcsncpy(FX_LPWSTR dstStr, FX_LPCWSTR srcStr, size_t count)\r
25 {\r
26     FXSYS_assert(dstStr != NULL && srcStr != NULL && count > 0);\r
27     for (size_t i = 0; i < count; ++i)\r
28         if ((dstStr[i] = srcStr[i]) == L'\0') {\r
29             break;\r
30         }\r
31     return dstStr;\r
32 }\r
33 FX_INT32 FX_wcsnicmp(FX_LPCWSTR s1, FX_LPCWSTR s2, size_t count)\r
34 {\r
35     FXSYS_assert(s1 != NULL && s2 != NULL && count > 0);\r
36     FX_WCHAR wch1 = 0, wch2 = 0;\r
37     while (count-- > 0) {\r
38         wch1 = (FX_WCHAR)FX_tolower(*s1++);\r
39         wch2 = (FX_WCHAR)FX_tolower(*s2++);\r
40         if (wch1 != wch2) {\r
41             break;\r
42         }\r
43     }\r
44     return wch1 - wch2;\r
45 }\r
46 FX_INT32 FX_strnicmp(FX_LPCSTR s1, FX_LPCSTR s2, size_t count)\r
47 {\r
48     FXSYS_assert(s1 != NULL && s2 != NULL && count > 0);\r
49     FX_CHAR ch1 = 0, ch2 = 0;\r
50     while (count-- > 0) {\r
51         ch1 = (FX_CHAR)FX_tolower(*s1++);\r
52         ch2 = (FX_CHAR)FX_tolower(*s2++);\r
53         if (ch1 != ch2) {\r
54             break;\r
55         }\r
56     }\r
57     return ch1 - ch2;\r
58 }\r
59 FX_INT32 FX_filelength(FXSYS_FILE *file)\r
60 {\r
61     FXSYS_assert(file != NULL);\r
62 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_\r
63     return _filelength(_fileno(file));\r
64 #else\r
65     FX_INT32 iPos = FXSYS_ftell(file);\r
66     FXSYS_fseek(file, 0, FXSYS_SEEK_END);\r
67     FX_INT32 iLen = FXSYS_ftell(file);\r
68     FXSYS_fseek(file, iPos, FXSYS_SEEK_SET);\r
69     return iLen;\r
70 #endif\r
71 }\r
72 FX_BOOL FX_fsetsize(FXSYS_FILE *file, FX_INT32 size)\r
73 {\r
74     FXSYS_assert(file != NULL);\r
75 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_\r
76     return _chsize(_fileno(file), size) == 0;\r
77 #elif _FX_OS_ == _FX_WIN32_MOBILE_\r
78     HANDLE hFile = _fileno(file);\r
79     FX_DWORD dwPos = ::SetFilePointer(hFile, 0, 0, FILE_CURRENT);\r
80     ::SetFilePointer(hFile, size, 0, FILE_BEGIN);\r
81     FX_BOOL bRet = ::SetEndOfFile(hFile);\r
82     ::SetFilePointer(hFile, (FX_INT32)dwPos, 0, FILE_BEGIN);\r
83     return bRet;\r
84 #else\r
85     return FALSE;\r
86 #endif\r
87 }\r
88 FX_FLOAT FX_strtof(FX_LPCSTR pcsStr, FX_INT32 iLength , FX_INT32 *pUsedLen )\r
89 {\r
90     FXSYS_assert(pcsStr != NULL);\r
91     if (iLength < 0) {\r
92         iLength = FXSYS_strlen(pcsStr);\r
93     }\r
94     return FX_wcstof(CFX_WideString::FromLocal(pcsStr, iLength), iLength, pUsedLen);\r
95 }\r
96 FX_FLOAT FX_wcstof(FX_LPCWSTR pwsStr, FX_INT32 iLength , FX_INT32 *pUsedLen )\r
97 {\r
98     FXSYS_assert(pwsStr != NULL);\r
99     if (iLength < 0) {\r
100         iLength = FXSYS_wcslen(pwsStr);\r
101     }\r
102     if (iLength == 0) {\r
103         return 0.0f;\r
104     }\r
105     FX_INT32 iUsedLen = 0;\r
106     FX_BOOL bNegtive = FALSE;\r
107     switch (pwsStr[iUsedLen]) {\r
108         case '-':\r
109             bNegtive = TRUE;\r
110         case '+':\r
111             iUsedLen++;\r
112             break;\r
113     }\r
114     FX_FLOAT fValue = 0.0f;\r
115     while (iUsedLen < iLength) {\r
116         FX_WCHAR wch = pwsStr[iUsedLen];\r
117         if (wch >= L'0' && wch <= L'9') {\r
118             fValue = fValue * 10.0f + (wch - L'0');\r
119         } else {\r
120             break;\r
121         }\r
122         iUsedLen++;\r
123     }\r
124     if (iUsedLen < iLength && pwsStr[iUsedLen] == L'.') {\r
125         FX_FLOAT fPrecise = 0.1f;\r
126         while (++iUsedLen < iLength) {\r
127             FX_WCHAR wch = pwsStr[iUsedLen];\r
128             if (wch >= L'0' && wch <= L'9') {\r
129                 fValue += (wch - L'0') * fPrecise;\r
130                 fPrecise *= 0.1f;\r
131             } else {\r
132                 break;\r
133             }\r
134         }\r
135     }\r
136     if (pUsedLen) {\r
137         *pUsedLen = iUsedLen;\r
138     }\r
139     return bNegtive ? -fValue : fValue;\r
140 }\r
141 void FX_memset(FX_LPVOID pBuf, FX_INT32 iValue, size_t size)\r
142 {\r
143     FXSYS_assert(pBuf != NULL && size > 0 && (size & 0x03) == 0);\r
144     FXSYS_assert((((size_t)pBuf) & 0x03) == 0);\r
145     FX_DWORD *pStart = (FX_DWORD*)pBuf;\r
146     FX_DWORD *pEnd = pStart + (size >> 2);\r
147     while (pStart < pEnd) {\r
148         *pStart ++ = iValue;\r
149     }\r
150 }\r
151 void FX_memcpy(FX_LPVOID pDst, FX_LPCVOID pSrc, size_t size)\r
152 {\r
153     FXSYS_assert(pDst != NULL && pSrc != NULL && size > 0 && (size & 0x03) == 0);\r
154     FXSYS_assert((((size_t)pDst) & 0x03) == 0 && (((size_t)pSrc) & 0x03) == 0);\r
155     FX_DWORD *pStart = (FX_DWORD*)pDst;\r
156     FX_DWORD *pEnd = pStart + (size >> 2);\r
157     FX_DWORD *pValue = (FX_DWORD*)pSrc;\r
158     while (pStart < pEnd) {\r
159         *pStart ++ = *pValue ++;\r
160     }\r
161 }\r
162 FX_BOOL FX_IsRelativePath(const CFX_WideStringC &wsUrl)\r
163 {\r
164     FX_INT32 iUrlLen = wsUrl.GetLength();\r
165     if (iUrlLen == 0) {\r
166         return TRUE;\r
167     }\r
168     for (FX_INT32 i = FX_MIN(5, iUrlLen) - 1; i >= 0; --i)\r
169         if (wsUrl.GetAt(i) == ':') {\r
170             return FALSE;\r
171         }\r
172     return TRUE;\r
173 }\r
174 FX_BOOL FX_JoinPath(const CFX_WideStringC &wsBasePath, const CFX_WideStringC &wsRelativePath, CFX_WideString &wsAbsolutePath)\r
175 {\r
176     if (!FX_IsRelativePath(wsRelativePath)) {\r
177         wsAbsolutePath = wsRelativePath;\r
178         return TRUE;\r
179     }\r
180     FX_LPCWSTR pRelStart = wsRelativePath.GetPtr();\r
181     FX_LPCWSTR pRelEnd   = pRelStart + wsRelativePath.GetLength();\r
182     if (pRelStart < pRelEnd) {\r
183         switch (*pRelStart) {\r
184             case '#':\r
185                 wsAbsolutePath = CFX_WideString(wsBasePath, wsRelativePath);\r
186                 return wsAbsolutePath.GetLength() > 0;\r
187             case '/':\r
188             case '\\':\r
189                 wsAbsolutePath = wsRelativePath;\r
190                 return wsAbsolutePath.GetLength() > 0;\r
191         }\r
192     }\r
193     FX_INT32 nBackCount = 0;\r
194     for(;;) {\r
195         if (pRelStart >= pRelEnd) {\r
196             wsAbsolutePath = wsBasePath;\r
197             return TRUE;\r
198         }\r
199         if (*pRelStart != '.') {\r
200             break;\r
201         }\r
202         if (pRelStart + 1 < pRelEnd &&\r
203                 (pRelStart[1] == '/' || pRelStart[1] == '\\')) {\r
204             pRelStart += 2;\r
205         } else if (pRelStart + 2 < pRelEnd\r
206                    && pRelStart[1] == '.'\r
207                    && (pRelStart[2] == '/' || pRelStart[2] == '\\')) {\r
208             pRelStart += 3;\r
209             nBackCount++;\r
210         } else {\r
211             return FALSE;\r
212         }\r
213     }\r
214     FX_LPCWSTR pBaseStart = wsBasePath.GetPtr();\r
215     FX_LPCWSTR pBaseEnd   = pBaseStart + wsBasePath.GetLength();\r
216     while(pBaseStart < (--pBaseEnd) && *pBaseEnd != '/' && *pBaseEnd != '\\')\r
217         ;\r
218     if (pBaseStart == pBaseEnd) {\r
219         wsAbsolutePath = CFX_WideStringC(pRelStart, pRelEnd - pRelStart);\r
220         return wsAbsolutePath.GetLength() > 0;\r
221     }\r
222     while (nBackCount > 0) {\r
223         if (pBaseStart >= (--pBaseEnd)) {\r
224             return FALSE;\r
225         } else if (*pBaseEnd == '/' || *pBaseEnd == '\\')\r
226             if ((--nBackCount) <= 0) {\r
227                 break;\r
228             }\r
229     }\r
230     wsAbsolutePath = CFX_WideString(CFX_WideStringC(pBaseStart, pBaseEnd - pBaseStart + 1),\r
231                                     CFX_WideStringC(pRelStart, pRelEnd - pRelStart));\r
232     return wsAbsolutePath.GetLength() > 0;\r
233 }\r
234 #ifdef __cplusplus\r
235 };\r
236 #endif\r