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