diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64 | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64')
-rw-r--r-- | contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp new file mode 100644 index 0000000000..2103d6d5a6 --- /dev/null +++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp @@ -0,0 +1,148 @@ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/core/utils/base64/Base64.h> +#include <cstring> + +using namespace Aws::Utils::Base64; + +static const uint8_t SENTINEL_VALUE = 255; +static const char BASE64_ENCODING_TABLE_MIME[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +namespace Aws +{ +namespace Utils +{ +namespace Base64 +{ + +Base64::Base64(const char *encodingTable) +{ + if(encodingTable == nullptr) + { + encodingTable = BASE64_ENCODING_TABLE_MIME; + } + + size_t encodingTableLength = strlen(encodingTable); + if(encodingTableLength != 64) + { + encodingTable = BASE64_ENCODING_TABLE_MIME; + encodingTableLength = 64; + } + + memcpy(m_mimeBase64EncodingTable, encodingTable, encodingTableLength); + + memset((void *)m_mimeBase64DecodingTable, 0, 256); + + for(uint32_t i = 0; i < encodingTableLength; ++i) + { + uint32_t index = static_cast<uint32_t>(m_mimeBase64EncodingTable[i]); + m_mimeBase64DecodingTable[index] = static_cast<uint8_t>(i); + } + + m_mimeBase64DecodingTable[(uint32_t)'='] = SENTINEL_VALUE; +} + +Aws::String Base64::Encode(const Aws::Utils::ByteBuffer& buffer) const +{ + size_t bufferLength = buffer.GetLength(); + size_t blockCount = (bufferLength + 2) / 3; + size_t remainderCount = (bufferLength % 3); + + Aws::String outputString; + outputString.reserve(CalculateBase64EncodedLength(buffer)); + + for(size_t i = 0; i < bufferLength; i += 3 ) + { + uint32_t block = buffer[ i ]; + + block <<= 8; + if (i + 1 < bufferLength) + { + block = block | buffer[ i + 1 ]; + } + + block <<= 8; + if (i + 2 < bufferLength) + { + block = block | buffer[ i + 2 ]; + } + + outputString.push_back(m_mimeBase64EncodingTable[(block >> 18) & 0x3F]); + outputString.push_back(m_mimeBase64EncodingTable[(block >> 12) & 0x3F]); + outputString.push_back(m_mimeBase64EncodingTable[(block >> 6) & 0x3F]); + outputString.push_back(m_mimeBase64EncodingTable[block & 0x3F]); + } + + if(remainderCount > 0) + { + outputString[blockCount * 4 - 1] = '='; + if(remainderCount == 1) + { + outputString[blockCount * 4 - 2] = '='; + } + } + + return outputString; +} + +Aws::Utils::ByteBuffer Base64::Decode(const Aws::String& str) const +{ + size_t decodedLength = CalculateBase64DecodedLength(str); + + Aws::Utils::ByteBuffer buffer(decodedLength); + + const char* rawString = str.c_str(); + size_t blockCount = str.length() / 4; + for(size_t i = 0; i < blockCount; ++i) + { + size_t stringIndex = i * 4; + + uint32_t value1 = m_mimeBase64DecodingTable[uint32_t(rawString[stringIndex])]; + uint32_t value2 = m_mimeBase64DecodingTable[uint32_t(rawString[++stringIndex])]; + uint32_t value3 = m_mimeBase64DecodingTable[uint32_t(rawString[++stringIndex])]; + uint32_t value4 = m_mimeBase64DecodingTable[uint32_t(rawString[++stringIndex])]; + + size_t bufferIndex = i * 3; + buffer[bufferIndex] = static_cast<uint8_t>((value1 << 2) | ((value2 >> 4) & 0x03)); + if(value3 != SENTINEL_VALUE) + { + buffer[++bufferIndex] = static_cast<uint8_t>(((value2 << 4) & 0xF0) | ((value3 >> 2) & 0x0F)); + if(value4 != SENTINEL_VALUE) + { + buffer[++bufferIndex] = static_cast<uint8_t>((value3 & 0x03) << 6 | value4); + } + } + } + + return buffer; +} + +size_t Base64::CalculateBase64DecodedLength(const Aws::String& b64input) +{ + const size_t len = b64input.length(); + if(len < 2) + { + return 0; + } + + size_t padding = 0; + + if (b64input[len - 1] == '=' && b64input[len - 2] == '=') //last two chars are = + padding = 2; + else if (b64input[len - 1] == '=') //last char is = + padding = 1; + + return (len * 3 / 4 - padding); +} + +size_t Base64::CalculateBase64EncodedLength(const Aws::Utils::ByteBuffer& buffer) +{ + return 4 * ((buffer.GetLength() + 2) / 3); +} + +} // namespace Base64 +} // namespace Utils +} // namespace Aws
\ No newline at end of file |