[7297] Fixed profession spells sorting in trainer spell list at client.
[getmangos.git] / dep / ACE_wrappers / ace / Codecs.cpp
blob71491fe1c44cd5ab2742d63e3927f46c4e0a31b6
1 #include "ace/Codecs.h"
2 #include "ace/Log_Msg.h"
3 #include "ace/OS_Memory.h"
4 #include "ace/OS_NS_ctype.h"
6 ACE_RCSID (ace,
7 Codecs,
8 "$Id: Codecs.cpp 80826 2008-03-04 14:51:23Z wotte $")
10 namespace
12 // Just in case ...
13 #undef alphabet
14 #undef pad
15 #undef max_columns
17 // Symbols which form the Base64 alphabet (Defined as per RFC 2045)
18 ACE_Byte const alphabet[] =
19 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
21 // The padding character used in the encoding
22 ACE_Byte const pad = '=';
24 // Number of columns per line of encoded output (Can have a maximum
25 // value of 76).
26 int const max_columns = 72;
29 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
31 bool ACE_Base64::init_ = false;
33 ACE_Byte ACE_Base64::decoder_[256];
35 ACE_Byte ACE_Base64::member_[256];
37 ACE_Byte*
38 ACE_Base64::encode (const ACE_Byte* input,
39 const size_t input_len,
40 size_t* output_len,
41 bool is_chunked)
43 if (!ACE_Base64::init_)
44 ACE_Base64::init();
46 if (!input)
47 return 0;
49 ACE_Byte* result = 0;
51 size_t length = ((input_len + 2) / 3) * 4;
52 size_t num_lines = length / max_columns + 1;
53 length += num_lines + 1;
54 ACE_NEW_RETURN (result, ACE_Byte[length], 0);
56 int char_count = 0;
57 int bits = 0;
58 size_t pos = 0;
59 int cols = 0;
61 for (size_t i = 0; i < input_len; ++i)
63 bits += input[i];
64 ++char_count;
66 if (char_count == 3)
68 result[pos++] = alphabet[bits >> 18];
69 result[pos++] = alphabet[(bits >> 12) & 0x3f];
70 result[pos++] = alphabet[(bits >> 6) & 0x3f];
71 result[pos++] = alphabet[bits & 0x3f];
72 cols += 4;
73 if (cols == max_columns) {
74 if (is_chunked)
75 result[pos++] = '\n';
76 cols = 0;
78 bits = 0;
79 char_count = 0;
81 else
83 bits <<= 8;
87 if (char_count != 0)
89 bits <<= (16 - (8 * char_count));
90 result[pos++] = alphabet[bits >> 18];
91 result[pos++] = alphabet[(bits >> 12) & 0x3f];
92 cols += 2;
93 if (char_count == 1)
95 result[pos++] = pad;
96 result[pos++] = pad;
97 cols += 2;
99 else
101 result[pos++] = alphabet[(bits >> 6) & 0x3f];
102 result[pos++] = pad;
103 cols += 2;
107 if (cols > 0 && is_chunked)
108 result[pos++] = '\n';
110 result[pos] = 0;
111 *output_len = pos;
112 return result;
115 size_t
116 ACE_Base64::length (const ACE_Byte* input)
118 if (!ACE_Base64::init_)
119 ACE_Base64::init();
121 ACE_Byte* ptr = const_cast<ACE_Byte*> (input);
122 while (*ptr != 0 &&
123 (member_[*(ptr)] == 1 || *ptr == pad
124 || ACE_OS::ace_isspace (*ptr)))
125 ++ptr;
126 size_t len = ptr - input;
127 len = ((len + 3) / 4) * 3 + 1 ;
128 return len;
131 ACE_Byte*
132 ACE_Base64::decode (const ACE_Byte* input, size_t* output_len)
134 if (!ACE_Base64::init_)
135 ACE_Base64::init();
137 if (!input)
138 return 0;
140 size_t result_len = ACE_Base64::length (input);
141 ACE_Byte* result = 0;
142 ACE_NEW_RETURN (result, ACE_Byte[result_len], 0);
144 ACE_Byte* ptr = const_cast<ACE_Byte*> (input);
145 while (*ptr != 0 &&
146 (member_[*(ptr)] == 1 || *ptr == pad
147 || ACE_OS::ace_isspace (*ptr)))
148 ++ptr;
149 size_t input_len = ptr - input;
151 int char_count = 0;
152 int bits = 0;
153 size_t pos = 0;
155 size_t i = 0;
156 for (; i < input_len; ++i)
158 if (input[i] == pad)
159 break;
160 if (!ACE_Base64::member_[input[i]])
161 continue;
162 bits += decoder_[input[i]];
163 ++char_count;
165 if (char_count == 4)
167 result[pos++] = static_cast<ACE_Byte> (bits >> 16);
168 result[pos++] = static_cast<ACE_Byte> ((bits >> 8) & 0xff);
169 result[pos++] = static_cast<ACE_Byte> (bits & 0xff);
170 bits = 0;
171 char_count = 0;
173 else
175 bits <<= 6;
179 int errors = 0;
180 if ( i == input_len)
182 if (char_count)
184 ACE_ERROR ((LM_ERROR,
185 ACE_TEXT ("Decoding incomplete: atleast %d bits truncated\n"),
186 (4 - char_count) * 6));
187 ++errors;
190 else
192 switch (char_count)
194 case 1:
195 ACE_ERROR ((LM_ERROR,
196 ACE_TEXT ("Decoding incomplete: atleast 2 bits missing\n")));
197 ++errors;
198 break;
199 case 2:
200 result[pos++] = static_cast<ACE_Byte> (bits >> 10);
201 break;
202 case 3:
203 result[pos++] = static_cast<ACE_Byte> (bits >> 16);
204 result[pos++] = static_cast<ACE_Byte> ((bits >> 8) & 0xff);
205 break;
209 if (errors)
211 delete[] result;
212 return 0;
214 result[pos] = 0;
215 *output_len = pos;
216 return result;
219 void
220 ACE_Base64::init ()
222 if (!ACE_Base64::init_)
224 for (ACE_Byte i = 0; i < sizeof (alphabet); ++i)
226 ACE_Base64::decoder_[alphabet[i]] = i;
227 ACE_Base64::member_ [alphabet[i]] = 1;
229 ACE_Base64::init_ = true;
231 return;
234 ACE_END_VERSIONED_NAMESPACE_DECL