1 #include "ace/Codecs.h"
2 #include "ace/Log_Category.h"
3 #include "ace/OS_Memory.h"
4 #include "ace/OS_NS_ctype.h"
6 #if defined (ACE_HAS_ALLOC_HOOKS)
7 # include "ace/Malloc_Base.h"
8 #endif /* ACE_HAS_ALLOC_HOOKS */
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
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];
38 ACE_Base64::encode (const ACE_Byte
* input
,
39 const size_t input_len
,
43 if (!ACE_Base64::init_
)
51 size_t length
= ((input_len
+ 2) / 3) * 4;
52 size_t num_lines
= length
/ max_columns
+ 1;
53 length
+= num_lines
+ 1;
54 #if defined (ACE_HAS_ALLOC_HOOKS)
55 ACE_ALLOCATOR_RETURN (result
, static_cast<ACE_Byte
*> (ACE_Allocator::instance()->malloc(sizeof (ACE_Byte
) * length
)), 0);
57 ACE_NEW_RETURN (result
, ACE_Byte
[length
], 0);
58 #endif /* ACE_HAS_ALLOC_HOOKS */
65 for (size_t i
= 0; i
< input_len
; ++i
)
72 result
[pos
++] = alphabet
[bits
>> 18];
73 result
[pos
++] = alphabet
[(bits
>> 12) & 0x3f];
74 result
[pos
++] = alphabet
[(bits
>> 6) & 0x3f];
75 result
[pos
++] = alphabet
[bits
& 0x3f];
77 if (cols
== max_columns
) {
93 bits
<<= (16 - (8 * char_count
));
94 result
[pos
++] = alphabet
[bits
>> 18];
95 result
[pos
++] = alphabet
[(bits
>> 12) & 0x3f];
105 result
[pos
++] = alphabet
[(bits
>> 6) & 0x3f];
111 if (cols
> 0 && is_chunked
)
112 result
[pos
++] = '\n';
120 ACE_Base64::length (const ACE_Byte
* input
)
122 if (!ACE_Base64::init_
)
125 ACE_Byte
* ptr
= const_cast<ACE_Byte
*> (input
);
127 (member_
[*(ptr
)] == 1 || *ptr
== pad
128 || ACE_OS::ace_isspace (*ptr
)))
130 size_t len
= ptr
- input
;
131 len
= ((len
+ 3) / 4) * 3 + 1 ;
136 ACE_Base64::decode (const ACE_Byte
* input
, size_t* output_len
)
138 if (!ACE_Base64::init_
)
144 size_t result_len
= ACE_Base64::length (input
);
145 ACE_Byte
* result
= 0;
147 #if defined (ACE_HAS_ALLOC_HOOKS)
148 ACE_ALLOCATOR_RETURN (result
, static_cast<ACE_Byte
*> (ACE_Allocator::instance()->malloc(sizeof (ACE_Byte
) * result_len
)), 0);
150 ACE_NEW_RETURN (result
, ACE_Byte
[result_len
], 0);
151 #endif /* ACE_HAS_ALLOC_HOOKS */
153 ACE_Byte
* ptr
= const_cast<ACE_Byte
*> (input
);
155 (member_
[*(ptr
)] == 1 || *ptr
== pad
156 || ACE_OS::ace_isspace (*ptr
)))
158 size_t input_len
= ptr
- input
;
165 for (; i
< input_len
; ++i
)
169 if (!ACE_Base64::member_
[input
[i
]])
171 bits
+= decoder_
[input
[i
]];
176 result
[pos
++] = static_cast<ACE_Byte
> (bits
>> 16);
177 result
[pos
++] = static_cast<ACE_Byte
> ((bits
>> 8) & 0xff);
178 result
[pos
++] = static_cast<ACE_Byte
> (bits
& 0xff);
193 ACELIB_ERROR ((LM_ERROR
,
194 ACE_TEXT ("Decoding incomplete: atleast %d bits truncated\n"),
195 (4 - char_count
) * 6));
204 ACELIB_ERROR ((LM_ERROR
,
205 ACE_TEXT ("Decoding incomplete: atleast 2 bits missing\n")));
209 result
[pos
++] = static_cast<ACE_Byte
> (bits
>> 10);
212 result
[pos
++] = static_cast<ACE_Byte
> (bits
>> 16);
213 result
[pos
++] = static_cast<ACE_Byte
> ((bits
>> 8) & 0xff);
220 #if defined (ACE_HAS_ALLOC_HOOKS)
221 ACE_Allocator::instance()->free(result
);
224 #endif /* ACE_HAS_ALLOC_HOOKS */
235 if (!ACE_Base64::init_
)
237 for (ACE_Byte i
= 0; i
< sizeof (alphabet
); ++i
)
239 ACE_Base64::decoder_
[alphabet
[i
]] = i
;
240 ACE_Base64::member_
[alphabet
[i
]] = 1;
242 ACE_Base64::init_
= true;
247 ACE_END_VERSIONED_NAMESPACE_DECL