mxw_wotlk_azerothcore/deps/acelite/ace/Codecs.cpp

231 lines
5.0 KiB
C++

#include "ace/Codecs.h"
#include "ace/Log_Category.h"
#include "ace/OS_Memory.h"
#include "ace/OS_NS_ctype.h"
namespace
{
// Just in case ...
#undef alphabet
#undef pad
#undef max_columns
// Symbols which form the Base64 alphabet (Defined as per RFC 2045)
ACE_Byte const alphabet[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
// The padding character used in the encoding
ACE_Byte const pad = '=';
// Number of columns per line of encoded output (Can have a maximum
// value of 76).
int const max_columns = 72;
}
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
bool ACE_Base64::init_ = false;
ACE_Byte ACE_Base64::decoder_[256];
ACE_Byte ACE_Base64::member_[256];
ACE_Byte*
ACE_Base64::encode (const ACE_Byte* input,
const size_t input_len,
size_t* output_len,
bool is_chunked)
{
if (!ACE_Base64::init_)
ACE_Base64::init();
if (!input)
return 0;
ACE_Byte* result = 0;
size_t length = ((input_len + 2) / 3) * 4;
size_t num_lines = length / max_columns + 1;
length += num_lines + 1;
ACE_NEW_RETURN (result, ACE_Byte[length], 0);
int char_count = 0;
int bits = 0;
size_t pos = 0;
int cols = 0;
for (size_t i = 0; i < input_len; ++i)
{
bits += input[i];
++char_count;
if (char_count == 3)
{
result[pos++] = alphabet[bits >> 18];
result[pos++] = alphabet[(bits >> 12) & 0x3f];
result[pos++] = alphabet[(bits >> 6) & 0x3f];
result[pos++] = alphabet[bits & 0x3f];
cols += 4;
if (cols == max_columns) {
if (is_chunked)
result[pos++] = '\n';
cols = 0;
}
bits = 0;
char_count = 0;
}
else
{
bits <<= 8;
}
}
if (char_count != 0)
{
bits <<= (16 - (8 * char_count));
result[pos++] = alphabet[bits >> 18];
result[pos++] = alphabet[(bits >> 12) & 0x3f];
cols += 2;
if (char_count == 1)
{
result[pos++] = pad;
result[pos++] = pad;
cols += 2;
}
else
{
result[pos++] = alphabet[(bits >> 6) & 0x3f];
result[pos++] = pad;
cols += 2;
}
}
if (cols > 0 && is_chunked)
result[pos++] = '\n';
result[pos] = 0;
*output_len = pos;
return result;
}
size_t
ACE_Base64::length (const ACE_Byte* input)
{
if (!ACE_Base64::init_)
ACE_Base64::init();
ACE_Byte* ptr = const_cast<ACE_Byte*> (input);
while (*ptr != 0 &&
(member_[*(ptr)] == 1 || *ptr == pad
|| ACE_OS::ace_isspace (*ptr)))
++ptr;
size_t len = ptr - input;
len = ((len + 3) / 4) * 3 + 1 ;
return len;
}
ACE_Byte*
ACE_Base64::decode (const ACE_Byte* input, size_t* output_len)
{
if (!ACE_Base64::init_)
ACE_Base64::init();
if (!input)
return 0;
size_t result_len = ACE_Base64::length (input);
ACE_Byte* result = 0;
ACE_NEW_RETURN (result, ACE_Byte[result_len], 0);
ACE_Byte* ptr = const_cast<ACE_Byte*> (input);
while (*ptr != 0 &&
(member_[*(ptr)] == 1 || *ptr == pad
|| ACE_OS::ace_isspace (*ptr)))
++ptr;
size_t input_len = ptr - input;
int char_count = 0;
int bits = 0;
size_t pos = 0;
size_t i = 0;
for (; i < input_len; ++i)
{
if (input[i] == pad)
break;
if (!ACE_Base64::member_[input[i]])
continue;
bits += decoder_[input[i]];
++char_count;
if (char_count == 4)
{
result[pos++] = static_cast<ACE_Byte> (bits >> 16);
result[pos++] = static_cast<ACE_Byte> ((bits >> 8) & 0xff);
result[pos++] = static_cast<ACE_Byte> (bits & 0xff);
bits = 0;
char_count = 0;
}
else
{
bits <<= 6;
}
}
int errors = 0;
if ( i == input_len)
{
if (char_count)
{
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("Decoding incomplete: atleast %d bits truncated\n"),
(4 - char_count) * 6));
++errors;
}
}
else
{
switch (char_count)
{
case 1:
ACELIB_ERROR ((LM_ERROR,
ACE_TEXT ("Decoding incomplete: atleast 2 bits missing\n")));
++errors;
break;
case 2:
result[pos++] = static_cast<ACE_Byte> (bits >> 10);
break;
case 3:
result[pos++] = static_cast<ACE_Byte> (bits >> 16);
result[pos++] = static_cast<ACE_Byte> ((bits >> 8) & 0xff);
break;
}
}
if (errors)
{
delete[] result;
return 0;
}
result[pos] = 0;
*output_len = pos;
return result;
}
void
ACE_Base64::init ()
{
if (!ACE_Base64::init_)
{
for (ACE_Byte i = 0; i < sizeof (alphabet); ++i)
{
ACE_Base64::decoder_[alphabet[i]] = i;
ACE_Base64::member_ [alphabet[i]] = 1;
}
ACE_Base64::init_ = true;
}
return;
}
ACE_END_VERSIONED_NAMESPACE_DECL