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