Back to index

nordugrid-arc-nox  1.1.0~rc6
Base64.cpp
Go to the documentation of this file.
00001 // -*- indent-tabs-mode: nil -*-
00002 
00003 /* Base64 encoding and decoding, borrowed from Axis2c project.
00004  * Below is the license which is required by Axis2c.
00005  */
00006 
00007 /*
00008  * Licensed to the Apache Software Foundation (ASF) under one or more
00009  * contributor license agreements.  See the NOTICE file distributed with
00010  * this work for additional information regarding copyright ownership.
00011  * The ASF licenses this file to You under the Apache License, Version 2.0
00012  * (the "License"); you may not use this file except in compliance with
00013  * the License.  You may obtain a copy of the License at
00014  *
00015  *      http://www.apache.org/licenses/LICENSE-2.0
00016  *
00017  * Unless required by applicable law or agreed to in writing, software
00018  * distributed under the License is distributed on an "AS IS" BASIS,
00019  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020  * See the License for the specific language governing permissions and
00021  * limitations under the License.
00022  */
00023 
00024 #ifdef HAVE_CONFIG_H
00025 #include "config.h"
00026 #endif
00027 
00028 #include "Base64.h"
00029 
00030 static const unsigned char pr2six[256] = {
00031 #ifndef CHARSET_EBCDIC
00032   /* ASCII table */
00033   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00034   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00035   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63,
00036   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64,
00037   64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
00038   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64,
00039   64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
00040   41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64,
00041   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00042   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00043   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00044   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00045   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00046   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00047   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00048   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64
00049 #else /* CHARSET_EBCDIC */
00050       /* EBCDIC table */
00051   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00052   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00053   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00054   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00055   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64,
00056   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00057   64, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00058   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00059   64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 64, 64, 64, 64, 64, 64,
00060   64, 35, 36, 37, 38, 39, 40, 41, 42, 43, 64, 64, 64, 64, 64, 64,
00061   64, 64, 44, 45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64,
00062   64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
00063   64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 64, 64, 64, 64, 64, 64,
00064   64, 9, 10, 11, 12, 13, 14, 15, 16, 17, 64, 64, 64, 64, 64, 64,
00065   64, 64, 18, 19, 20, 21, 22, 23, 24, 25, 64, 64, 64, 64, 64, 64,
00066   52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 64, 64, 64, 64, 64, 64
00067 #endif /* CHARSET_EBCDIC */
00068 };
00069 
00070 #ifdef CHARSET_EBCDIC
00071 
00072 static unsigned char os_toascii[256] = {
00073   /* 0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F */
00074   0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15,
00075   16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31,
00076   128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7,
00077   144, 145, 22, 147, 148, 149, 150, 4, 152, 153, 154, 155, 20, 21, 158, 26,
00078   32, 160, 226, 228, 224, 225, 227, 229, 231, 241, 162, 46, 60, 40, 43, 124,
00079   38, 233, 234, 235, 232, 237, 238, 239, 236, 223, 33, 36, 42, 41, 59, 172,
00080   45, 47, 194, 196, 192, 193, 195, 197, 199, 209, 166, 44, 37, 95, 62, 63,
00081   248, 201, 202, 203, 200, 205, 206, 207, 204, 96, 58, 35, 64, 39, 61, 34,
00082   216, 97, 98, 99, 100, 101, 102, 103, 104, 105, 171, 187, 240, 253, 254, 177,
00083   176, 106, 107, 108, 109, 110, 111, 112, 113, 114, 170, 186, 230, 184, 198, 164,
00084   181, 126, 115, 116, 117, 118, 119, 120, 121, 122, 161, 191, 208, 221, 222, 174,
00085   94, 163, 165, 183, 169, 167, 182, 188, 189, 190, 91, 93, 175, 168, 180, 215,
00086   123, 65, 66, 67, 68, 69, 70, 71, 72, 73, 173, 244, 246, 242, 243, 245,
00087   125, 74, 75, 76, 77, 78, 79, 80, 81, 82, 185, 251, 252, 249, 250, 255,
00088   92, 247, 83, 84, 85, 86, 87, 88, 89, 90, 178, 212, 214, 210, 211, 213,
00089   48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 179, 219, 220, 217, 218, 159
00090 };
00091 
00092 #endif /* CHARSET_EBCDIC */
00093 
00094 /* This is the same as base64_decode() except on EBCDIC machines, where
00095  * the conversion of the output to ebcdic is left out.
00096  */
00097 static int base64_decode_binary(unsigned char *bufplain,
00098                                 const char *bufcoded) {
00099   int nbytesdecoded;
00100   register const unsigned char *bufin;
00101   register unsigned char *bufout;
00102   register int nprbytes;
00103 
00104   bufin = (const unsigned char*)bufcoded;
00105   while (pr2six[*(bufin++)] <= 63) {}
00106   nprbytes = (bufin - (const unsigned char*)bufcoded) - 1;
00107   nbytesdecoded = ((nprbytes + 3) / 4) * 3;
00108 
00109   bufout = (unsigned char*)bufplain;
00110   bufin = (const unsigned char*)bufcoded;
00111 
00112   while (nprbytes > 4) {
00113     *(bufout++) =
00114       (unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
00115     *(bufout++) =
00116       (unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
00117     *(bufout++) =
00118       (unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
00119     bufin += 4;
00120     nprbytes -= 4;
00121   }
00122 
00123   /* Note: (nprbytes == 1) would be an error, so just ingore that case */
00124   if (nprbytes > 1)
00125     *(bufout++) =
00126       (unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
00127   if (nprbytes > 2)
00128     *(bufout++) =
00129       (unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
00130   if (nprbytes > 3)
00131     *(bufout++) =
00132       (unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
00133 
00134   nbytesdecoded -= (4 - nprbytes) & 3;
00135   return nbytesdecoded;
00136 }
00137 
00138 static const char basis_64[] =
00139   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00140 
00141 /* This is the same as base64_encode() except on EBCDIC machines, where
00142  * the conversion of the input to ascii is left out.
00143  */
00144 static int base64_encode_binary(char *encoded,
00145                                 const unsigned char *string, int len) {
00146   int i;
00147   char *p;
00148 
00149   p = encoded;
00150   for (i = 0; i < len - 2; i += 3) {
00151     *p++ = basis_64[(string[i] >> 2) & 0x3F];
00152     *p++ = basis_64[((string[i] & 0x3) << 4) |
00153                     ((int)(string[i + 1] & 0xF0) >> 4)];
00154     *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
00155                     ((int)(string[i + 2] & 0xC0) >> 6)];
00156     *p++ = basis_64[string[i + 2] & 0x3F];
00157   }
00158   if (i < len) {
00159     *p++ = basis_64[(string[i] >> 2) & 0x3F];
00160     if (i == (len - 1)) {
00161       *p++ = basis_64[((string[i] & 0x3) << 4)];
00162       *p++ = '=';
00163     }
00164     else {
00165       *p++ = basis_64[((string[i] & 0x3) << 4) |
00166                       ((int)(string[i + 1] & 0xF0) >> 4)];
00167       *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
00168     }
00169     *p++ = '=';
00170   }
00171 
00172   *p++ = '\0';
00173   return p - encoded;
00174 }
00175 
00176 
00177 namespace Arc {
00178   int Base64::decode_len(const char *bufcoded) {
00179     int nbytesdecoded;
00180     register const unsigned char *bufin;
00181     register int nprbytes;
00182 
00183     bufin = (const unsigned char*)bufcoded;
00184     while (pr2six[*(bufin++)] <= 63) {}
00185 
00186     nprbytes = (bufin - (const unsigned char*)bufcoded) - 1;
00187     nbytesdecoded = ((nprbytes + 3) / 4) * 3;
00188 
00189     return nbytesdecoded + 1;
00190   }
00191 
00192   int Base64::decode(char *bufplain, const char *bufcoded) {
00193     int len;
00194     len = base64_decode_binary((unsigned char*)bufplain, bufcoded);
00195     bufplain[len] = '\0';
00196     return len;
00197   }
00198 
00199   int Base64::encode_len(int len) {
00200     return ((len + 2) / 3 * 4) + 1;
00201   }
00202 
00203   int Base64::encode(char *encoded, const char *string, int len) {
00204   #ifndef CHARSET_EBCDIC
00205     return base64_encode_binary(encoded, (const unsigned char*)string, len);
00206   #else /* CHARSET_EBCDIC */
00207     int i;
00208     char *p;
00209 
00210     p = encoded;
00211     for (i = 0; i < len - 2; i += 3) {
00212       *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F];
00213       *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) |
00214                       ((int)(os_toascii[string[i + 1]] & 0xF0) >> 4)];
00215       *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2) |
00216                       ((int)(os_toascii[string[i + 2]] & 0xC0) >> 6)];
00217       *p++ = basis_64[os_toascii[string[i + 2]] & 0x3F];
00218     }
00219     if (i < len) {
00220       *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F];
00221       if (i == (len - 1)) {
00222         *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4)];
00223         *p++ = '=';
00224       }
00225       else {
00226         *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) |
00227                         ((int)(os_toascii[string[i + 1]] & 0xF0) >> 4)];
00228         *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2)];
00229       }
00230       *p++ = '=';
00231     }
00232 
00233     *p++ = '\0';
00234     return p - encoded;
00235   #endif                /* CHARSET_EBCDIC */
00236   }
00237 
00238 }