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