Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Codecs.cpp

Go to the documentation of this file.
00001 #include "ace_pch.h"
00002 // $Id: Codecs.cpp,v 1.1.1.1.2.1 2003/03/13 19:44:20 chad Exp $
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 }

Generated on Mon Jun 16 11:19:22 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002