Merge to XFA: Use stdint.h types throughout PDFium.
[pdfium.git] / xfa / src / fgas / src / crt / fx_algorithm.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 #ifdef __cplusplus\r
9 extern "C" {\r
10 #endif\r
11 const static FX_CHAR g_FXBase64EncoderMap[64] = {\r
12     'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',\r
13     'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',\r
14     'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',\r
15     'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',\r
16     'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',\r
17     'o', 'p', 'q', 'r', 's', 't', 'u', 'v',\r
18     'w', 'x', 'y', 'z', '0', '1', '2', '3',\r
19     '4', '5', '6', '7', '8', '9', '+', '/',\r
20 };\r
21 typedef struct _FX_BASE64DATA {\r
22 \r
23     FX_DWORD    data1 : 2;\r
24     FX_DWORD    data2 : 6;\r
25     FX_DWORD    data3 : 4;\r
26     FX_DWORD    data4 : 4;\r
27     FX_DWORD    data5 : 6;\r
28     FX_DWORD    data6 : 2;\r
29     FX_DWORD    data7 : 8;\r
30 } FX_BASE64DATA, * FX_LPBASE64ENCODEDATA;\r
31 typedef FX_BASE64DATA const * FX_LPCBASE64DATA;\r
32 static void FX_Base64EncodePiece(const FX_BASE64DATA &src, int32_t iBytes, FX_CHAR dst[4])\r
33 {\r
34     dst[0] = g_FXBase64EncoderMap[src.data2];\r
35     FX_DWORD b = src.data1 << 4;\r
36     if (iBytes > 1) {\r
37         b |= src.data4;\r
38     }\r
39     dst[1] = g_FXBase64EncoderMap[b];\r
40     if (iBytes > 1) {\r
41         b = src.data3 << 2;\r
42         if (iBytes > 2) {\r
43             b |= src.data6;\r
44         }\r
45         dst[2] = g_FXBase64EncoderMap[b];\r
46         if (iBytes > 2) {\r
47             dst[3] = g_FXBase64EncoderMap[src.data5];\r
48         } else {\r
49             dst[3] = '=';\r
50         }\r
51     } else {\r
52         dst[2] = dst[3] = '=';\r
53     }\r
54 }\r
55 int32_t FX_Base64EncodeA(FX_LPCBYTE pSrc, int32_t iSrcLen, FX_LPSTR pDst)\r
56 {\r
57     FXSYS_assert(pSrc != NULL);\r
58     if (iSrcLen < 1) {\r
59         return 0;\r
60     }\r
61     if (pDst == NULL) {\r
62         int32_t iDstLen = iSrcLen / 3 * 4;\r
63         if ((iSrcLen % 3) != 0) {\r
64             iDstLen += 4;\r
65         }\r
66         return iDstLen;\r
67     }\r
68     FX_BASE64DATA srcData;\r
69     int32_t iBytes = 3;\r
70     FX_LPSTR pDstEnd = pDst;\r
71     while (iSrcLen > 0) {\r
72         if (iSrcLen > 2) {\r
73             ((FX_LPBYTE)&srcData)[0] = *pSrc ++;\r
74             ((FX_LPBYTE)&srcData)[1] = *pSrc ++;\r
75             ((FX_LPBYTE)&srcData)[2] = *pSrc ++;\r
76             iSrcLen -= 3;\r
77         } else {\r
78             *((FX_LPDWORD)&srcData) = 0;\r
79             ((FX_LPBYTE)&srcData)[0] = *pSrc ++;\r
80             if (iSrcLen > 1) {\r
81                 ((FX_LPBYTE)&srcData)[1] = *pSrc ++;\r
82             }\r
83             iBytes = iSrcLen;\r
84             iSrcLen = 0;\r
85         }\r
86         FX_Base64EncodePiece(srcData, iBytes, pDstEnd);\r
87         pDstEnd += 4;\r
88     }\r
89     return pDstEnd - pDst;\r
90 }\r
91 const static uint8_t g_FXBase64DecoderMap[256] = {\r
92     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
93     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
94     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
95     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
96     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
97     0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F,\r
98     0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,\r
99     0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
100     0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,\r
101     0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,\r
102     0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,\r
103     0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
104     0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,\r
105     0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,\r
106     0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,\r
107     0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
108     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
109     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
110     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
111     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
112     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
113     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
114     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
115     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
116     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
117     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
118     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
119     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
120     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
121     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
122     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
123     0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,\r
124 };\r
125 static void FX_Base64DecodePiece(const FX_CHAR src[4], int32_t iChars, FX_BASE64DATA &dst, int32_t &iBytes)\r
126 {\r
127     FXSYS_assert(iChars > 0 && iChars < 5);\r
128     iBytes = 1;\r
129     dst.data2 = g_FXBase64DecoderMap[(uint8_t)src[0]];\r
130     if (iChars > 1) {\r
131         uint8_t b = g_FXBase64DecoderMap[(uint8_t)src[1]];\r
132         dst.data1 = b >> 4;\r
133         dst.data4 = b;\r
134         if (iChars > 2) {\r
135             iBytes = 2;\r
136             b = g_FXBase64DecoderMap[(uint8_t)src[2]];\r
137             dst.data3 = b >> 2;\r
138             dst.data6 = b;\r
139             if (iChars > 3) {\r
140                 iBytes = 3;\r
141                 dst.data5 = g_FXBase64DecoderMap[(uint8_t)src[3]];\r
142             } else {\r
143                 dst.data5 = 0;\r
144             }\r
145         } else {\r
146             dst.data3 = 0;\r
147         }\r
148     } else {\r
149         dst.data1 = 0;\r
150     }\r
151 }\r
152 int32_t FX_Base64DecodeA(FX_LPCSTR pSrc, int32_t iSrcLen, FX_LPBYTE pDst)\r
153 {\r
154     FXSYS_assert(pSrc != NULL);\r
155     if (iSrcLen < 1) {\r
156         return 0;\r
157     }\r
158     while (iSrcLen > 0 && pSrc[iSrcLen - 1] == '=') {\r
159         iSrcLen --;\r
160     }\r
161     if (iSrcLen < 1) {\r
162         return 0;\r
163     }\r
164     if (pDst == NULL) {\r
165         int32_t iDstLen = iSrcLen / 4 * 3;\r
166         iSrcLen %= 4;\r
167         if (iSrcLen == 1) {\r
168             iDstLen += 1;\r
169         } else if (iSrcLen == 2) {\r
170             iDstLen += 1;\r
171         } else if (iSrcLen == 3) {\r
172             iDstLen += 2;\r
173         }\r
174         return iDstLen;\r
175     }\r
176     FX_CHAR srcData[4];\r
177     FX_BASE64DATA dstData;\r
178     int32_t iChars = 4, iBytes;\r
179     FX_LPBYTE pDstEnd = pDst;\r
180     while (iSrcLen > 0) {\r
181         if (iSrcLen > 3) {\r
182             *((FX_DWORD*)srcData) = *((FX_DWORD*)pSrc);\r
183             pSrc += 4;\r
184             iSrcLen -= 4;\r
185         } else {\r
186             *((FX_LPDWORD)&dstData) = 0;\r
187             *((FX_DWORD*)srcData) = 0;\r
188             srcData[0] = *pSrc ++;\r
189             if (iSrcLen > 1) {\r
190                 srcData[1] = *pSrc ++;\r
191             }\r
192             if (iSrcLen > 2) {\r
193                 srcData[2] = *pSrc ++;\r
194             }\r
195             iChars = iSrcLen;\r
196             iSrcLen = 0;\r
197         }\r
198         FX_Base64DecodePiece(srcData, iChars, dstData, iBytes);\r
199         *pDstEnd ++ = ((FX_LPBYTE)&dstData)[0];\r
200         if (iBytes > 1) {\r
201             *pDstEnd ++ = ((FX_LPBYTE)&dstData)[1];\r
202         }\r
203         if (iBytes > 2) {\r
204             *pDstEnd ++ = ((FX_LPBYTE)&dstData)[2];\r
205         }\r
206     }\r
207     return pDstEnd - pDst;\r
208 }\r
209 int32_t FX_Base64DecodeW(FX_LPCWSTR pSrc, int32_t iSrcLen, FX_LPBYTE pDst)\r
210 {\r
211     FXSYS_assert(pSrc != NULL);\r
212     if (iSrcLen < 1) {\r
213         return 0;\r
214     }\r
215     while (iSrcLen > 0 && pSrc[iSrcLen - 1] == '=') {\r
216         iSrcLen --;\r
217     }\r
218     if (iSrcLen < 1) {\r
219         return 0;\r
220     }\r
221     if (pDst == NULL) {\r
222         int32_t iDstLen = iSrcLen / 4 * 3;\r
223         iSrcLen %= 4;\r
224         if (iSrcLen == 1) {\r
225             iDstLen += 1;\r
226         } else if (iSrcLen == 2) {\r
227             iDstLen += 1;\r
228         } else if (iSrcLen == 3) {\r
229             iDstLen += 2;\r
230         }\r
231         return iDstLen;\r
232     }\r
233     FX_CHAR srcData[4];\r
234     FX_BASE64DATA dstData;\r
235     int32_t iChars = 4, iBytes;\r
236     FX_LPBYTE pDstEnd = pDst;\r
237     while (iSrcLen > 0) {\r
238         if (iSrcLen > 3) {\r
239             srcData[0] = (FX_CHAR) * pSrc ++;\r
240             srcData[1] = (FX_CHAR) * pSrc ++;\r
241             srcData[2] = (FX_CHAR) * pSrc ++;\r
242             srcData[3] = (FX_CHAR) * pSrc ++;\r
243             iSrcLen -= 4;\r
244         } else {\r
245             *((FX_LPDWORD)&dstData) = 0;\r
246             *((FX_DWORD*)srcData) = 0;\r
247             srcData[0] = (FX_CHAR) * pSrc ++;\r
248             if (iSrcLen > 1) {\r
249                 srcData[1] = (FX_CHAR) * pSrc ++;\r
250             }\r
251             if (iSrcLen > 2) {\r
252                 srcData[2] = (FX_CHAR) * pSrc ++;\r
253             }\r
254             iChars = iSrcLen;\r
255             iSrcLen = 0;\r
256         }\r
257         FX_Base64DecodePiece(srcData, iChars, dstData, iBytes);\r
258         *pDstEnd ++ = ((FX_LPBYTE)&dstData)[0];\r
259         if (iBytes > 1) {\r
260             *pDstEnd ++ = ((FX_LPBYTE)&dstData)[1];\r
261         }\r
262         if (iBytes > 2) {\r
263             *pDstEnd ++ = ((FX_LPBYTE)&dstData)[2];\r
264         }\r
265     }\r
266     return pDstEnd - pDst;\r
267 }\r
268 const static uint8_t g_FXHex2DecMap[256] = {\r
269     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
270     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
271     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
272     0,  1,      2,      3,      4,      5,      6,      7,      8,      9,      0,      0,      0,      0,      0,      0,\r
273     0,  10,     11,     12,     13,     14,     15,     0,      0,      0,      0,      0,      0,      0,      0,      0,\r
274     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
275     0,  10,     11,     12,     13,     14,     15,     0,      0,      0,      0,      0,      0,      0,      0,      0,\r
276     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
277     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
278     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
279     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
280     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
281     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
282     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
283     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
284     0,  0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,\r
285 };\r
286 uint8_t FX_Hex2Dec(uint8_t hexHigh, uint8_t hexLow)\r
287 {\r
288     return (g_FXHex2DecMap[hexHigh] << 4) + g_FXHex2DecMap[hexLow];\r
289 }\r
290 int32_t FX_SeparateStringW(FX_LPCWSTR pStr, int32_t iStrLen, FX_WCHAR delimiter, CFX_WideStringArray &pieces)\r
291 {\r
292     if (pStr == NULL) {\r
293         return 0;\r
294     }\r
295     if (iStrLen < 0) {\r
296         iStrLen = FXSYS_wcslen(pStr);\r
297     }\r
298     FX_LPCWSTR pToken = pStr;\r
299     FX_LPCWSTR pEnd = pStr + iStrLen;\r
300     while (TRUE) {\r
301         if (pStr >= pEnd || delimiter == *pStr) {\r
302             CFX_WideString sub(pToken, pStr - pToken);\r
303             pieces.Add(sub);\r
304             pToken = pStr + 1;\r
305             if (pStr >= pEnd) {\r
306                 break;\r
307             }\r
308         }\r
309         pStr ++;\r
310     }\r
311     return pieces.GetSize();\r
312 }\r
313 #ifdef __cplusplus\r
314 };\r
315 #endif\r