Add very old versions (for history).
[opsoft_archive.git] / silentbob / silentbob-1.4 / gclib / gclib_c / base64.c
blob555965971396c34ab769f9b96105e9ac4c8db8f4
1 /*
2 * (c) Oleg Puchinin 2006
3 * graycardinalster@gmail.com
4 *
5 */
7 #include <string.h>
8 #define __export
10 const static char base64ABC[] =
11 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
12 typedef unsigned char uchar_t;
14 #define S_(a) S[n * 3 + a]
15 #define S__(a,b) (S[n * 3 + a] & b)
16 #define S__l(a,b,c) ((S[n * 3 + a] & b) << c)
18 #define B1 buf[(n<<2)] = base64ABC[ (S_(0) >> 2) ];
19 #define B2 buf[(n<<2) + 1] = base64ABC [ (S__l(0,0x3,4)) | S_(1) >> 4 ];
20 #define B3 buf[(n<<2) + 2] = base64ABC [ S__l(1,0x0F,2) | S_(2) >> 6];
21 #define B4 buf[(n<<2) + 3] = base64ABC [ S__(2,0x3F) ];
23 __export uchar_t * base64_code (unsigned char * S, int SIZE)
25 uchar_t c, *buf;
26 int n;
28 c = (SIZE == 0) ? strlen ((const char *) S) % 3 : SIZE % 3;
29 SIZE = (SIZE == 0) ? strlen ((const char *) S) / 3 : SIZE / 3;
31 buf = (uchar_t *) malloc (SIZE * 4 + 5);
33 for (n = 0; n < SIZE; ++n) {
34 B1; B2; B3; B4;
37 switch (c) {
38 case 1:
39 B1; B2;
40 buf[(n<<2) + 2] = '=';
41 buf[(n<<2) + 3] = '=';
42 ++n;
43 break;
44 case 2:
45 B1; B2; B3;
46 buf[(n<<2) + 3] = '=';
47 ++n;
48 break;
50 buf[(n<<2)] = 0;
51 return buf;
54 #define BASE64(a) ((unsigned char) (strchr (base64ABC, S[(n<<2) + a]) - base64ABC))
56 __export uchar_t * base64_decode (unsigned char * S, int SIZE)
58 unsigned char * ptr;
59 int n;
61 if (SIZE % 4)
62 return NULL;
64 SIZE = SIZE ? SIZE / 4 : strlen ((const char *) S) / 4;
65 ptr = (uchar_t *) malloc (SIZE * 4 + 5);
67 for (n = 0; n < SIZE; n++) {
68 ptr[n * 3] = (BASE64(0) << 2) | ( BASE64(1) >> 4);
69 if (S[(n<<2) + 2] != '=') {
70 ptr[n * 3 + 1] = ((BASE64(1) & 0x0F) << 4) | (BASE64(2) >> 2);
71 if (S[(n<<2) + 3] != '=')
72 ptr[n * 3 + 2] = ((BASE64(2) & 0x03) << 6) | BASE64(3);
73 else
74 ptr[n * 3 + 2] = 0;
75 } else
76 ptr[n * 3 +1] = 0;
79 ++n;
80 ptr [n * 3] = 0;
81 return ptr;