OLD | NEW |
1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ | 1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ |
2 /* vi: set expandtab shiftwidth=4 tabstop=4: */ | 2 /* vi: set expandtab shiftwidth=4 tabstop=4: */ |
3 /** | 3 /** |
4 * \file | 4 * \file |
5 * <PRE> | 5 * <PRE> |
6 * MODP_B64 - High performance base64 encoder/decoder | 6 * MODP_B64 - High performance base64 encoder/decoder |
7 * Version 1.3 -- 17-Mar-2006 | 7 * Version 1.3 -- 17-Mar-2006 |
8 * http://modp.com/release/base64 | 8 * http://modp.com/release/base64 |
9 * | 9 * |
10 * Copyright © 2005, 2006 Nick Galbreath -- nickg [at] modp [dot] com | 10 * Copyright © 2005, 2006 Nick Galbreath -- nickg [at] modp [dot] com |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
204 } | 204 } |
205 } | 205 } |
206 #endif | 206 #endif |
207 | 207 |
208 size_t i; | 208 size_t i; |
209 int leftover = len % 4; | 209 int leftover = len % 4; |
210 size_t chunks = (leftover == 0) ? len / 4 - 1 : len /4; | 210 size_t chunks = (leftover == 0) ? len / 4 - 1 : len /4; |
211 | 211 |
212 uint8_t* p = (uint8_t*)dest; | 212 uint8_t* p = (uint8_t*)dest; |
213 uint32_t x = 0; | 213 uint32_t x = 0; |
214 uint32_t* destInt = (uint32_t*) p; | 214 const uint8_t* y = (uint8_t*)src; |
215 uint32_t* srcInt = (uint32_t*) src; | 215 for (i = 0; i < chunks; ++i, y += 4) { |
216 uint32_t y = *srcInt++; | 216 x = d0[y[0]] | d1[y[1]] | d2[y[2]] | d3[y[3]]; |
217 for (i = 0; i < chunks; ++i) { | |
218 x = d0[y & 0xff] | | |
219 d1[(y >> 8) & 0xff] | | |
220 d2[(y >> 16) & 0xff] | | |
221 d3[(y >> 24) & 0xff]; | |
222 | |
223 if (x >= BADCHAR) return MODP_B64_ERROR; | 217 if (x >= BADCHAR) return MODP_B64_ERROR; |
224 *destInt = x ; | 218 *p++ = ((uint8_t*)(&x))[0]; |
225 p += 3; | 219 *p++ = ((uint8_t*)(&x))[1]; |
226 destInt = (uint32_t*)p; | 220 *p++ = ((uint8_t*)(&x))[2]; |
227 y = *srcInt++;} | 221 } |
228 | |
229 | 222 |
230 switch (leftover) { | 223 switch (leftover) { |
231 case 0: | 224 case 0: |
232 x = d0[y & 0xff] | | 225 x = d0[y[0]] | d1[y[1]] | d2[y[2]] | d3[y[3]]; |
233 d1[(y >> 8) & 0xff] | | |
234 d2[(y >> 16) & 0xff] | | |
235 d3[(y >> 24) & 0xff]; | |
236 | 226 |
237 if (x >= BADCHAR) return MODP_B64_ERROR; | 227 if (x >= BADCHAR) return MODP_B64_ERROR; |
238 *p++ = ((uint8_t*)(&x))[0]; | 228 *p++ = ((uint8_t*)(&x))[0]; |
239 *p++ = ((uint8_t*)(&x))[1]; | 229 *p++ = ((uint8_t*)(&x))[1]; |
240 *p = ((uint8_t*)(&x))[2]; | 230 *p = ((uint8_t*)(&x))[2]; |
241 return (chunks+1)*3; | 231 return (chunks+1)*3; |
242 break; | 232 break; |
243 case 1: /* with padding this is an impossible case */ | 233 case 1: /* with padding this is an impossible case */ |
244 x = d0[y & 0xff]; | 234 x = d0[y[0]]; |
245 *p = *((uint8_t*)(&x)); // i.e. first char/byte in int | 235 *p = *((uint8_t*)(&x)); // i.e. first char/byte in int |
246 break; | 236 break; |
247 case 2: // * case 2, 1 output byte */ | 237 case 2: // * case 2, 1 output byte */ |
248 x = d0[y & 0xff] | d1[y >> 8 & 0xff]; | 238 x = d0[y[0]] | d1[y[1]]; |
249 *p = *((uint8_t*)(&x)); // i.e. first char | 239 *p = *((uint8_t*)(&x)); // i.e. first char |
250 break; | 240 break; |
251 default: /* case 3, 2 output bytes */ | 241 default: /* case 3, 2 output bytes */ |
252 x = d0[y & 0xff] | | 242 x = d0[y[0]] | d1[y[1]] | d2[y[2]]; /* 0x3c */ |
253 d1[y >> 8 & 0xff ] | | |
254 d2[y >> 16 & 0xff]; /* 0x3c */ | |
255 *p++ = ((uint8_t*)(&x))[0]; | 243 *p++ = ((uint8_t*)(&x))[0]; |
256 *p = ((uint8_t*)(&x))[1]; | 244 *p = ((uint8_t*)(&x))[1]; |
257 break; | 245 break; |
258 } | 246 } |
259 | 247 |
260 if (x >= BADCHAR) return MODP_B64_ERROR; | 248 if (x >= BADCHAR) return MODP_B64_ERROR; |
261 | 249 |
262 return 3*chunks + (6*leftover)/8; | 250 return 3*chunks + (6*leftover)/8; |
263 } | 251 } |
264 | 252 |
265 #endif /* if bigendian / else / endif */ | 253 #endif /* if bigendian / else / endif */ |
OLD | NEW |