root/ext/xmlrpc/libxmlrpc/base64.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. buffer_new
  2. buffer_add
  3. buffer_delete
  4. base64_encode_xmlrpc
  5. base64_decode_xmlrpc

   1 static const char rcsid[] = "#(@) $Id$";
   2 
   3 /*
   4 
   5            Encode or decode file as MIME base64 (RFC 1341)
   6 
   7                             by John Walker
   8                        http://www.fourmilab.ch/
   9 
  10                 This program is in the public domain.
  11 
  12 */
  13 #include <stdio.h>
  14 
  15 /*  ENCODE  --  Encode binary file into base64.  */
  16 #include <stdlib.h>
  17 #include <ctype.h>
  18 
  19 #include "base64.h"
  20 
  21 static unsigned char dtable[512];
  22 
  23 void buffer_new(struct buffer_st *b)
  24 {
  25   b->length = 512;
  26   b->data = malloc(sizeof(char)*(b->length));
  27   b->data[0] = 0;
  28   b->ptr = b->data;
  29   b->offset = 0;
  30 }
  31 
  32 void buffer_add(struct buffer_st *b, char c)
  33 {
  34   *(b->ptr++) = c;
  35   b->offset++;
  36   if (b->offset == b->length) {
  37     b->length += 512;
  38     b->data = realloc(b->data, b->length);
  39     b->ptr = b->data + b->offset;
  40   }
  41 }
  42 
  43 void buffer_delete(struct buffer_st *b)
  44 {
  45   free(b->data);
  46   b->length = 0;
  47   b->offset = 0;
  48   b->ptr = NULL;
  49   b->data = NULL;
  50 }
  51 
  52 void base64_encode_xmlrpc(struct buffer_st *b, const char *source, int length)
  53 {
  54   int i, hiteof = 0;
  55   int offset = 0;
  56   int olen;
  57 
  58   olen = 0;
  59 
  60   buffer_new(b);
  61 
  62   /*    Fill dtable with character encodings.  */
  63 
  64   for (i = 0; i < 26; i++) {
  65     dtable[i] = 'A' + i;
  66     dtable[26 + i] = 'a' + i;
  67   }
  68   for (i = 0; i < 10; i++) {
  69     dtable[52 + i] = '0' + i;
  70   }
  71   dtable[62] = '+';
  72   dtable[63] = '/';
  73 
  74   while (!hiteof) {
  75     unsigned char igroup[3], ogroup[4];
  76     int c, n;
  77 
  78     igroup[0] = igroup[1] = igroup[2] = 0;
  79     for (n = 0; n < 3; n++) {
  80       c = *(source++);
  81       offset++;
  82       if (offset > length) {
  83         hiteof = 1;
  84         break;
  85       }
  86       igroup[n] = (unsigned char) c;
  87     }
  88     if (n > 0) {
  89       ogroup[0] = dtable[igroup[0] >> 2];
  90       ogroup[1] = dtable[((igroup[0] & 3) << 4) | (igroup[1] >> 4)];
  91       ogroup[2] = dtable[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)];
  92       ogroup[3] = dtable[igroup[2] & 0x3F];
  93 
  94       /* Replace characters in output stream with "=" pad
  95          characters if fewer than three characters were
  96          read from the end of the input stream. */
  97 
  98       if (n < 3) {
  99         ogroup[3] = '=';
 100         if (n < 2) {
 101           ogroup[2] = '=';
 102         }
 103       }
 104       for (i = 0; i < 4; i++) {
 105         buffer_add(b, ogroup[i]);
 106         if (!(b->offset % 72)) {
 107           /* buffer_add(b, '\r'); */
 108           buffer_add(b, '\n');
 109         }
 110       }
 111     }
 112   }
 113   /* buffer_add(b, '\r'); */
 114   buffer_add(b, '\n');
 115 }
 116 
 117 void base64_decode_xmlrpc(struct buffer_st *bfr, const char *source, int length)
 118 {
 119     int i;
 120     int offset = 0;
 121     int endoffile;
 122     int count;
 123 
 124     buffer_new(bfr);
 125 
 126     for (i = 0; i < 255; i++) {
 127         dtable[i] = 0x80;
 128     }
 129     for (i = 'A'; i <= 'Z'; i++) {
 130         dtable[i] = 0 + (i - 'A');
 131     }
 132     for (i = 'a'; i <= 'z'; i++) {
 133         dtable[i] = 26 + (i - 'a');
 134     }
 135     for (i = '0'; i <= '9'; i++) {
 136         dtable[i] = 52 + (i - '0');
 137     }
 138     dtable['+'] = 62;
 139     dtable['/'] = 63;
 140     dtable['='] = 0;
 141 
 142     endoffile = 0;
 143 
 144     /*CONSTANTCONDITION*/
 145     while (1) {
 146         unsigned char a[4], b[4], o[3];
 147 
 148         for (i = 0; i < 4; i++) {
 149             int c;
 150             while (1) {
 151               c = *(source++);
 152               offset++;
 153               if (offset > length) endoffile = 1;
 154               if (isspace(c) || c == '\n' || c == '\r') continue;
 155               break;
 156             }
 157 
 158             if (endoffile) {
 159               /*
 160                 if (i > 0) {
 161                     fprintf(stderr, "Input file incomplete.\n");
 162                     exit(1);
 163                 }
 164               */
 165                 return;
 166             }
 167 
 168             if (dtable[c] & 0x80) {
 169               /*
 170               fprintf(stderr, "Offset %i length %i\n", offset, length);
 171               fprintf(stderr, "character '%c:%x:%c' in input file.\n", c, c, dtable[c]);
 172               exit(1);
 173               */
 174               i--;
 175               continue;
 176             }
 177             a[i] = (unsigned char) c;
 178             b[i] = (unsigned char) dtable[c];
 179         }
 180         o[0] = (b[0] << 2) | (b[1] >> 4);
 181         o[1] = (b[1] << 4) | (b[2] >> 2);
 182         o[2] = (b[2] << 6) | b[3];
 183         i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3);
 184         count = 0;
 185         while (count < i) {
 186           buffer_add(bfr, o[count++]);
 187         }
 188         if (i < 3) {
 189             return;
 190         }
 191     }
 192 }

/* [<][>][^][v][top][bottom][index][help] */