Codecs.cpp

Go to the documentation of this file.
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   // Just in case ...
00013 #undef alphabet
00014 #undef pad
00015 #undef max_columns
00016 
00017   // Symbols which form the Base64 alphabet (Defined as per RFC 2045)
00018   ACE_Byte const alphabet[] =
00019      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
00020 
00021   // The padding character used in the encoding
00022   ACE_Byte const pad = '=';
00023 
00024   // Number of columns per line of encoded output (Can have a maximum
00025   // value of 76).
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

Generated on Thu Nov 9 09:41:48 2006 for ACE by doxygen 1.3.6