33 * SPDX-License-Identifier: Apache-2.0.
44 */
55
6+ #include < aws/core/utils/UnreferencedParam.h>
67#include < aws/core/utils/base64/Base64.h>
7- #include < cstring >
8+ #include < aws/crt/Types.h >
89
910using namespace Aws ::Utils::Base64;
1011
11- static const uint8_t SENTINEL_VALUE = 255 ;
12- static const char BASE64_ENCODING_TABLE_MIME [] = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" ;
12+ namespace Aws {
13+ namespace Utils {
14+ namespace Base64 {
1315
14- namespace Aws
15- {
16- namespace Utils
17- {
18- namespace Base64
19- {
20-
21- Base64::Base64 (const char *encodingTable)
22- {
23- if (encodingTable == nullptr )
24- {
25- encodingTable = BASE64_ENCODING_TABLE_MIME ;
26- }
27-
28- size_t encodingTableLength = strlen (encodingTable);
29- if (encodingTableLength != 64 )
30- {
31- encodingTable = BASE64_ENCODING_TABLE_MIME ;
32- encodingTableLength = 64 ;
33- }
34-
35- memcpy (m_mimeBase64EncodingTable, encodingTable, encodingTableLength);
36-
37- memset ((void *)m_mimeBase64DecodingTable, 0 , 256 );
38-
39- for (uint32_t i = 0 ; i < encodingTableLength; ++i)
40- {
41- uint32_t index = static_cast <uint32_t >(m_mimeBase64EncodingTable[i]);
42- m_mimeBase64DecodingTable[index] = static_cast <uint8_t >(i);
43- }
44-
45- m_mimeBase64DecodingTable[(uint32_t )' =' ] = SENTINEL_VALUE ;
16+ namespace {
17+ Aws::Crt::ByteCursor AsCursor (const Aws::Utils::ByteBuffer& buffer) {
18+ return Aws::Crt::ByteCursorFromArray (buffer.GetUnderlyingData (), buffer.GetLength ());
4619}
4720
48- Aws::String Base64::Encode (const Aws::Utils::ByteBuffer& buffer) const
49- {
50- size_t bufferLength = buffer.GetLength ();
51- size_t blockCount = (bufferLength + 2 ) / 3 ;
52- size_t remainderCount = (bufferLength % 3 );
53-
54- Aws::String outputString;
55- outputString.reserve (CalculateBase64EncodedLength (buffer));
56-
57- for (size_t i = 0 ; i < bufferLength; i += 3 )
58- {
59- uint32_t block = buffer[ i ];
60-
61- block <<= 8 ;
62- if (i + 1 < bufferLength)
63- {
64- block = block | buffer[ i + 1 ];
65- }
66-
67- block <<= 8 ;
68- if (i + 2 < bufferLength)
69- {
70- block = block | buffer[ i + 2 ];
71- }
72-
73- outputString.push_back (m_mimeBase64EncodingTable[(block >> 18 ) & 0x3F ]);
74- outputString.push_back (m_mimeBase64EncodingTable[(block >> 12 ) & 0x3F ]);
75- outputString.push_back (m_mimeBase64EncodingTable[(block >> 6 ) & 0x3F ]);
76- outputString.push_back (m_mimeBase64EncodingTable[block & 0x3F ]);
77- }
78-
79- if (remainderCount > 0 )
80- {
81- outputString[blockCount * 4 - 1 ] = ' =' ;
82- if (remainderCount == 1 )
83- {
84- outputString[blockCount * 4 - 2 ] = ' =' ;
85- }
86- }
87-
88- return outputString;
21+ Aws::Crt::ByteCursor AsCursor (const Aws::String& str) {
22+ return Aws::Crt::ByteCursorFromArray (reinterpret_cast <const uint8_t *>(str.data ()), str.length ());
8923}
24+ } // namespace
9025
91- Aws::Utils::ByteBuffer Base64::Decode (const Aws::String& str) const
92- {
93- size_t decodedLength = CalculateBase64DecodedLength (str);
94-
95- Aws::Utils::ByteBuffer buffer (decodedLength);
96-
97- const char * rawString = str.c_str ();
98- size_t blockCount = str.length () / 4 ;
99- for (size_t i = 0 ; i < blockCount; ++i)
100- {
101- size_t stringIndex = i * 4 ;
26+ Base64::Base64 (const char * encodingTable) { AWS_UNREFERENCED_PARAM (encodingTable); }
10227
103- uint32_t value1 = m_mimeBase64DecodingTable[uint32_t (rawString[stringIndex])];
104- uint32_t value2 = m_mimeBase64DecodingTable[uint32_t (rawString[++stringIndex])];
105- uint32_t value3 = m_mimeBase64DecodingTable[uint32_t (rawString[++stringIndex])];
106- uint32_t value4 = m_mimeBase64DecodingTable[uint32_t (rawString[++stringIndex])];
107-
108- size_t bufferIndex = i * 3 ;
109- buffer[bufferIndex] = static_cast <uint8_t >((value1 << 2 ) | ((value2 >> 4 ) & 0x03 ));
110- if (value3 != SENTINEL_VALUE )
111- {
112- buffer[++bufferIndex] = static_cast <uint8_t >(((value2 << 4 ) & 0xF0 ) | ((value3 >> 2 ) & 0x0F ));
113- if (value4 != SENTINEL_VALUE )
114- {
115- buffer[++bufferIndex] = static_cast <uint8_t >((value3 & 0x03 ) << 6 | value4);
116- }
117- }
118- }
119-
120- return buffer;
28+ Aws::String Base64::Encode (const Aws::Utils::ByteBuffer& buffer) const {
29+ const auto encoded = Aws::Crt::Base64Encode (AsCursor (buffer));
30+ return {encoded.data (), encoded.size ()};
12131}
12232
123- size_t Base64::CalculateBase64DecodedLength (const Aws::String& b64input)
124- {
125- const size_t len = b64input.length ();
126- if (len < 2 )
127- {
128- return 0 ;
129- }
130-
131- size_t padding = 0 ;
132-
133- if (b64input[len - 1 ] == ' =' && b64input[len - 2 ] == ' =' ) // last two chars are =
134- padding = 2 ;
135- else if (b64input[len - 1 ] == ' =' ) // last char is =
136- padding = 1 ;
33+ Aws::Utils::ByteBuffer Base64::Decode (const Aws::String& str) const {
34+ const auto decoded = Aws::Crt::Base64Decode (AsCursor (str));
35+ return {decoded.data (), decoded.size ()};
36+ }
13737
138- return (len * 3 / 4 - padding);
38+ size_t Base64::CalculateBase64EncodedLength (const Aws::Utils::ByteBuffer& buffer) {
39+ return Aws::Crt::Base64EncodedLength (AsCursor (buffer));
13940}
14041
141- size_t Base64::CalculateBase64EncodedLength (const Aws::Utils::ByteBuffer& buffer)
142- {
143- return 4 * ((buffer.GetLength () + 2 ) / 3 );
42+ size_t Base64::CalculateBase64DecodedLength (const Aws::String& b64input) {
43+ return Aws::Crt::Base64DecodedLength (AsCursor (b64input));
14444}
14545
146- } // namespace Base64
147- } // namespace Utils
148- } // namespace Aws
46+ } // namespace Base64
47+ } // namespace Utils
48+ } // namespace Aws
0 commit comments