00001 #include "ace/Codecs.h"
00002 #include "ace/Log_Msg.h"
00003 #include "ace/OS_Memory.h"
00004 #include "ace/OS_NS_ctype.h"
00005
00006 ACE_RCSID (ace,
00007 Codecs,
00008 "Codecs.cpp,v 4.10 2006/03/15 15:30:22 sjiang Exp")
00009
00010 namespace
00011 {
00012
00013 #undef alphabet
00014 #undef pad
00015 #undef max_columns
00016
00017
00018 ACE_Byte const alphabet[] =
00019 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00020
00021
00022 ACE_Byte const pad = '=';
00023
00024
00025
00026 int const max_columns = 72;
00027 }
00028
00029 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00030
00031 bool ACE_Base64::init_ = false;
00032
00033 ACE_Byte ACE_Base64::decoder_[256];
00034
00035 ACE_Byte ACE_Base64::member_[256];
00036
00037 ACE_Byte*
00038 ACE_Base64::encode (const ACE_Byte* input,
00039 const size_t input_len,
00040 size_t* output_len)
00041 {
00042 if (!ACE_Base64::init_)
00043 ACE_Base64::init();
00044
00045 if (!input)
00046 return 0;
00047
00048 ACE_Byte* result = 0;
00049
00050 size_t length = ((input_len + 2) / 3) * 4;
00051 size_t num_lines = length / max_columns + 1;
00052 length += num_lines + 1;
00053 ACE_NEW_RETURN (result, ACE_Byte[length], 0);
00054
00055 int char_count = 0;
00056 int bits = 0;
00057 size_t pos = 0;
00058 int cols = 0;
00059
00060 for (size_t i = 0; i < input_len; ++i)
00061 {
00062 bits += input[i];
00063 char_count++;
00064
00065 if (char_count == 3)
00066 {
00067 result[pos++] = alphabet[bits >> 18];
00068 result[pos++] = alphabet[(bits >> 12) & 0x3f];
00069 result[pos++] = alphabet[(bits >> 6) & 0x3f];
00070 result[pos++] = alphabet[bits & 0x3f];
00071 cols += 4;
00072 if (cols == max_columns) {
00073 result[pos++] = '\n';
00074 cols = 0;
00075 }
00076 bits = 0;
00077 char_count = 0;
00078 }
00079 else
00080 {
00081 bits <<= 8;
00082 }
00083 }
00084
00085 if (char_count != 0)
00086 {
00087 bits <<= (16 - (8 * char_count));
00088 result[pos++] = alphabet[bits >> 18];
00089 result[pos++] = alphabet[(bits >> 12) & 0x3f];
00090 if (char_count == 1)
00091 {
00092 result[pos++] = pad;
00093 result[pos++] = pad;
00094 }
00095 else
00096 {
00097 result[pos++] = alphabet[(bits >> 6) & 0x3f];
00098 result[pos++] = pad;
00099 }
00100 if (cols > 0)
00101 result[pos++] = '\n';
00102 }
00103 result[pos] = 0;
00104 *output_len = pos;
00105 return result;
00106 }
00107
00108 size_t
00109 ACE_Base64::length (const ACE_Byte* input)
00110 {
00111 if (!ACE_Base64::init_)
00112 ACE_Base64::init();
00113
00114 ACE_Byte* ptr = const_cast<ACE_Byte*> (input);
00115 while (*ptr != 0 &&
00116 (member_[*(ptr)] == 1 || *ptr == pad
00117 || ACE_OS::ace_isspace (*ptr)))
00118 ptr++;
00119 size_t len = ptr - input;
00120 len = ((len + 3) / 4) * 3 + 1 ;
00121 return len;
00122 }
00123
00124 ACE_Byte*
00125 ACE_Base64::decode (const ACE_Byte* input, size_t* output_len)
00126 {
00127 if (!ACE_Base64::init_)
00128 ACE_Base64::init();
00129
00130 if (!input)
00131 return 0;
00132
00133 size_t result_len = ACE_Base64::length (input);
00134 ACE_Byte* result = 0;
00135 ACE_NEW_RETURN (result, ACE_Byte[result_len], 0);
00136
00137 ACE_Byte* ptr = const_cast<ACE_Byte*> (input);
00138 while (*ptr != 0 &&
00139 (member_[*(ptr)] == 1 || *ptr == pad
00140 || ACE_OS::ace_isspace (*ptr)))
00141 ptr++;
00142 size_t input_len = ptr - input;
00143
00144 int char_count = 0;
00145 int bits = 0;
00146 size_t pos = 0;
00147
00148 size_t i = 0;
00149 for (; i < input_len; ++i)
00150 {
00151 if (input[i] == pad)
00152 break;
00153 if (!ACE_Base64::member_[input[i]])
00154 continue;
00155 bits += decoder_[input[i]];
00156 char_count++;
00157
00158 if (char_count == 4)
00159 {
00160 result[pos++] = static_cast<ACE_Byte> (bits >> 16);
00161 result[pos++] = static_cast<ACE_Byte> ((bits >> 8) & 0xff);
00162 result[pos++] = static_cast<ACE_Byte> (bits & 0xff);
00163 bits = 0;
00164 char_count = 0;
00165 }
00166 else
00167 {
00168 bits <<= 6;
00169 }
00170 }
00171
00172 int errors = 0;
00173 if ( i == input_len)
00174 {
00175 if (char_count)
00176 {
00177 ACE_ERROR ((LM_ERROR,
00178 ACE_LIB_TEXT ("Decoding incomplete: atleast %d bits truncated\n"),
00179 (4 - char_count) * 6));
00180 errors++;
00181 }
00182 }
00183 else
00184 {
00185 switch (char_count)
00186 {
00187 case 1:
00188 ACE_ERROR ((LM_ERROR,
00189 ACE_LIB_TEXT ("Decoding incomplete: atleast 2 bits missing\n")));
00190 errors++;
00191 break;
00192 case 2:
00193 result[pos++] = static_cast<ACE_Byte> (bits >> 10);
00194 break;
00195 case 3:
00196 result[pos++] = static_cast<ACE_Byte> (bits >> 16);
00197 result[pos++] = static_cast<ACE_Byte> ((bits >> 8) & 0xff);
00198 break;
00199 }
00200 }
00201
00202 if (errors)
00203 {
00204 delete[] result;
00205 return 0;
00206 }
00207 result[pos] = 0;
00208 *output_len = pos;
00209 return result;
00210 }
00211
00212 void
00213 ACE_Base64::init ()
00214 {
00215 if (!ACE_Base64::init_)
00216 {
00217 for (ACE_Byte i = 0; i < sizeof (alphabet); ++i)
00218 {
00219 ACE_Base64::decoder_[alphabet[i]] = i;
00220 ACE_Base64::member_ [alphabet[i]] = 1;
00221 }
00222 ACE_Base64::init_ = true;
00223 }
00224 return;
00225 }
00226
00227 ACE_END_VERSIONED_NAMESPACE_DECL