Main Page   Modules   Compound List   File List   Compound Members   File Members   Related Pages  

rpmio/base64.c

Go to the documentation of this file.
00001 
00005 static int _debug = 0;
00006 
00007 #include "system.h"
00008 #include "base64.h"
00009 #include "debug.h"
00010 
00011 int B64decode (const char * s, void ** datap, size_t *lenp)
00012 {
00013     static /*@only@*/ char * b64dec = NULL;
00014     unsigned char *t, *te;
00015     size_t ns, nt;
00016     unsigned a, b, c, d;
00017 
00018     if (s == NULL)      return 1;
00019     ns = strlen(s);
00020     if (ns & 0x3)       return 2;
00021 
00022     if (b64dec == NULL) {
00023         b64dec = xmalloc(255);
00024         memset(b64dec, 0x80, 255);
00025         for (c = 'A'; c <= 'Z'; c++)
00026             b64dec[ c ] = 0 + (c - 'A');
00027         for (c = 'a'; c <= 'z'; c++)
00028             b64dec[ c ] = 26 + (c - 'a');
00029         for (c = '0'; c <= '9'; c++)
00030             b64dec[ c ] = 52 + (c - '0');
00031         b64dec[(unsigned)'+'] = 62;
00032         b64dec[(unsigned)'/'] = 63;
00033         b64dec[(unsigned)'='] = 0;
00034     }
00035     
00036     nt = (ns / 4) * 3;
00037     t = te = xmalloc(nt + 1);
00038 
00039     while (ns > 0) {
00040         if ((a = b64dec[ (unsigned)*s++ ]) == 0x80)
00041             break;
00042         if ((b = b64dec[ (unsigned)*s++ ]) == 0x80)
00043             break;
00044         if ((c = b64dec[ (unsigned)*s++ ]) == 0x80)
00045             break;
00046         if ((d = b64dec[ (unsigned)*s++ ]) == 0x80)
00047             break;
00048 if (_debug)
00049 fprintf(stderr, "%7u %02x %02x %02x %02x -> %02x %02x %02x\n",
00050 (unsigned)ns, a, b, c, d,
00051 (((a << 2) | (b >> 4)) & 0xff),
00052 (((b << 4) | (c >> 2)) & 0xff),
00053 (((c << 6) | d) & 0xff));
00054         ns -= 4;
00055         *te++ = (a << 2) | (b >> 4);
00056         if (s[-2] == '=') break;
00057         *te++ = (b << 4) | (c >> 2);
00058         if (s[-1] == '=') break;
00059         *te++ = (c << 6) | d;
00060     }
00061 
00062     if (ns > 0) {
00063         free(t);
00064         return 3;
00065     }
00066     if (lenp)
00067         *lenp = (te - t);
00068     if (datap)
00069         *datap = t;
00070     else
00071         free(t);
00072 
00073     return 0;
00074 }
00075 
00076 char * B64encode (const void * str, size_t ns)
00077 {
00078     static char b64enc[] =
00079         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00080     const unsigned char *s = str;
00081     unsigned char *t, *te;
00082     size_t nt;
00083     unsigned c;
00084 
00085     if (s == NULL)      return NULL;
00086     if (*s == '\0')     return xstrdup("");
00087 
00088     if (ns == 0) ns = strlen(s);
00089     nt = ((ns + 2) / 3) * 4;
00090     t = te = xmalloc(nt + 1);
00091 
00092     while (ns) {
00093 
00094 if (_debug)
00095 fprintf(stderr, "%7u %02x %02x %02x -> %02x %02x %02x %02x\n",
00096 (unsigned)ns, (unsigned)s[0], (unsigned)s[1], (unsigned)s[2],
00097 (unsigned)(s[0] >> 2),
00098 (unsigned)((s[0] & 0x3) << 4) | (s[1] >> 4),
00099 (unsigned)((s[1] & 0xf) << 2) | (s[2] >> 6),
00100 (unsigned)(s[2]& 0x3f));
00101         c = *s++;
00102         *te++ = b64enc[ (c >> 2) ];
00103         *te++ = b64enc[ ((c & 0x3) << 4) | (*s >> 4) ];
00104         if (--ns <= 0) {
00105             *te++ = '=';
00106             *te++ = '=';
00107             continue;
00108         }
00109         c = *s++;
00110         *te++ = b64enc[ ((c & 0xf) << 2) | (*s >> 6) ];
00111         if (--ns <= 0) {
00112             *te++ = '=';
00113             continue;
00114         }
00115         *te++ = b64enc[ (int)(*s & 0x3f) ];
00116         s++;
00117         --ns;
00118     }
00119     *te = '\0';
00120     return t;
00121 }

Generated at Mon May 21 08:53:40 2001 for rpm by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001