aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils')
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/ARN.cpp46
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Array.cpp65
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp55
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp1502
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp323
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp33
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp51
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp36
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp236
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/StringUtils.cpp421
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp54
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp90
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/base64/Base64.cpp148
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp123
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp34
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp61
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoBuf.cpp348
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoStream.cpp52
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/EncryptionMaterials.cpp19
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/KeyWrapAlgorithm.cpp68
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/MD5.cpp31
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp30
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256HMAC.cpp34
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp895
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp987
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventDecoderStream.cpp22
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventEncoderStream.cpp28
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventHeader.cpp107
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventMessage.cpp132
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamBuf.cpp147
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamDecoder.cpp170
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamEncoder.cpp162
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamErrors.cpp66
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp665
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp51
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp22
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp117
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp99
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/LogLevel.cpp45
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/AWSMemory.cpp134
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/stl/SimpleStringStream.cpp66
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ConcurrentStreamBuf.cpp126
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/PreallocatedStreamBuf.cpp75
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp91
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/SimpleStreamBuf.cpp239
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Executor.cpp155
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ReaderWriterLock.cpp64
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Semaphore.cpp39
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ThreadTask.cpp46
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp302
50 files changed, 8912 insertions, 0 deletions
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/ARN.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/ARN.cpp
new file mode 100644
index 0000000000..dac358c09d
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/ARN.cpp
@@ -0,0 +1,46 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/ARN.h>
+#include <aws/core/utils/StringUtils.h>
+#include <aws/core/utils/logging/LogMacros.h>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ ARN::ARN(const Aws::String& arnString)
+ {
+ m_valid = false;
+
+ // An ARN can be identified as any string starting with arn: with 6 defined segments each separated by a :
+ const auto result = StringUtils::Split(arnString, ':', StringUtils::SplitOptions::INCLUDE_EMPTY_ENTRIES);
+
+ if (result.size() < 6)
+ {
+ return;
+ }
+
+ if (result[0] != "arn")
+ {
+ return;
+ }
+
+ m_arnString = arnString;
+ m_partition = result[1];
+ m_service = result[2];
+ m_region = result[3];
+ m_accountId = result[4];
+ m_resource = result[5];
+
+ for (size_t i = 6; i < result.size(); i++)
+ {
+ m_resource += ":" + result[i];
+ }
+
+ m_valid = true;
+ }
+ }
+} \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Array.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Array.cpp
new file mode 100644
index 0000000000..43e7863421
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Array.cpp
@@ -0,0 +1,65 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/Array.h>
+
+#include <aws/core/platform/Security.h>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ Array<CryptoBuffer> CryptoBuffer::Slice(size_t sizeOfSlice) const
+ {
+ assert(sizeOfSlice <= GetLength());
+
+ size_t numberOfSlices = (GetLength() + sizeOfSlice - 1) / sizeOfSlice;
+ size_t currentSliceIndex = 0;
+ Array<CryptoBuffer> slices(numberOfSlices);
+
+ for (size_t i = 0; i < numberOfSlices - 1; ++i)
+ {
+ CryptoBuffer newArray(sizeOfSlice);
+ for (size_t cpyIdx = 0; cpyIdx < newArray.GetLength(); ++cpyIdx)
+ {
+ newArray[cpyIdx] = GetItem(cpyIdx + currentSliceIndex);
+ }
+ currentSliceIndex += sizeOfSlice;
+ slices[i] = std::move(newArray);
+ }
+
+ CryptoBuffer lastArray(GetLength() % sizeOfSlice == 0 ? sizeOfSlice : GetLength() % sizeOfSlice );
+ for (size_t cpyIdx = 0; cpyIdx < lastArray.GetLength(); ++cpyIdx)
+ {
+ lastArray[cpyIdx] = GetItem(cpyIdx + currentSliceIndex);
+ }
+ slices[slices.GetLength() - 1] = std::move(lastArray);
+
+ return slices;
+ }
+
+ CryptoBuffer& CryptoBuffer::operator^(const CryptoBuffer& operand)
+ {
+ size_t smallestSize = std::min<size_t>(GetLength(), operand.GetLength());
+ for (size_t i = 0; i < smallestSize; ++i)
+ {
+ (*this)[i] ^= operand[i];
+ }
+
+ return *this;
+ }
+
+ /**
+ * Zero out the array securely
+ */
+ void CryptoBuffer::Zero()
+ {
+ if (GetUnderlyingData())
+ {
+ Aws::Security::SecureMemClear(GetUnderlyingData(), GetLength());
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp
new file mode 100644
index 0000000000..ce588150e2
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DNS.cpp
@@ -0,0 +1,55 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/DNS.h>
+#include <aws/core/utils/StringUtils.h>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ bool IsValidDnsLabel(const Aws::String& label)
+ {
+ // Valid DNS hostnames are composed of valid DNS labels separated by a period.
+ // Valid DNS labels are characterized by the following:
+ // 1- Only contains alphanumeric characters and/or dashes
+ // 2- Cannot start or end with a dash
+ // 3- Have a maximum length of 63 characters (the entirety of the domain name should be less than 255 bytes)
+
+ if (label.empty())
+ return false;
+
+ if (label.size() > 63)
+ return false;
+
+ if (!StringUtils::IsAlnum(label.front()))
+ return false; // '-' is not acceptable as the first character
+
+ if (!StringUtils::IsAlnum(label.back()))
+ return false; // '-' is not acceptable as the last character
+
+ for (size_t i = 1, e = label.size() - 1; i < e; ++i)
+ {
+ auto c = label[i];
+ if (c != '-' && !StringUtils::IsAlnum(c))
+ return false;
+ }
+
+ return true;
+ }
+
+ bool IsValidHost(const Aws::String& host)
+ {
+ // Valid DNS hostnames are composed of valid DNS labels separated by a period.
+ auto labels = StringUtils::Split(host, '.');
+ if (labels.empty())
+ {
+ return false;
+ }
+
+ return !std::any_of(labels.begin(), labels.end(), [](const Aws::String& label){ return !IsValidDnsLabel(label); });
+ }
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp
new file mode 100644
index 0000000000..b690c90c2d
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/DateTimeCommon.cpp
@@ -0,0 +1,1502 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/DateTime.h>
+
+#include <aws/core/platform/Time.h>
+#include <aws/core/utils/memory/stl/AWSStringStream.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <time.h>
+#include <cassert>
+#include <iostream>
+#include <cstring>
+
+static const char* CLASS_TAG = "DateTime";
+static const char* RFC822_DATE_FORMAT_STR_MINUS_Z = "%a, %d %b %Y %H:%M:%S";
+static const char* RFC822_DATE_FORMAT_STR_WITH_Z = "%a, %d %b %Y %H:%M:%S %Z";
+static const char* ISO_8601_LONG_DATE_FORMAT_STR = "%Y-%m-%dT%H:%M:%SZ";
+static const char* ISO_8601_LONG_BASIC_DATE_FORMAT_STR = "%Y%m%dT%H%M%SZ";
+
+using namespace Aws::Utils;
+
+
+std::tm CreateZeroedTm()
+{
+ std::tm timeStruct;
+ timeStruct.tm_hour = 0;
+ timeStruct.tm_isdst = -1;
+ timeStruct.tm_mday = 0;
+ timeStruct.tm_min = 0;
+ timeStruct.tm_mon = 0;
+ timeStruct.tm_sec = 0;
+ timeStruct.tm_wday = 0;
+ timeStruct.tm_yday = 0;
+ timeStruct.tm_year = 0;
+
+ return timeStruct;
+}
+
+//Get the 0-6 week day number from a string representing WeekDay. Case insensitive and will stop on abbreviation
+static int GetWeekDayNumberFromStr(const char* timeString, size_t startIndex, size_t stopIndex)
+{
+ if(stopIndex - startIndex < 3)
+ {
+ return -1;
+ }
+
+ size_t index = startIndex;
+
+ char c = timeString[index];
+ char next = 0;
+
+ //it's ugly but this should compile down to EXACTLY 3 comparisons and no memory allocations
+ switch(c)
+ {
+ case 'S':
+ case 's':
+ next = timeString[++index];
+ switch(next)
+ {
+ case 'A':
+ case 'a':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'T':
+ case 't':
+ return 6;
+ default:
+ return -1;
+ }
+ case 'U':
+ case 'u':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'N':
+ case 'n':
+ return 0;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ case 'T':
+ case 't':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'H':
+ case 'h':
+ next = timeString[++index];
+ switch(next)
+ {
+ case 'U':
+ case 'u':
+ return 4;
+ default:
+ return -1;
+ }
+ case 'U':
+ case 'u':
+ next = timeString[++index];
+ switch(next)
+ {
+ case 'E':
+ case 'e':
+ return 2;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ case 'M':
+ case 'm':
+ next = timeString[++index];
+ switch(next)
+ {
+ case 'O':
+ case 'o':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'N':
+ case 'n':
+ return 1;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ case 'W':
+ case 'w':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'E':
+ case 'e':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'D':
+ case 'd':
+ return 3;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ case 'F':
+ case 'f':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'R':
+ case 'r':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'I':
+ case 'i':
+ return 5;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+}
+
+//Get the 0-11 monthy number from a string representing Month. Case insensitive and will stop on abbreviation
+static int GetMonthNumberFromStr(const char* timeString, size_t startIndex, size_t stopIndex)
+{
+ if (stopIndex - startIndex < 3)
+ {
+ return -1;
+ }
+
+ size_t index = startIndex;
+
+ char c = timeString[index];
+ char next = 0;
+
+ //it's ugly but this should compile down to EXACTLY 3 comparisons and no memory allocations
+ switch (c)
+ {
+ case 'M':
+ case 'm':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'A':
+ case 'a':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'Y':
+ case 'y':
+ return 4;
+ case 'R':
+ case 'r':
+ return 2;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ case 'A':
+ case 'a':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'P':
+ case 'p':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'R':
+ case 'r':
+ return 3;
+ default:
+ return -1;
+ }
+ case 'U':
+ case 'u':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'G':
+ case 'g':
+ return 7;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ case 'J':
+ case 'j':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'A':
+ case 'a':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'N':
+ case 'n':
+ return 0;
+ default:
+ return -1;
+ }
+ case 'U':
+ case 'u':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'N':
+ case 'n':
+ return 5;
+ case 'L':
+ case 'l':
+ return 6;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ case 'F':
+ case 'f':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'E':
+ case 'e':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'B':
+ case 'b':
+ return 1;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ case 'S':
+ case 's':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'E':
+ case 'e':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'P':
+ case 'p':
+ return 8;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ case 'O':
+ case 'o':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'C':
+ case 'c':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'T':
+ case 't':
+ return 9;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ case 'N':
+ case 'n':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'O':
+ case 'o':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'V':
+ case 'v':
+ return 10;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ case 'D':
+ case 'd':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'E':
+ case 'e':
+ next = timeString[++index];
+ switch (next)
+ {
+ case 'C':
+ case 'c':
+ return 11;
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+ default:
+ return -1;
+ }
+}
+// Ensure local classes with generic names have internal linkage
+namespace {
+
+class DateParser
+{
+public:
+ DateParser(const char* toParse) : m_error(false), m_toParse(toParse), m_utcAssumed(true)
+ {
+ m_parsedTimestamp = CreateZeroedTm();
+ memset(m_tz, 0, 7);
+ }
+
+ virtual ~DateParser() = default;
+
+ virtual void Parse() = 0;
+ bool WasParseSuccessful() const { return !m_error; }
+ std::tm& GetParsedTimestamp() { return m_parsedTimestamp; }
+ bool ShouldIAssumeThisIsUTC() const { return m_utcAssumed; }
+ const char* GetParsedTimezone() const { return m_tz; }
+
+protected:
+ bool m_error;
+ const char* m_toParse;
+ std::tm m_parsedTimestamp;
+ bool m_utcAssumed;
+ // The size should be at least one byte greater than the maximum possible size so that we could use the last char to indicate the end of the string.
+ char m_tz[7];
+};
+
+static const int MAX_LEN = 100;
+
+//Before you send me hate mail because I'm doing this manually, I encourage you to try using std::get_time on all platforms and getting
+//uniform results. Timezone information doesn't parse on Windows and it hardly even works on GCC 4.9.x. This is the only way to make sure
+//the standard is parsed correctly. strptime isn't available one Windows. This code gets hit pretty hard during http serialization/deserialization
+//as a result I'm going for no dynamic allocations and linear complexity
+class RFC822DateParser : public DateParser
+{
+public:
+ RFC822DateParser(const char* toParse) : DateParser(toParse), m_state(0)
+ {
+ }
+
+ /**
+ * Really simple state machine for the format %a, %d %b %Y %H:%M:%S %Z
+ */
+ void Parse() override
+ {
+ size_t len = strlen(m_toParse);
+
+ //DOS check
+ if (len > MAX_LEN)
+ {
+ AWS_LOGSTREAM_WARN(CLASS_TAG, "Incoming String to parse too long with length: " << len)
+ m_error = true;
+ return;
+ }
+
+ size_t index = 0;
+ size_t stateStartIndex = 0;
+ int finalState = 8;
+
+ while(m_state <= finalState && !m_error && index < len)
+ {
+ char c = m_toParse[index];
+
+ switch (m_state)
+ {
+ case 0:
+ if(c == ',')
+ {
+ int weekNumber = GetWeekDayNumberFromStr(m_toParse, stateStartIndex, index + 1);
+
+ if (weekNumber > -1)
+ {
+ m_state = 1;
+ stateStartIndex = index + 1;
+ m_parsedTimestamp.tm_wday = weekNumber;
+ }
+ else
+ {
+ m_error = true;
+ }
+ }
+ else if(!isalpha(c))
+ {
+ m_error = true;
+ }
+ break;
+ case 1:
+ if (isspace(c))
+ {
+ m_state = 2;
+ stateStartIndex = index + 1;
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ case 2:
+ if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_mday = m_parsedTimestamp.tm_mday * 10 + (c - '0');
+ }
+ else if(isspace(c))
+ {
+ m_state = 3;
+ stateStartIndex = index + 1;
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ case 3:
+ if (isspace(c))
+ {
+ int monthNumber = GetMonthNumberFromStr(m_toParse, stateStartIndex, index + 1);
+
+ if (monthNumber > -1)
+ {
+ m_state = 4;
+ stateStartIndex = index + 1;
+ m_parsedTimestamp.tm_mon = monthNumber;
+ }
+ else
+ {
+ m_error = true;
+ }
+ }
+ else if (!isalpha(c))
+ {
+ m_error = true;
+ }
+ break;
+ case 4:
+ if (isspace(c) && index - stateStartIndex == 4)
+ {
+ m_state = 5;
+ stateStartIndex = index + 1;
+ m_parsedTimestamp.tm_year -= 1900;
+ }
+ else if (isspace(c) && index - stateStartIndex == 2)
+ {
+ m_state = 5;
+ stateStartIndex = index + 1;
+ m_parsedTimestamp.tm_year += 2000 - 1900;
+ }
+ else if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_year = m_parsedTimestamp.tm_year * 10 + (c - '0');
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ case 5:
+ if(c == ':' && index - stateStartIndex == 2)
+ {
+ m_state = 6;
+ stateStartIndex = index + 1;
+ }
+ else if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_hour = m_parsedTimestamp.tm_hour * 10 + (c - '0');
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ case 6:
+ if (c == ':' && index - stateStartIndex == 2)
+ {
+ m_state = 7;
+ stateStartIndex = index + 1;
+ }
+ else if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_min = m_parsedTimestamp.tm_min * 10 + (c - '0');
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ case 7:
+ if (isspace(c) && index - stateStartIndex == 2)
+ {
+ m_state = 8;
+ stateStartIndex = index + 1;
+ }
+ else if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_sec = m_parsedTimestamp.tm_sec * 10 + (c - '0');
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ case 8:
+ if ((isalnum(c) || c == '+' || c == '-') && (index - stateStartIndex < 5))
+ {
+ m_tz[index - stateStartIndex] = c;
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ default:
+ m_error = true;
+ break;
+ }
+
+ index++;
+ }
+
+ if (m_tz[0] != 0)
+ {
+ m_utcAssumed = IsUTCTimeZoneDesignator(m_tz);
+ }
+
+ m_error = (m_error || m_state != finalState);
+ }
+
+ int GetState() const { return m_state; }
+
+private:
+ //Detects whether or not the passed in timezone string is a UTC zone.
+ static bool IsUTCTimeZoneDesignator(const char* str)
+ {
+ size_t len = strlen(str);
+ if (len < 3)
+ {
+ return false;
+ }
+
+ int index = 0;
+ char c = str[index];
+ switch (c)
+ {
+ case 'U':
+ case 'u':
+ c = str[++index];
+ switch(c)
+ {
+ case 'T':
+ case 't':
+ c = str[++index];
+ switch(c)
+ {
+ case 'C':
+ case 'c':
+ return true;
+ default:
+ return false;
+ }
+
+ case 'C':
+ case 'c':
+ c = str[++index];
+ switch (c)
+ {
+ case 'T':
+ case 't':
+ return true;
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+ case 'G':
+ case 'g':
+ c = str[++index];
+ switch (c)
+ {
+ case 'M':
+ case 'm':
+ c = str[++index];
+ switch (c)
+ {
+ case 'T':
+ case 't':
+ return true;
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+ case '+':
+ case '-':
+ c = str[++index];
+ switch (c)
+ {
+ case '0':
+ c = str[++index];
+ switch (c)
+ {
+ case '0':
+ c = str[++index];
+ switch (c)
+ {
+ case '0':
+ return true;
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+ default:
+ return false;
+ }
+ case 'Z':
+ return true;
+ default:
+ return false;
+ }
+
+ }
+
+ int m_state;
+};
+
+//Before you send me hate mail because I'm doing this manually, I encourage you to try using std::get_time on all platforms and getting
+//uniform results. Timezone information doesn't parse on Windows and it hardly even works on GCC 4.9.x. This is the only way to make sure
+//the standard is parsed correctly. strptime isn't available one Windows. This code gets hit pretty hard during http serialization/deserialization
+//as a result I'm going for no dynamic allocations and linear complexity
+class ISO_8601DateParser : public DateParser
+{
+public:
+ ISO_8601DateParser(const char* stringToParse) : DateParser(stringToParse), m_state(0)
+ {
+ }
+
+ //parses "%Y-%m-%dT%H:%M:%SZ or "%Y-%m-%dT%H:%M:%S.000Z"
+ void Parse() override
+ {
+ size_t len = strlen(m_toParse);
+
+ //DOS check
+ if (len > MAX_LEN)
+ {
+ AWS_LOGSTREAM_WARN(CLASS_TAG, "Incoming String to parse too long with length: " << len)
+ m_error = true;
+ return;
+ }
+
+ size_t index = 0;
+ size_t stateStartIndex = 0;
+ const int finalState = 7;
+
+ while (m_state <= finalState && !m_error && index < len)
+ {
+ char c = m_toParse[index];
+ switch (m_state)
+ {
+ case 0:
+ if (c == '-' && index - stateStartIndex == 4)
+ {
+ m_state = 1;
+ stateStartIndex = index + 1;
+ m_parsedTimestamp.tm_year -= 1900;
+ }
+ else if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_year = m_parsedTimestamp.tm_year * 10 + (c - '0');
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ case 1:
+ if (c == '-' && index - stateStartIndex == 2)
+ {
+ m_state = 2;
+ stateStartIndex = index + 1;
+ m_parsedTimestamp.tm_mon -= 1;
+ }
+ else if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_mon = m_parsedTimestamp.tm_mon * 10 + (c - '0');
+ }
+ else
+ {
+ m_error = true;
+ }
+
+ break;
+ case 2:
+ if (c == 'T' && index - stateStartIndex == 2)
+ {
+ m_state = 3;
+ stateStartIndex = index + 1;
+ }
+ else if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_mday = m_parsedTimestamp.tm_mday * 10 + (c - '0');
+ }
+ else
+ {
+ m_error = true;
+ }
+
+ break;
+ case 3:
+ if (c == ':' && index - stateStartIndex == 2)
+ {
+ m_state = 4;
+ stateStartIndex = index + 1;
+ }
+ else if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_hour = m_parsedTimestamp.tm_hour * 10 + (c - '0');
+ }
+ else
+ {
+ m_error = true;
+ }
+
+ break;
+ case 4:
+ if (c == ':' && index - stateStartIndex == 2)
+ {
+ m_state = 5;
+ stateStartIndex = index + 1;
+ }
+ else if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_min = m_parsedTimestamp.tm_min * 10 + (c - '0');
+ }
+ else
+ {
+ m_error = true;
+ }
+
+ break;
+ case 5:
+ if ((c == 'Z' || c == '+' || c == '-' ) && (index - stateStartIndex == 2))
+ {
+ m_tz[0] = c;
+ m_state = 7;
+ stateStartIndex = index + 1;
+ }
+ else if (c == '.' && index - stateStartIndex == 2)
+ {
+ m_state = 6;
+ stateStartIndex = index + 1;
+ }
+ else if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_sec = m_parsedTimestamp.tm_sec * 10 + (c - '0');
+ }
+ else
+ {
+ m_error = true;
+ }
+
+ break;
+ case 6:
+ if ((c == 'Z' || c == '+' || c == '-' ) && (index - stateStartIndex == 3))
+ {
+ m_tz[0] = c;
+ m_state = 7;
+ stateStartIndex = index + 1;
+ }
+ else if(!isdigit(c))
+ {
+ m_error = true;
+ }
+ break;
+ case 7:
+ if ((isdigit(c) || c == ':') && (index - stateStartIndex < 5))
+ {
+ m_tz[1 + index - stateStartIndex] = c;
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ default:
+ m_error = true;
+ break;
+ }
+ index++;
+ }
+
+ if (m_tz[0] != 0)
+ {
+ m_utcAssumed = IsUTCTimeZoneDesignator(m_tz);
+ }
+
+ m_error = (m_error || m_state != finalState);
+ }
+
+private:
+ //Detects whether or not the passed in timezone string is a UTC zone.
+ static bool IsUTCTimeZoneDesignator(const char* str)
+ {
+ size_t len = strlen(str);
+
+ if (len > 0)
+ {
+ if (len == 1 && str[0] == 'Z')
+ {
+ return true;
+ }
+
+ if (len == 6 && str[0] == '+'
+ && str[1] == '0'
+ && str[2] == '0'
+ && str[3] == ':'
+ && str[4] == '0'
+ && str[5] == '0')
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ return false;
+ }
+
+ int m_state;
+};
+
+class ISO_8601BasicDateParser : public DateParser
+{
+public:
+ ISO_8601BasicDateParser(const char* stringToParse) : DateParser(stringToParse), m_state(0)
+ {
+ }
+
+ //parses "%Y%m%dT%H%M%SZ or "%Y%m%dT%H%M%S000Z"
+ void Parse() override
+ {
+ size_t len = strlen(m_toParse);
+
+ //DOS check
+ if (len > MAX_LEN)
+ {
+ AWS_LOGSTREAM_WARN(CLASS_TAG, "Incoming String to parse too long with length: " << len)
+ m_error = true;
+ return;
+ }
+
+ size_t index = 0;
+ size_t stateStartIndex = 0;
+ const int finalState = 7;
+
+ while (m_state <= finalState && !m_error && index < len)
+ {
+ char c = m_toParse[index];
+ switch (m_state)
+ {
+ // On year: %Y
+ case 0:
+ if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_year = m_parsedTimestamp.tm_year * 10 + (c - '0');
+ if (index - stateStartIndex == 3)
+ {
+ m_state = 1;
+ stateStartIndex = index + 1;
+ m_parsedTimestamp.tm_year -= 1900;
+ }
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ // On month: %m
+ case 1:
+ if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_mon = m_parsedTimestamp.tm_mon * 10 + (c - '0');
+ if (index - stateStartIndex == 1)
+ {
+ m_state = 2;
+ stateStartIndex = index + 1;
+ m_parsedTimestamp.tm_mon -= 1;
+ }
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ // On month day: %d
+ case 2:
+ if (c == 'T' && index - stateStartIndex == 2)
+ {
+ m_state = 3;
+ stateStartIndex = index + 1;
+ }
+ else if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_mday = m_parsedTimestamp.tm_mday * 10 + (c - '0');
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ // On hour: %H
+ case 3:
+ if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_hour = m_parsedTimestamp.tm_hour * 10 + (c - '0');
+ if (index - stateStartIndex == 1)
+ {
+ m_state = 4;
+ stateStartIndex = index + 1;
+ }
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ // On minute: %M
+ case 4:
+ if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_min = m_parsedTimestamp.tm_min * 10 + (c - '0');
+ if (index - stateStartIndex == 1)
+ {
+ m_state = 5;
+ stateStartIndex = index + 1;
+ }
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ // On second: %S
+ case 5:
+ if (isdigit(c))
+ {
+ m_parsedTimestamp.tm_sec = m_parsedTimestamp.tm_sec * 10 + (c - '0');
+ if (index - stateStartIndex == 1)
+ {
+ m_state = 6;
+ stateStartIndex = index + 1;
+ }
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ // On TZ: Z or 000Z
+ case 6:
+ if ((c == 'Z' || c == '+' || c == '-' ) && (index - stateStartIndex == 0 || index - stateStartIndex == 3))
+ {
+ m_tz[0] = c;
+ m_state = 7;
+ stateStartIndex = index + 1;
+ }
+ else if (!isdigit(c) || index - stateStartIndex > 3)
+ {
+ m_error = true;
+ }
+ break;
+ case 7:
+ if ((isdigit(c) || c == ':') && (index - stateStartIndex < 5))
+ {
+ m_tz[1 + index - stateStartIndex] = c;
+ }
+ else
+ {
+ m_error = true;
+ }
+ break;
+ default:
+ m_error = true;
+ break;
+ }
+ index++;
+ }
+
+ if (m_tz[0] != 0)
+ {
+ m_utcAssumed = IsUTCTimeZoneDesignator(m_tz);
+ }
+
+ m_error = (m_error || m_state != finalState);
+ }
+
+private:
+ //Detects whether or not the passed in timezone string is a UTC zone.
+ static bool IsUTCTimeZoneDesignator(const char* str)
+ {
+ size_t len = strlen(str);
+
+ if (len > 0)
+ {
+ if (len == 1 && str[0] == 'Z')
+ {
+ return true;
+ }
+
+ if (len == 5 && str[0] == '+'
+ && str[1] == '0'
+ && str[2] == '0'
+ && str[3] == '0'
+ && str[4] == '0')
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+ return false;
+ }
+
+ int m_state;
+};
+
+} // namespace
+
+DateTime::DateTime(const std::chrono::system_clock::time_point& timepointToAssign) : m_time(timepointToAssign), m_valid(true)
+{
+}
+
+DateTime::DateTime(int64_t millisSinceEpoch) : m_valid(true)
+{
+ std::chrono::duration<int64_t, std::chrono::milliseconds::period> timestamp(millisSinceEpoch);
+ m_time = std::chrono::system_clock::time_point(timestamp);
+}
+
+DateTime::DateTime(double epoch_millis) : m_valid(true)
+{
+ std::chrono::duration<double, std::chrono::seconds::period> timestamp(epoch_millis);
+ m_time = std::chrono::system_clock::time_point(std::chrono::duration_cast<std::chrono::milliseconds>(timestamp));
+}
+
+DateTime::DateTime(const Aws::String& timestamp, DateFormat format) : m_valid(true)
+{
+ ConvertTimestampStringToTimePoint(timestamp.c_str(), format);
+}
+
+DateTime::DateTime(const char* timestamp, DateFormat format) : m_valid(true)
+{
+ ConvertTimestampStringToTimePoint(timestamp, format);
+}
+
+DateTime::DateTime() : m_valid(true)
+{
+ //init time_point to default by doing nothing.
+}
+
+DateTime& DateTime::operator=(const Aws::String& timestamp)
+{
+ *this = DateTime(timestamp, DateFormat::AutoDetect);
+ return *this;
+}
+
+DateTime& DateTime::operator=(double secondsMillis)
+{
+ *this = DateTime(secondsMillis);
+ return *this;
+}
+
+DateTime& DateTime::operator=(int64_t millisSinceEpoch)
+{
+ *this = DateTime(millisSinceEpoch);
+ return *this;
+}
+
+DateTime& DateTime::operator=(const std::chrono::system_clock::time_point& timepointToAssign)
+{
+ *this = DateTime(timepointToAssign);
+ return *this;
+}
+
+bool DateTime::operator == (const DateTime& other) const
+{
+ return m_time == other.m_time;
+}
+
+bool DateTime::operator < (const DateTime& other) const
+{
+ return m_time < other.m_time;
+}
+
+bool DateTime::operator > (const DateTime& other) const
+{
+ return m_time > other.m_time;
+}
+
+bool DateTime::operator != (const DateTime& other) const
+{
+ return m_time != other.m_time;
+}
+
+bool DateTime::operator <= (const DateTime& other) const
+{
+ return m_time <= other.m_time;
+}
+
+bool DateTime::operator >= (const DateTime& other) const
+{
+ return m_time >= other.m_time;
+}
+
+DateTime DateTime::operator +(const std::chrono::milliseconds& a) const
+{
+ auto timepointCpy = m_time;
+ timepointCpy += a;
+ return DateTime(timepointCpy);
+}
+
+DateTime DateTime::operator -(const std::chrono::milliseconds& a) const
+{
+ auto timepointCpy = m_time;
+ timepointCpy -= a;
+ return DateTime(timepointCpy);
+}
+
+Aws::String DateTime::ToLocalTimeString(DateFormat format) const
+{
+ switch (format)
+ {
+ case DateFormat::ISO_8601:
+ return ToLocalTimeString(ISO_8601_LONG_DATE_FORMAT_STR);
+ case DateFormat::ISO_8601_BASIC:
+ return ToLocalTimeString(ISO_8601_LONG_BASIC_DATE_FORMAT_STR);
+ case DateFormat::RFC822:
+ return ToLocalTimeString(RFC822_DATE_FORMAT_STR_WITH_Z);
+ default:
+ assert(0);
+ return "";
+ }
+}
+
+Aws::String DateTime::ToLocalTimeString(const char* formatStr) const
+{
+ struct tm localTimeStamp = ConvertTimestampToLocalTimeStruct();
+
+ char formattedString[100];
+ std::strftime(formattedString, sizeof(formattedString), formatStr, &localTimeStamp);
+ return formattedString;
+}
+
+Aws::String DateTime::ToGmtString(DateFormat format) const
+{
+ switch (format)
+ {
+ case DateFormat::ISO_8601:
+ return ToGmtString(ISO_8601_LONG_DATE_FORMAT_STR);
+ case DateFormat::ISO_8601_BASIC:
+ return ToGmtString(ISO_8601_LONG_BASIC_DATE_FORMAT_STR);
+ case DateFormat::RFC822:
+ {
+ //Windows erroneously drops the local timezone in for %Z
+ Aws::String rfc822GmtString = ToGmtString(RFC822_DATE_FORMAT_STR_MINUS_Z);
+ rfc822GmtString += " GMT";
+ return rfc822GmtString;
+ }
+ default:
+ assert(0);
+ return "";
+ }
+}
+
+Aws::String DateTime::ToGmtString(const char* formatStr) const
+{
+ struct tm gmtTimeStamp = ConvertTimestampToGmtStruct();
+
+ char formattedString[100];
+ std::strftime(formattedString, sizeof(formattedString), formatStr, &gmtTimeStamp);
+ return formattedString;
+}
+
+double DateTime::SecondsWithMSPrecision() const
+{
+ std::chrono::duration<double, std::chrono::seconds::period> timestamp(m_time.time_since_epoch());
+ return timestamp.count();
+}
+
+int64_t DateTime::Millis() const
+{
+ auto timestamp = std::chrono::duration_cast<std::chrono::milliseconds>(m_time.time_since_epoch());
+ return timestamp.count();
+}
+
+std::chrono::system_clock::time_point DateTime::UnderlyingTimestamp() const
+{
+ return m_time;
+}
+
+int DateTime::GetYear(bool localTime) const
+{
+ return GetTimeStruct(localTime).tm_year + 1900;
+}
+
+Month DateTime::GetMonth(bool localTime) const
+{
+ return static_cast<Aws::Utils::Month>(GetTimeStruct(localTime).tm_mon);
+}
+
+int DateTime::GetDay(bool localTime) const
+{
+ return GetTimeStruct(localTime).tm_mday;
+}
+
+DayOfWeek DateTime::GetDayOfWeek(bool localTime) const
+{
+ return static_cast<Aws::Utils::DayOfWeek>(GetTimeStruct(localTime).tm_wday);
+}
+
+int DateTime::GetHour(bool localTime) const
+{
+ return GetTimeStruct(localTime).tm_hour;
+}
+
+int DateTime::GetMinute(bool localTime) const
+{
+ return GetTimeStruct(localTime).tm_min;
+}
+
+int DateTime::GetSecond(bool localTime) const
+{
+ return GetTimeStruct(localTime).tm_sec;
+}
+
+bool DateTime::IsDST(bool localTime) const
+{
+ return GetTimeStruct(localTime).tm_isdst == 0 ? false : true;
+}
+
+DateTime DateTime::Now()
+{
+ DateTime dateTime;
+ dateTime.m_time = std::chrono::system_clock::now();
+ return dateTime;
+}
+
+int64_t DateTime::CurrentTimeMillis()
+{
+ return Now().Millis();
+}
+
+Aws::String DateTime::CalculateLocalTimestampAsString(const char* formatStr)
+{
+ DateTime now = Now();
+ return now.ToLocalTimeString(formatStr);
+}
+
+Aws::String DateTime::CalculateGmtTimestampAsString(const char* formatStr)
+{
+ DateTime now = Now();
+ return now.ToGmtString(formatStr);
+}
+
+Aws::String DateTime::CalculateGmtTimeWithMsPrecision()
+{
+ auto now = DateTime::Now();
+ struct tm gmtTimeStamp = now.ConvertTimestampToGmtStruct();
+
+ char formattedString[100];
+ auto len = std::strftime(formattedString, sizeof(formattedString), "%Y-%m-%d %H:%M:%S", &gmtTimeStamp);
+ if (len)
+ {
+ auto ms = now.Millis();
+ ms = ms - ms / 1000 * 1000; // calculate the milliseconds as fraction.
+ formattedString[len++] = '.';
+ int divisor = 100;
+ while(divisor)
+ {
+ auto digit = ms / divisor;
+ formattedString[len++] = char('0' + digit);
+ ms = ms - divisor * digit;
+ divisor /= 10;
+ }
+ formattedString[len] = '\0';
+ }
+ return formattedString;
+}
+
+int DateTime::CalculateCurrentHour()
+{
+ return Now().GetHour(true);
+}
+
+double DateTime::ComputeCurrentTimestampInAmazonFormat()
+{
+ return Now().SecondsWithMSPrecision();
+}
+
+std::chrono::milliseconds DateTime::Diff(const DateTime& a, const DateTime& b)
+{
+ auto diff = a.m_time - b.m_time;
+ return std::chrono::duration_cast<std::chrono::milliseconds>(diff);
+}
+
+std::chrono::milliseconds DateTime::operator-(const DateTime& other) const
+{
+ auto diff = this->m_time - other.m_time;
+ return std::chrono::duration_cast<std::chrono::milliseconds>(diff);
+}
+
+void DateTime::ConvertTimestampStringToTimePoint(const char* timestamp, DateFormat format)
+{
+ std::tm timeStruct;
+ bool isUtc = true;
+
+ switch (format)
+ {
+ case DateFormat::RFC822:
+ {
+ RFC822DateParser parser(timestamp);
+ parser.Parse();
+ m_valid = parser.WasParseSuccessful();
+ isUtc = parser.ShouldIAssumeThisIsUTC();
+ timeStruct = parser.GetParsedTimestamp();
+ break;
+ }
+ case DateFormat::ISO_8601:
+ {
+ ISO_8601DateParser parser(timestamp);
+ parser.Parse();
+ m_valid = parser.WasParseSuccessful();
+ isUtc = parser.ShouldIAssumeThisIsUTC();
+ timeStruct = parser.GetParsedTimestamp();
+ break;
+ }
+ case DateFormat::ISO_8601_BASIC:
+ {
+ ISO_8601BasicDateParser parser(timestamp);
+ parser.Parse();
+ m_valid = parser.WasParseSuccessful();
+ isUtc = parser.ShouldIAssumeThisIsUTC();
+ timeStruct = parser.GetParsedTimestamp();
+ break;
+ }
+ case DateFormat::AutoDetect:
+ {
+ RFC822DateParser rfcParser(timestamp);
+ rfcParser.Parse();
+ if(rfcParser.WasParseSuccessful())
+ {
+ m_valid = true;
+ isUtc = rfcParser.ShouldIAssumeThisIsUTC();
+ timeStruct = rfcParser.GetParsedTimestamp();
+ break;
+ }
+ ISO_8601DateParser isoParser(timestamp);
+ isoParser.Parse();
+ if (isoParser.WasParseSuccessful())
+ {
+ m_valid = true;
+ isUtc = isoParser.ShouldIAssumeThisIsUTC();
+ timeStruct = isoParser.GetParsedTimestamp();
+ break;
+ }
+ ISO_8601BasicDateParser isoBasicParser(timestamp);
+ isoBasicParser.Parse();
+ if (isoBasicParser.WasParseSuccessful())
+ {
+ m_valid = true;
+ isUtc = isoBasicParser.ShouldIAssumeThisIsUTC();
+ timeStruct = isoBasicParser.GetParsedTimestamp();
+ break;
+ }
+ m_valid = false;
+ break;
+ }
+ default:
+ assert(0);
+ }
+
+ if (m_valid)
+ {
+ std::time_t tt;
+ if(isUtc)
+ {
+ tt = Aws::Time::TimeGM(&timeStruct);
+ }
+ else
+ {
+ assert(0);
+ AWS_LOGSTREAM_WARN(CLASS_TAG, "Non-UTC timestamp detected. This is always a bug. Make the world a better place and fix whatever sent you this timestamp: " << timestamp)
+ tt = std::mktime(&timeStruct);
+ }
+ m_time = std::chrono::system_clock::from_time_t(tt);
+ }
+}
+
+tm DateTime::GetTimeStruct(bool localTime) const
+{
+ return localTime ? ConvertTimestampToLocalTimeStruct() : ConvertTimestampToGmtStruct();
+}
+
+tm DateTime::ConvertTimestampToLocalTimeStruct() const
+{
+ std::time_t time = std::chrono::system_clock::to_time_t(m_time);
+ struct tm localTimeStamp;
+
+ Aws::Time::LocalTime(&localTimeStamp, time);
+
+ return localTimeStamp;
+}
+
+tm DateTime::ConvertTimestampToGmtStruct() const
+{
+ std::time_t time = std::chrono::system_clock::to_time_t(m_time);
+ struct tm gmtTimeStamp;
+ Aws::Time::GMTime(&gmtTimeStamp, time);
+
+ return gmtTimeStamp;
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp
new file mode 100644
index 0000000000..49ca56b280
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/Directory.cpp
@@ -0,0 +1,323 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/platform/FileSystem.h>
+#include <aws/core/utils/memory/stl/AWSQueue.h>
+#include <aws/core/utils/memory/stl/AWSStringStream.h>
+#include <aws/core/utils/memory/stl/AWSStreamFwd.h>
+#include <aws/core/utils/StringUtils.h>
+#include <fstream>
+#include <cassert>
+
+namespace Aws
+{
+ namespace FileSystem
+ {
+ Aws::String Join(const Aws::String& leftSegment, const Aws::String& rightSegment)
+ {
+ return Join(PATH_DELIM, leftSegment, rightSegment);
+ }
+
+ Aws::String Join(char delimiter, const Aws::String& leftSegment, const Aws::String& rightSegment)
+ {
+ Aws::StringStream ss;
+
+ if (!leftSegment.empty())
+ {
+ if (leftSegment.back() == delimiter)
+ {
+ ss << leftSegment.substr(0, leftSegment.length() - 1);
+ }
+ else
+ {
+ ss << leftSegment;
+ }
+ }
+
+ ss << delimiter;
+
+ if (!rightSegment.empty())
+ {
+ if (rightSegment.front() == delimiter)
+ {
+ ss << rightSegment.substr(1);
+ }
+ else
+ {
+ ss << rightSegment;
+ }
+ }
+
+ return ss.str();
+ }
+
+ bool DeepCopyDirectory(const char* from, const char* to)
+ {
+ if (!from || !to) return false;
+
+ DirectoryTree fromDir(from);
+
+ if (!fromDir) return false;
+
+ CreateDirectoryIfNotExists(to);
+ DirectoryTree toDir(to);
+
+ if (!toDir) return false;
+
+ bool success(true);
+
+ auto visitor = [to,&success](const DirectoryTree*, const DirectoryEntry& entry)
+ {
+ auto newPath = Aws::FileSystem::Join(to, entry.relativePath);
+
+ if (entry.fileType == Aws::FileSystem::FileType::File)
+ {
+ Aws::OFStream copyOutStream(newPath.c_str());
+ Aws::IFStream originalStream(entry.path.c_str());
+
+ if(!copyOutStream.good() || !originalStream.good())
+ {
+ success = false;
+ return false;
+ }
+
+ std::copy(std::istreambuf_iterator<char>(originalStream),
+ std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(copyOutStream));
+ }
+ else if (entry.fileType == Aws::FileSystem::FileType::Directory)
+ {
+ success = CreateDirectoryIfNotExists(newPath.c_str());
+ return success;
+ }
+
+ return success;
+ };
+
+ fromDir.TraverseDepthFirst(visitor);
+ return success;
+ }
+
+ bool DeepDeleteDirectory(const char* toDelete)
+ {
+ bool success(true);
+
+ //scope this to a new stack frame, because we won't be able to delete the root directory
+ //unless the directory handle has closed.
+ {
+ DirectoryTree delDir(toDelete);
+
+ if (!delDir) return false;
+
+ auto visitor = [&success](const DirectoryTree*, const DirectoryEntry& entry)
+ {
+ if (entry.fileType == FileType::File)
+ {
+ success = RemoveFileIfExists(entry.path.c_str());
+ }
+ else
+ {
+ success = RemoveDirectoryIfExists(entry.path.c_str());
+ }
+
+ return success;
+ };
+
+ delDir.TraverseDepthFirst(visitor, true);
+ }
+
+ if (success)
+ {
+ success = RemoveDirectoryIfExists(toDelete);
+ }
+
+ return success;
+ }
+
+ Directory::Directory(const Aws::String& path, const Aws::String& relativePath)
+ {
+ auto trimmedPath = Utils::StringUtils::Trim(path.c_str());
+ auto trimmedRelativePath = Utils::StringUtils::Trim(relativePath.c_str());
+
+ if (!trimmedPath.empty() && trimmedPath[trimmedPath.length() - 1] == PATH_DELIM)
+ {
+ m_directoryEntry.path = trimmedPath.substr(0, trimmedPath.length() - 1);
+ }
+ else
+ {
+ m_directoryEntry.path = trimmedPath;
+ }
+
+ if (!trimmedRelativePath.empty() && trimmedRelativePath[trimmedRelativePath.length() - 1] == PATH_DELIM)
+ {
+ m_directoryEntry.relativePath = trimmedRelativePath.substr(0, trimmedRelativePath.length() - 1);
+ }
+ else
+ {
+ m_directoryEntry.relativePath = trimmedRelativePath;
+ }
+ }
+
+ Aws::UniquePtr<Directory> Directory::Descend(const DirectoryEntry& directoryEntry)
+ {
+ assert(directoryEntry.fileType != FileType::File);
+ return OpenDirectory(directoryEntry.path, directoryEntry.relativePath);
+ }
+
+ Aws::Vector<Aws::String> Directory::GetAllFilePathsInDirectory(const Aws::String& path)
+ {
+ Aws::FileSystem::DirectoryTree tree(path);
+ Aws::Vector<Aws::String> filesVector;
+ auto visitor = [&](const Aws::FileSystem::DirectoryTree*, const Aws::FileSystem::DirectoryEntry& entry)
+ {
+ if (entry.fileType == Aws::FileSystem::FileType::File)
+ {
+ filesVector.push_back(entry.path);
+ }
+ return true;
+ };
+ tree.TraverseBreadthFirst(visitor);
+ return filesVector;
+ }
+
+ DirectoryTree::DirectoryTree(const Aws::String& path)
+ {
+ m_dir = OpenDirectory(path);
+ }
+
+ DirectoryTree::operator bool() const
+ {
+ return m_dir->operator bool();
+ }
+
+ bool DirectoryTree::operator==(DirectoryTree& other)
+ {
+ return Diff(other).size() == 0;
+ }
+
+ bool DirectoryTree::operator==(const Aws::String& path)
+ {
+ return *this == DirectoryTree(path);
+ }
+
+ Aws::Map<Aws::String, DirectoryEntry> DirectoryTree::Diff(DirectoryTree& other)
+ {
+ Aws::Map<Aws::String, DirectoryEntry> thisEntries;
+ auto thisTraversal = [&thisEntries](const DirectoryTree*, const DirectoryEntry& entry)
+ {
+ thisEntries[entry.relativePath] = entry;
+ return true;
+ };
+
+ Aws::Map<Aws::String, DirectoryEntry> otherEntries;
+ auto otherTraversal = [&thisEntries, &otherEntries](const DirectoryTree*, const DirectoryEntry& entry)
+ {
+ auto thisEntry = thisEntries.find(entry.relativePath);
+ if (thisEntry != thisEntries.end())
+ {
+ thisEntries.erase(entry.relativePath);
+ }
+ else
+ {
+ otherEntries[entry.relativePath] = entry;
+ }
+
+ return true;
+ };
+
+ TraverseDepthFirst(thisTraversal);
+ other.TraverseDepthFirst(otherTraversal);
+
+ thisEntries.insert(otherEntries.begin(), otherEntries.end());
+ return thisEntries;
+ }
+
+ void DirectoryTree::TraverseDepthFirst(const DirectoryEntryVisitor& visitor, bool postOrderTraversal)
+ {
+ TraverseDepthFirst(*m_dir, visitor, postOrderTraversal);
+ m_dir = OpenDirectory(m_dir->GetPath());
+ }
+
+ void DirectoryTree::TraverseBreadthFirst(const DirectoryEntryVisitor& visitor)
+ {
+ TraverseBreadthFirst(*m_dir, visitor);
+ m_dir = OpenDirectory(m_dir->GetPath());
+ }
+
+ void DirectoryTree::TraverseBreadthFirst(Directory& dir, const DirectoryEntryVisitor& visitor)
+ {
+ if (!dir)
+ {
+ return;
+ }
+
+ Aws::Queue<DirectoryEntry> queue;
+ while (DirectoryEntry&& entry = dir.Next())
+ {
+ queue.push(std::move(entry));
+ }
+
+ while (queue.size() > 0)
+ {
+ auto entry = queue.front();
+ queue.pop();
+ if(visitor(this, entry))
+ {
+ if(entry.fileType == FileType::Directory)
+ {
+ auto currentDir = dir.Descend(entry);
+
+ while (DirectoryEntry&& dirEntry = currentDir->Next())
+ {
+ queue.push(std::move(dirEntry));
+ }
+ }
+ }
+ else
+ {
+ return;
+ }
+ }
+ }
+
+ bool DirectoryTree::TraverseDepthFirst(Directory& dir, const DirectoryEntryVisitor& visitor, bool postOrder)
+ {
+ if (!dir)
+ {
+ return true;
+ }
+
+ bool exitTraversal(false);
+ DirectoryEntry entry;
+
+ while ((entry = dir.Next()) && !exitTraversal)
+ {
+ if(!postOrder)
+ {
+ if(!visitor(this, entry))
+ {
+ return false;
+ }
+ }
+
+ if (entry.fileType == FileType::Directory)
+ {
+ auto subDir = dir.Descend(entry);
+ exitTraversal = !TraverseDepthFirst(*subDir, visitor, postOrder);
+ }
+
+ if (postOrder)
+ {
+ if (!visitor(this, entry))
+ {
+ return false;
+ }
+ }
+ }
+
+ return !exitTraversal;
+ }
+
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp
new file mode 100644
index 0000000000..eaeba1d910
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/EnumParseOverflowContainer.cpp
@@ -0,0 +1,33 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/EnumParseOverflowContainer.h>
+#include <aws/core/utils/logging/LogMacros.h>
+
+using namespace Aws::Utils;
+using namespace Aws::Utils::Threading;
+
+static const char LOG_TAG[] = "EnumParseOverflowContainer";
+
+const Aws::String& EnumParseOverflowContainer::RetrieveOverflow(int hashCode) const
+{
+ ReaderLockGuard guard(m_overflowLock);
+ auto foundIter = m_overflowMap.find(hashCode);
+ if (foundIter != m_overflowMap.end())
+ {
+ AWS_LOGSTREAM_DEBUG(LOG_TAG, "Found value " << foundIter->second << " for hash " << hashCode << " from enum overflow container.");
+ return foundIter->second;
+ }
+
+ AWS_LOGSTREAM_ERROR(LOG_TAG, "Could not find a previously stored overflow value for hash " << hashCode << ". This will likely break some requests.");
+ return m_emptyString;
+}
+
+void EnumParseOverflowContainer::StoreOverflow(int hashCode, const Aws::String& value)
+{
+ WriterLockGuard guard(m_overflowLock);
+ AWS_LOGSTREAM_WARN(LOG_TAG, "Encountered enum member " << value << " which is not modeled in your clients. You should update your clients when you get a chance.");
+ m_overflowMap[hashCode] = value;
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp
new file mode 100644
index 0000000000..c47f750960
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/FileSystemUtils.cpp
@@ -0,0 +1,51 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/FileSystemUtils.h>
+
+using namespace Aws::Utils;
+
+Aws::String PathUtils::GetFileNameFromPathWithoutExt(const Aws::String& path)
+{
+ Aws::String fileName = Aws::Utils::PathUtils::GetFileNameFromPathWithExt(path);
+ size_t endPos = fileName.find_last_of('.');
+ if (endPos == std::string::npos)
+ {
+ return fileName;
+ }
+ if (endPos == 0) // fileName is "."
+ {
+ return {};
+ }
+
+ return fileName.substr(0, endPos);
+}
+
+Aws::String PathUtils::GetFileNameFromPathWithExt(const Aws::String& path)
+{
+ if (path.size() == 0)
+ {
+ return path;
+ }
+
+ size_t startPos = path.find_last_of(Aws::FileSystem::PATH_DELIM);
+ if (startPos == path.size() - 1)
+ {
+ return {};
+ }
+
+ if (startPos == std::string::npos)
+ {
+ startPos = 0;
+ }
+ else
+ {
+ startPos += 1;
+ }
+
+ size_t endPos = path.size() - 1;
+
+ return path.substr(startPos, endPos - startPos + 1);
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp
new file mode 100644
index 0000000000..6e78b546ab
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/GetTheLights.cpp
@@ -0,0 +1,36 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+#include <aws/core/utils/GetTheLights.h>
+#include <cassert>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ GetTheLights::GetTheLights() : m_value(0)
+ {
+ }
+
+ void GetTheLights::EnterRoom(std::function<void()> &&callable)
+ {
+ int cpy = ++m_value;
+ assert(cpy > 0);
+ if(cpy == 1)
+ {
+ callable();
+ }
+ }
+
+ void GetTheLights::LeaveRoom(std::function<void()> &&callable)
+ {
+ int cpy = --m_value;
+ assert(cpy >= 0);
+ if(cpy == 0)
+ {
+ callable();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp
new file mode 100644
index 0000000000..147bddf33e
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/HashingUtils.cpp
@@ -0,0 +1,236 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/logging/LogMacros.h>
+#include <aws/core/utils/HashingUtils.h>
+#include <aws/core/utils/StringUtils.h>
+#include <aws/core/utils/base64/Base64.h>
+#include <aws/core/utils/crypto/Sha256.h>
+#include <aws/core/utils/crypto/Sha256HMAC.h>
+#include <aws/core/utils/crypto/MD5.h>
+#include <aws/core/utils/Outcome.h>
+#include <aws/core/utils/memory/stl/AWSStringStream.h>
+#include <aws/core/utils/memory/stl/AWSList.h>
+
+#include <iomanip>
+
+using namespace Aws::Utils;
+using namespace Aws::Utils::Base64;
+using namespace Aws::Utils::Crypto;
+
+// internal buffers are fixed-size arrays, so this is harmless memory-management wise
+static Aws::Utils::Base64::Base64 s_base64;
+
+// Aws Glacier Tree Hash calculates hash value for each 1MB data
+const static size_t TREE_HASH_ONE_MB = 1024 * 1024;
+
+Aws::String HashingUtils::Base64Encode(const ByteBuffer& message)
+{
+ return s_base64.Encode(message);
+}
+
+ByteBuffer HashingUtils::Base64Decode(const Aws::String& encodedMessage)
+{
+ return s_base64.Decode(encodedMessage);
+}
+
+ByteBuffer HashingUtils::CalculateSHA256HMAC(const ByteBuffer& toSign, const ByteBuffer& secret)
+{
+ Sha256HMAC hash;
+ return hash.Calculate(toSign, secret).GetResult();
+}
+
+ByteBuffer HashingUtils::CalculateSHA256(const Aws::String& str)
+{
+ Sha256 hash;
+ return hash.Calculate(str).GetResult();
+}
+
+ByteBuffer HashingUtils::CalculateSHA256(Aws::IOStream& stream)
+{
+ Sha256 hash;
+ return hash.Calculate(stream).GetResult();
+}
+
+/**
+ * This function is only used by HashingUtils::CalculateSHA256TreeHash() in this cpp file
+ * It's a helper function be used to compute the TreeHash defined at:
+ * http://docs.aws.amazon.com/amazonglacier/latest/dev/checksum-calculations.html
+ */
+static ByteBuffer TreeHashFinalCompute(Aws::List<ByteBuffer>& input)
+{
+ Sha256 hash;
+ assert(input.size() != 0);
+
+ // O(n) time complexity of merging (n + n/2 + n/4 + n/8 +...+ 1)
+ while (input.size() > 1)
+ {
+ auto iter = input.begin();
+ // if only one element left, just left it there
+ while (std::next(iter) != input.end())
+ {
+ // if >= two elements
+ Aws::String str(reinterpret_cast<char*>(iter->GetUnderlyingData()), iter->GetLength());
+ // list erase returns iterator of next element next to the erased element or end() if erased the last one
+ // list insert inserts element before pos, here we erase two elements, and insert a new element
+ iter = input.erase(iter);
+ str.append(reinterpret_cast<char*>(iter->GetUnderlyingData()), iter->GetLength());
+ iter = input.erase(iter);
+ input.insert(iter, hash.Calculate(str).GetResult());
+
+ if (iter == input.end()) break;
+ } // while process to the last element
+ } // while the list has only one element left
+
+ return *(input.begin());
+}
+
+ByteBuffer HashingUtils::CalculateSHA256TreeHash(const Aws::String& str)
+{
+ Sha256 hash;
+ if (str.size() == 0)
+ {
+ return hash.Calculate(str).GetResult();
+ }
+
+ Aws::List<ByteBuffer> input;
+ size_t pos = 0;
+ while (pos < str.size())
+ {
+ input.push_back(hash.Calculate(Aws::String(str, pos, TREE_HASH_ONE_MB)).GetResult());
+ pos += TREE_HASH_ONE_MB;
+ }
+
+ return TreeHashFinalCompute(input);
+}
+
+ByteBuffer HashingUtils::CalculateSHA256TreeHash(Aws::IOStream& stream)
+{
+ Sha256 hash;
+ Aws::List<ByteBuffer> input;
+ auto currentPos = stream.tellg();
+ if (currentPos == std::ios::pos_type(-1))
+ {
+ currentPos = 0;
+ stream.clear();
+ }
+ stream.seekg(0, stream.beg);
+ Array<char> streamBuffer(TREE_HASH_ONE_MB);
+ while (stream.good())
+ {
+ stream.read(streamBuffer.GetUnderlyingData(), TREE_HASH_ONE_MB);
+ auto bytesRead = stream.gcount();
+ if (bytesRead > 0)
+ {
+ input.push_back(hash.Calculate(Aws::String(reinterpret_cast<char*>(streamBuffer.GetUnderlyingData()), static_cast<size_t>(bytesRead))).GetResult());
+ }
+ }
+ stream.clear();
+ stream.seekg(currentPos, stream.beg);
+
+ if (input.size() == 0)
+ {
+ return hash.Calculate("").GetResult();
+ }
+ return TreeHashFinalCompute(input);
+}
+
+Aws::String HashingUtils::HexEncode(const ByteBuffer& message)
+{
+ Aws::String encoded;
+ encoded.reserve(2 * message.GetLength());
+
+ for (unsigned i = 0; i < message.GetLength(); ++i)
+ {
+ encoded.push_back("0123456789abcdef"[message[i] >> 4]);
+ encoded.push_back("0123456789abcdef"[message[i] & 0x0f]);
+ }
+
+ return encoded;
+}
+
+ByteBuffer HashingUtils::HexDecode(const Aws::String& str)
+{
+ //number of characters should be even
+ assert(str.length() % 2 == 0);
+ assert(str.length() >= 2);
+
+ if(str.length() < 2 || str.length() % 2 != 0)
+ {
+ return ByteBuffer();
+ }
+
+ size_t strLength = str.length();
+ size_t readIndex = 0;
+
+ if(str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
+ {
+ strLength -= 2;
+ readIndex = 2;
+ }
+
+ ByteBuffer hexBuffer(strLength / 2);
+ size_t bufferIndex = 0;
+
+ for (size_t i = readIndex; i < str.length(); i += 2)
+ {
+ if(!StringUtils::IsAlnum(str[i]) || !StringUtils::IsAlnum(str[i + 1]))
+ {
+ //contains non-hex characters
+ assert(0);
+ }
+
+ char firstChar = str[i];
+ uint8_t distance = firstChar - '0';
+
+ if(isalpha(firstChar))
+ {
+ firstChar = static_cast<char>(toupper(firstChar));
+ distance = firstChar - 'A' + 10;
+ }
+
+ unsigned char val = distance * 16;
+
+ char secondChar = str[i + 1];
+ distance = secondChar - '0';
+
+ if(isalpha(secondChar))
+ {
+ secondChar = static_cast<char>(toupper(secondChar));
+ distance = secondChar - 'A' + 10;
+ }
+
+ val += distance;
+ hexBuffer[bufferIndex++] = val;
+ }
+
+ return hexBuffer;
+}
+
+ByteBuffer HashingUtils::CalculateMD5(const Aws::String& str)
+{
+ MD5 hash;
+ return hash.Calculate(str).GetResult();
+}
+
+ByteBuffer HashingUtils::CalculateMD5(Aws::IOStream& stream)
+{
+ MD5 hash;
+ return hash.Calculate(stream).GetResult();
+}
+
+int HashingUtils::HashString(const char* strToHash)
+{
+ if (!strToHash)
+ return 0;
+
+ unsigned hash = 0;
+ while (char charValue = *strToHash++)
+ {
+ hash = charValue + 31 * hash;
+ }
+
+ return hash;
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/StringUtils.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/StringUtils.cpp
new file mode 100644
index 0000000000..e1deb3f046
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/StringUtils.cpp
@@ -0,0 +1,421 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+
+#include <aws/core/utils/StringUtils.h>
+#include <aws/core/utils/memory/stl/AWSStringStream.h>
+#include <algorithm>
+#include <iomanip>
+#include <cstdlib>
+#include <cstdio>
+#include <cstring>
+#include <functional>
+
+#ifdef _WIN32
+#include <Windows.h>
+#endif
+
+using namespace Aws::Utils;
+
+void StringUtils::Replace(Aws::String& s, const char* search, const char* replace)
+{
+ if(!search || !replace)
+ {
+ return;
+ }
+
+ size_t replaceLength = strlen(replace);
+ size_t searchLength = strlen(search);
+
+ for (std::size_t pos = 0;; pos += replaceLength)
+ {
+ pos = s.find(search, pos);
+ if (pos == Aws::String::npos)
+ break;
+
+ s.erase(pos, searchLength);
+ s.insert(pos, replace);
+ }
+}
+
+
+Aws::String StringUtils::ToLower(const char* source)
+{
+ Aws::String copy;
+ size_t sourceLength = strlen(source);
+ copy.resize(sourceLength);
+ //appease the latest whims of the VC++ 2017 gods
+ std::transform(source, source + sourceLength, copy.begin(), [](unsigned char c) { return (char)::tolower(c); });
+
+ return copy;
+}
+
+
+Aws::String StringUtils::ToUpper(const char* source)
+{
+ Aws::String copy;
+ size_t sourceLength = strlen(source);
+ copy.resize(sourceLength);
+ //appease the latest whims of the VC++ 2017 gods
+ std::transform(source, source + sourceLength, copy.begin(), [](unsigned char c) { return (char)::toupper(c); });
+
+ return copy;
+}
+
+
+bool StringUtils::CaselessCompare(const char* value1, const char* value2)
+{
+ Aws::String value1Lower = ToLower(value1);
+ Aws::String value2Lower = ToLower(value2);
+
+ return value1Lower == value2Lower;
+}
+
+Aws::Vector<Aws::String> StringUtils::Split(const Aws::String& toSplit, char splitOn)
+{
+ return Split(toSplit, splitOn, SIZE_MAX, SplitOptions::NOT_SET);
+}
+
+Aws::Vector<Aws::String> StringUtils::Split(const Aws::String& toSplit, char splitOn, SplitOptions option)
+{
+ return Split(toSplit, splitOn, SIZE_MAX, option);
+}
+
+Aws::Vector<Aws::String> StringUtils::Split(const Aws::String& toSplit, char splitOn, size_t numOfTargetParts)
+{
+ return Split(toSplit, splitOn, numOfTargetParts, SplitOptions::NOT_SET);
+}
+
+Aws::Vector<Aws::String> StringUtils::Split(const Aws::String& toSplit, char splitOn, size_t numOfTargetParts, SplitOptions option)
+{
+ Aws::Vector<Aws::String> returnValues;
+ Aws::StringStream input(toSplit);
+ Aws::String item;
+
+ while(returnValues.size() < numOfTargetParts - 1 && std::getline(input, item, splitOn))
+ {
+ if (!item.empty() || option == SplitOptions::INCLUDE_EMPTY_ENTRIES)
+ {
+ returnValues.emplace_back(std::move(item));
+ }
+ }
+
+ if (std::getline(input, item, static_cast<char>(EOF)))
+ {
+ if (option != SplitOptions::INCLUDE_EMPTY_ENTRIES)
+ {
+ // Trim all leading delimiters.
+ item.erase(item.begin(), std::find_if(item.begin(), item.end(), [splitOn](int ch) { return ch != splitOn; }));
+ if (!item.empty())
+ {
+ returnValues.emplace_back(std::move(item));
+ }
+ }
+ else
+ {
+ returnValues.emplace_back(std::move(item));
+ }
+
+ }
+ // To handle the case when there are trailing delimiters.
+ else if (!toSplit.empty() && toSplit.back() == splitOn && option == SplitOptions::INCLUDE_EMPTY_ENTRIES)
+ {
+ returnValues.emplace_back();
+ }
+
+ return returnValues;
+}
+
+Aws::Vector<Aws::String> StringUtils::SplitOnLine(const Aws::String& toSplit)
+{
+ Aws::StringStream input(toSplit);
+ Aws::Vector<Aws::String> returnValues;
+ Aws::String item;
+
+ while (std::getline(input, item))
+ {
+ if (item.size() > 0)
+ {
+ returnValues.push_back(item);
+ }
+ }
+
+ return returnValues;
+}
+
+
+Aws::String StringUtils::URLEncode(const char* unsafe)
+{
+ Aws::StringStream escaped;
+ escaped.fill('0');
+ escaped << std::hex << std::uppercase;
+
+ size_t unsafeLength = strlen(unsafe);
+ for (auto i = unsafe, n = unsafe + unsafeLength; i != n; ++i)
+ {
+ char c = *i;
+ if (IsAlnum(c) || c == '-' || c == '_' || c == '.' || c == '~')
+ {
+ escaped << (char)c;
+ }
+ else
+ {
+ //this unsigned char cast allows us to handle unicode characters.
+ escaped << '%' << std::setw(2) << int((unsigned char)c) << std::setw(0);
+ }
+ }
+
+ return escaped.str();
+}
+
+Aws::String StringUtils::UTF8Escape(const char* unicodeString, const char* delimiter)
+{
+ Aws::StringStream escaped;
+ escaped.fill('0');
+ escaped << std::hex << std::uppercase;
+
+ size_t unsafeLength = strlen(unicodeString);
+ for (auto i = unicodeString, n = unicodeString + unsafeLength; i != n; ++i)
+ {
+ int c = *i;
+ if (c >= ' ' && c < 127 )
+ {
+ escaped << (char)c;
+ }
+ else
+ {
+ //this unsigned char cast allows us to handle unicode characters.
+ escaped << delimiter << std::setw(2) << int((unsigned char)c) << std::setw(0);
+ }
+ }
+
+ return escaped.str();
+}
+
+Aws::String StringUtils::URLEncode(double unsafe)
+{
+ char buffer[32];
+#if defined(_MSC_VER) && _MSC_VER < 1900
+ _snprintf_s(buffer, sizeof(buffer), _TRUNCATE, "%g", unsafe);
+#else
+ snprintf(buffer, sizeof(buffer), "%g", unsafe);
+#endif
+
+ return StringUtils::URLEncode(buffer);
+}
+
+
+Aws::String StringUtils::URLDecode(const char* safe)
+{
+ Aws::String unescaped;
+
+ for (; *safe; safe++)
+ {
+ switch(*safe)
+ {
+ case '%':
+ {
+ int hex = 0;
+ auto ch = *++safe;
+ if (ch >= '0' && ch <= '9')
+ {
+ hex = (ch - '0') * 16;
+ }
+ else if (ch >= 'A' && ch <= 'F')
+ {
+ hex = (ch - 'A' + 10) * 16;
+ }
+ else if (ch >= 'a' && ch <= 'f')
+ {
+ hex = (ch - 'a' + 10) * 16;
+ }
+ else
+ {
+ unescaped.push_back('%');
+ if (ch == 0)
+ {
+ return unescaped;
+ }
+ unescaped.push_back(ch);
+ break;
+ }
+
+ ch = *++safe;
+ if (ch >= '0' && ch <= '9')
+ {
+ hex += (ch - '0');
+ }
+ else if (ch >= 'A' && ch <= 'F')
+ {
+ hex += (ch - 'A' + 10);
+ }
+ else if (ch >= 'a' && ch <= 'f')
+ {
+ hex += (ch - 'a' + 10);
+ }
+ else
+ {
+ unescaped.push_back('%');
+ unescaped.push_back(*(safe - 1));
+ if (ch == 0)
+ {
+ return unescaped;
+ }
+ unescaped.push_back(ch);
+ break;
+ }
+
+ unescaped.push_back(char(hex));
+ break;
+ }
+ case '+':
+ unescaped.push_back(' ');
+ break;
+ default:
+ unescaped.push_back(*safe);
+ break;
+ }
+ }
+
+ return unescaped;
+}
+
+static bool IsSpace(int ch)
+{
+ if (ch < -1 || ch > 255)
+ {
+ return false;
+ }
+
+ return ::isspace(ch) != 0;
+}
+
+Aws::String StringUtils::LTrim(const char* source)
+{
+ Aws::String copy(source);
+ copy.erase(copy.begin(), std::find_if(copy.begin(), copy.end(), [](int ch) { return !IsSpace(ch); }));
+ return copy;
+}
+
+// trim from end
+Aws::String StringUtils::RTrim(const char* source)
+{
+ Aws::String copy(source);
+ copy.erase(std::find_if(copy.rbegin(), copy.rend(), [](int ch) { return !IsSpace(ch); }).base(), copy.end());
+ return copy;
+}
+
+// trim from both ends
+Aws::String StringUtils::Trim(const char* source)
+{
+ return LTrim(RTrim(source).c_str());
+}
+
+long long StringUtils::ConvertToInt64(const char* source)
+{
+ if(!source)
+ {
+ return 0;
+ }
+
+#ifdef __ANDROID__
+ return atoll(source);
+#else
+ return std::atoll(source);
+#endif // __ANDROID__
+}
+
+
+long StringUtils::ConvertToInt32(const char* source)
+{
+ if (!source)
+ {
+ return 0;
+ }
+
+ return std::atol(source);
+}
+
+
+bool StringUtils::ConvertToBool(const char* source)
+{
+ if(!source)
+ {
+ return false;
+ }
+
+ Aws::String strValue = ToLower(source);
+ if(strValue == "true" || strValue == "1")
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+double StringUtils::ConvertToDouble(const char* source)
+{
+ if(!source)
+ {
+ return 0.0;
+ }
+
+ return std::strtod(source, NULL);
+}
+
+#ifdef _WIN32
+
+Aws::WString StringUtils::ToWString(const char* source)
+{
+ const auto len = static_cast<int>(std::strlen(source));
+ Aws::WString outString;
+ outString.resize(len); // there is no way UTF-16 would require _more_ code-points than UTF-8 for the _same_ string
+ const auto result = MultiByteToWideChar(CP_UTF8 /*CodePage*/,
+ 0 /*dwFlags*/,
+ source /*lpMultiByteStr*/,
+ len /*cbMultiByte*/,
+ &outString[0] /*lpWideCharStr*/,
+ static_cast<int>(outString.length())/*cchWideChar*/);
+ if (!result)
+ {
+ return L"";
+ }
+ outString.resize(result);
+ return outString;
+}
+
+Aws::String StringUtils::FromWString(const wchar_t* source)
+{
+ const auto len = static_cast<int>(std::wcslen(source));
+ Aws::String output;
+ if (int requiredSizeInBytes = WideCharToMultiByte(CP_UTF8 /*CodePage*/,
+ 0 /*dwFlags*/,
+ source /*lpWideCharStr*/,
+ len /*cchWideChar*/,
+ nullptr /*lpMultiByteStr*/,
+ 0 /*cbMultiByte*/,
+ nullptr /*lpDefaultChar*/,
+ nullptr /*lpUsedDefaultChar*/))
+ {
+ output.resize(requiredSizeInBytes);
+ }
+ const auto result = WideCharToMultiByte(CP_UTF8 /*CodePage*/,
+ 0 /*dwFlags*/,
+ source /*lpWideCharStr*/,
+ len /*cchWideChar*/,
+ &output[0] /*lpMultiByteStr*/,
+ static_cast<int>(output.length()) /*cbMultiByte*/,
+ nullptr /*lpDefaultChar*/,
+ nullptr /*lpUsedDefaultChar*/);
+ if (!result)
+ {
+ return "";
+ }
+ output.resize(result);
+ return output;
+}
+
+#endif
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp
new file mode 100644
index 0000000000..7bc07266c9
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/TempFile.cpp
@@ -0,0 +1,54 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/FileSystemUtils.h>
+
+#include <aws/core/platform/FileSystem.h>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ static Aws::String ComputeTempFileName(const char* prefix, const char* suffix)
+ {
+ Aws::String prefixStr;
+
+ if (prefix)
+ {
+ prefixStr = prefix;
+ }
+
+ Aws::String suffixStr;
+
+ if (suffix)
+ {
+ suffixStr = suffix;
+ }
+
+ return prefixStr + Aws::FileSystem::CreateTempFilePath() + suffixStr;
+ }
+
+ TempFile::TempFile(const char* prefix, const char* suffix, std::ios_base::openmode openFlags) :
+ FStreamWithFileName(ComputeTempFileName(prefix, suffix).c_str(), openFlags)
+ {
+ }
+
+ TempFile::TempFile(const char* prefix, std::ios_base::openmode openFlags) :
+ FStreamWithFileName(ComputeTempFileName(prefix, nullptr).c_str(), openFlags)
+ {
+ }
+
+ TempFile::TempFile(std::ios_base::openmode openFlags) :
+ FStreamWithFileName(ComputeTempFileName(nullptr, nullptr).c_str(), openFlags)
+ {
+ }
+
+
+ TempFile::~TempFile()
+ {
+ Aws::FileSystem::RemoveFileIfExists(m_fileName.c_str());
+ }
+ }
+} \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp
new file mode 100644
index 0000000000..862f3eacdd
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/UUID.cpp
@@ -0,0 +1,90 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/UUID.h>
+#include <aws/core/utils/HashingUtils.h>
+#include <aws/core/utils/StringUtils.h>
+#include <aws/core/utils/crypto/Factories.h>
+#include <aws/core/utils/crypto/SecureRandom.h>
+#include <iomanip>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ static const size_t UUID_STR_SIZE = 0x24u; // 36 characters
+ static const size_t VERSION_LOCATION = 0x06u;
+ static const size_t VARIANT_LOCATION = 0x08u;
+ static const unsigned char VERSION = 0x40u;
+ static const unsigned char VERSION_MASK = 0x0Fu;
+ static const unsigned char VARIANT = 0x80u;
+ static const unsigned char VARIANT_MASK = 0x3Fu;
+
+ static void hexify(Aws::String& ss, const unsigned char* toWrite, size_t min, size_t max)
+ {
+ for (size_t i = min; i < max; ++i)
+ {
+ ss.push_back("0123456789ABCDEF"[toWrite[i] >> 4]);
+ ss.push_back("0123456789ABCDEF"[toWrite[i] & 0x0F]);
+ }
+ }
+
+ UUID::UUID(const Aws::String& uuidToConvert)
+ {
+ //GUID has 2 characters per byte + 4 dashes = 36 bytes
+ assert(uuidToConvert.length() == UUID_STR_SIZE);
+ memset(m_uuid, 0, sizeof(m_uuid));
+ Aws::String escapedHexStr(uuidToConvert);
+ StringUtils::Replace(escapedHexStr, "-", "");
+ assert(escapedHexStr.length() == UUID_BINARY_SIZE * 2);
+ ByteBuffer&& rawUuid = HashingUtils::HexDecode(escapedHexStr);
+ memcpy(m_uuid, rawUuid.GetUnderlyingData(), rawUuid.GetLength());
+ }
+
+ UUID::UUID(const unsigned char toCopy[UUID_BINARY_SIZE])
+ {
+ memcpy(m_uuid, toCopy, sizeof(m_uuid));
+ }
+
+ UUID::operator Aws::String() const
+ {
+ Aws::String ss;
+ ss.reserve(UUID_STR_SIZE);
+ hexify(ss, m_uuid, 0, 4);
+ ss.push_back('-');
+
+ hexify(ss, m_uuid, 4, 6);
+ ss.push_back('-');
+
+ hexify(ss, m_uuid, 6, 8);
+ ss.push_back('-');
+
+ hexify(ss, m_uuid, 8, 10);
+ ss.push_back('-');
+
+ hexify(ss, m_uuid, 10, 16);
+
+ return ss;
+ }
+
+ UUID UUID::RandomUUID()
+ {
+ auto secureRandom = Crypto::CreateSecureRandomBytesImplementation();
+ assert(secureRandom);
+
+ unsigned char randomBytes[UUID_BINARY_SIZE];
+ memset(randomBytes, 0, UUID_BINARY_SIZE);
+ secureRandom->GetBytes(randomBytes, UUID_BINARY_SIZE);
+ //Set version bits to 0100
+ //https://tools.ietf.org/html/rfc4122#section-4.1.3
+ randomBytes[VERSION_LOCATION] = (randomBytes[VERSION_LOCATION] & VERSION_MASK) | VERSION;
+ //set variant bits to 10
+ //https://tools.ietf.org/html/rfc4122#section-4.1.1
+ randomBytes[VARIANT_LOCATION] = (randomBytes[VARIANT_LOCATION] & VARIANT_MASK) | VARIANT;
+
+ return UUID(randomBytes);
+ }
+ }
+}
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
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp
new file mode 100644
index 0000000000..1c844273f4
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Cipher.cpp
@@ -0,0 +1,123 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/crypto/Cipher.h>
+#include <aws/core/utils/crypto/Factories.h>
+#include <aws/core/utils/crypto/SecureRandom.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <cstdlib>
+#include <climits>
+
+//if you are reading this, you are witnessing pure brilliance.
+#define IS_BIG_ENDIAN (*(uint16_t*)"\0\xff" < 0x100)
+
+using namespace Aws::Utils::Crypto;
+using namespace Aws::Utils;
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Crypto
+ {
+ static const char* LOG_TAG = "Cipher";
+
+ //swap byte ordering
+ template<class T>
+ typename std::enable_if<std::is_unsigned<T>::value, T>::type
+ bswap(T i, T j = 0u, std::size_t n = 0u)
+ {
+ return n == sizeof(T) ? j :
+ bswap<T>(i >> CHAR_BIT, (j << CHAR_BIT) | (i & (T)(unsigned char)(-1)), n + 1);
+ }
+
+ CryptoBuffer IncrementCTRCounter(const CryptoBuffer& counter, uint32_t numberOfBlocks)
+ {
+ // minium counter size is 12 bytes. This isn't a variable because some compilers
+ // are stupid and thing that variable is unused.
+ assert(counter.GetLength() >= 12);
+
+ CryptoBuffer incrementedCounter(counter);
+
+ //get the last 4 bytes and manipulate them as an integer.
+ uint32_t* ctrPtr = (uint32_t*)(incrementedCounter.GetUnderlyingData() + incrementedCounter.GetLength() - sizeof(int32_t));
+ if(IS_BIG_ENDIAN)
+ {
+ //you likely are not Big Endian, but
+ //if it's big endian, just go ahead and increment it... done
+ *ctrPtr += numberOfBlocks;
+ }
+ else
+ {
+ //otherwise, swap the byte ordering of the integer we loaded from the buffer (because it is backwards). However, the number of blocks is already properly
+ //aligned. Once we compute the new value, swap it back so that the mirroring operation goes back to the actual buffer.
+ *ctrPtr = bswap<uint32_t>(bswap<uint32_t>(*ctrPtr) + numberOfBlocks);
+ }
+
+ return incrementedCounter;
+ }
+
+ CryptoBuffer GenerateXRandomBytes(size_t lengthBytes, bool ctrMode)
+ {
+ std::shared_ptr<SecureRandomBytes> rng = CreateSecureRandomBytesImplementation();
+
+ CryptoBuffer bytes(lengthBytes);
+ size_t lengthToGenerate = ctrMode ? (3 * bytes.GetLength()) / 4 : bytes.GetLength();
+
+ rng->GetBytes(bytes.GetUnderlyingData(), lengthToGenerate);
+
+ if(!*rng)
+ {
+ AWS_LOGSTREAM_FATAL(LOG_TAG, "Random Number generation failed. Abort all crypto operations.");
+ assert(false);
+ abort();
+ }
+
+ return bytes;
+ }
+
+ /**
+ * Generate random number per 4 bytes and use each byte for the byte in the iv
+ */
+ CryptoBuffer SymmetricCipher::GenerateIV(size_t ivLengthBytes, bool ctrMode)
+ {
+ CryptoBuffer iv(GenerateXRandomBytes(ivLengthBytes, ctrMode));
+
+ if(iv.GetLength() == 0)
+ {
+ AWS_LOGSTREAM_ERROR(LOG_TAG, "Unable to generate iv of length " << ivLengthBytes);
+ return iv;
+ }
+
+ if(ctrMode)
+ {
+ //init the counter
+ size_t length = iv.GetLength();
+ //[ nonce 1/4] [ iv 1/2 ] [ ctr 1/4 ]
+ size_t ctrStart = (length / 2) + (length / 4);
+ for(; ctrStart < iv.GetLength() - 1; ++ ctrStart)
+ {
+ iv[ctrStart] = 0;
+ }
+ iv[length - 1] = 1;
+ }
+
+ return iv;
+ }
+
+ CryptoBuffer SymmetricCipher::GenerateKey(size_t keyLengthBytes)
+ {
+ CryptoBuffer const& key = GenerateXRandomBytes(keyLengthBytes, false);
+
+ if(key.GetLength() == 0)
+ {
+ AWS_LOGSTREAM_ERROR(LOG_TAG, "Unable to generate key of length " << keyLengthBytes);
+ }
+
+ return key;
+ }
+ }
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp
new file mode 100644
index 0000000000..3036bd70eb
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoMaterial.cpp
@@ -0,0 +1,34 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+#include <aws/core/utils/crypto/ContentCryptoMaterial.h>
+#include <aws/core/utils/crypto/Cipher.h>
+
+using namespace Aws::Utils::Crypto;
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Crypto
+ {
+ ContentCryptoMaterial::ContentCryptoMaterial() :
+ m_cryptoTagLength(0), m_keyWrapAlgorithm(KeyWrapAlgorithm::NONE), m_contentCryptoScheme(ContentCryptoScheme::NONE)
+ {
+ }
+
+ ContentCryptoMaterial::ContentCryptoMaterial(ContentCryptoScheme contentCryptoScheme) :
+ m_contentEncryptionKey(SymmetricCipher::GenerateKey()), m_cryptoTagLength(0), m_keyWrapAlgorithm(KeyWrapAlgorithm::NONE), m_contentCryptoScheme(contentCryptoScheme)
+ {
+
+ }
+
+ ContentCryptoMaterial::ContentCryptoMaterial(const Aws::Utils::CryptoBuffer & cek, ContentCryptoScheme contentCryptoScheme) :
+ m_contentEncryptionKey(cek), m_cryptoTagLength(0), m_keyWrapAlgorithm(KeyWrapAlgorithm::NONE), m_contentCryptoScheme(contentCryptoScheme)
+ {
+
+ }
+ }
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp
new file mode 100644
index 0000000000..f39a75df2c
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/ContentCryptoScheme.cpp
@@ -0,0 +1,61 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+#include <aws/core/utils/crypto/ContentCryptoScheme.h>
+#include <aws/core/utils/HashingUtils.h>
+#include <aws/core/utils/EnumParseOverflowContainer.h>
+#include <aws/core/Globals.h>
+
+using namespace Aws::Utils;
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Crypto
+ {
+ namespace ContentCryptoSchemeMapper
+ {
+ static const int cryptoScheme_CBC_HASH = HashingUtils::HashString("AES/CBC/PKCS5Padding");
+ static const int cryptoScheme_CTR_HASH = HashingUtils::HashString("AES/CTR/NoPadding");
+ static const int cryptoScheme_GCM_HASH = HashingUtils::HashString("AES/GCM/NoPadding");
+
+ ContentCryptoScheme GetContentCryptoSchemeForName(const Aws::String& name)
+ {
+ int hashcode = HashingUtils::HashString(name.c_str());
+ if (hashcode == cryptoScheme_CBC_HASH)
+ {
+ return ContentCryptoScheme::CBC;
+ }
+ else if (hashcode == cryptoScheme_CTR_HASH)
+ {
+ return ContentCryptoScheme::CTR;
+ }
+ else if (hashcode == cryptoScheme_GCM_HASH)
+ {
+ return ContentCryptoScheme::GCM;
+ }
+ assert(0);
+ return ContentCryptoScheme::NONE;
+ }
+
+ Aws::String GetNameForContentCryptoScheme(ContentCryptoScheme enumValue)
+ {
+ switch (enumValue)
+ {
+ case ContentCryptoScheme::CBC:
+ return "AES/CBC/PKCS5Padding";
+ case ContentCryptoScheme::CTR:
+ return "AES/CTR/NoPadding";
+ case ContentCryptoScheme::GCM:
+ return "AES/GCM/NoPadding";
+ default:
+ assert(0);
+ return "";
+ }
+ }
+ }//namespace ContentCryptoSchemeMapper
+ } //namespace Crypto
+ }//namespace Utils
+}//namespace Aws \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoBuf.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoBuf.cpp
new file mode 100644
index 0000000000..2b47097679
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoBuf.cpp
@@ -0,0 +1,348 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/crypto/CryptoBuf.h>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Crypto
+ {
+ SymmetricCryptoBufSrc::SymmetricCryptoBufSrc(Aws::IStream& stream, SymmetricCipher& cipher, CipherMode cipherMode, size_t bufferSize)
+ :
+ m_isBuf(PUT_BACK_SIZE), m_cipher(cipher), m_stream(stream), m_cipherMode(cipherMode), m_isFinalized(false),
+ m_bufferSize(bufferSize), m_putBack(PUT_BACK_SIZE)
+ {
+ char* end = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData() + m_isBuf.GetLength());
+ setg(end, end, end);
+ }
+
+ SymmetricCryptoBufSrc::pos_type SymmetricCryptoBufSrc::seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which)
+ {
+ if(which == std::ios_base::in)
+ {
+ auto curPos = m_stream.tellg();
+ //error on seek we may have read past the end already. Try resetting and seeking to the end first
+ if (curPos == pos_type(-1))
+ {
+ m_stream.clear();
+ m_stream.seekg(0, std::ios_base::end);
+ curPos = m_stream.tellg();
+ }
+
+ auto absPosition = ComputeAbsSeekPosition(off, dir, curPos);
+ size_t seekTo = static_cast<size_t>(absPosition);
+ size_t index = static_cast<size_t>(curPos);
+
+ if(index == seekTo)
+ {
+ return curPos;
+ }
+ else if (seekTo < index)
+ {
+ m_cipher.Reset();
+ m_stream.clear();
+ m_stream.seekg(0);
+ m_isFinalized = false;
+ index = 0;
+ }
+
+ CryptoBuffer cryptoBuffer;
+ while (m_cipher && index < seekTo && !m_isFinalized)
+ {
+ size_t max_read = std::min<size_t>(static_cast<size_t>(seekTo - index), m_bufferSize);
+
+ Aws::Utils::Array<char> buf(max_read);
+ size_t readSize(0);
+ if(m_stream)
+ {
+ m_stream.read(buf.GetUnderlyingData(), max_read);
+ readSize = static_cast<size_t>(m_stream.gcount());
+ }
+
+ if (readSize > 0)
+ {
+ if (m_cipherMode == CipherMode::Encrypt)
+ {
+ cryptoBuffer = m_cipher.EncryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(buf.GetUnderlyingData()), readSize));
+ }
+ else
+ {
+ cryptoBuffer = m_cipher.DecryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(buf.GetUnderlyingData()), readSize));
+ }
+ }
+ else
+ {
+ if (m_cipherMode == CipherMode::Encrypt)
+ {
+ cryptoBuffer = m_cipher.FinalizeEncryption();
+ }
+ else
+ {
+ cryptoBuffer = m_cipher.FinalizeDecryption();
+ }
+
+ m_isFinalized = true;
+ }
+
+ index += cryptoBuffer.GetLength();
+ }
+
+ if (cryptoBuffer.GetLength() && m_cipher)
+ {
+ CryptoBuffer putBackArea(m_putBack);
+
+ m_isBuf = CryptoBuffer({&putBackArea, &cryptoBuffer});
+ //in the very unlikely case that the cipher had less output than the source stream.
+ assert(seekTo <= index);
+ size_t newBufferPos = index > seekTo ? cryptoBuffer.GetLength() - (index - seekTo) : cryptoBuffer.GetLength();
+ char* baseBufPtr = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData());
+ setg(baseBufPtr, baseBufPtr + m_putBack + newBufferPos, baseBufPtr + m_isBuf.GetLength());
+
+ return pos_type(seekTo);
+ }
+ else if (seekTo == 0)
+ {
+ m_isBuf = CryptoBuffer(m_putBack);
+ char* end = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData() + m_isBuf.GetLength());
+ setg(end, end, end);
+ return pos_type(seekTo);
+ }
+ }
+
+ return pos_type(off_type(-1));
+ }
+
+ SymmetricCryptoBufSrc::pos_type SymmetricCryptoBufSrc::seekpos(pos_type pos, std::ios_base::openmode which)
+ {
+ return seekoff(pos, std::ios_base::beg, which);
+ }
+
+ SymmetricCryptoBufSrc::int_type SymmetricCryptoBufSrc::underflow()
+ {
+ if (!m_cipher || (m_isFinalized && gptr() >= egptr()))
+ {
+ return traits_type::eof();
+ }
+
+ if (gptr() < egptr())
+ {
+ return traits_type::to_int_type(*gptr());
+ }
+
+ char* baseBufPtr = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData());
+ CryptoBuffer putBackArea(m_putBack);
+
+ //eback is properly set after the first fill. So this guarantees we are on the second or later fill.
+ if (eback() == baseBufPtr)
+ {
+ //just fill in the last bit of the previous buffer into the put back area so that it has some data in it
+ memcpy(putBackArea.GetUnderlyingData(), egptr() - m_putBack, m_putBack);
+ }
+
+ CryptoBuffer newDataBuf;
+
+ while(!newDataBuf.GetLength() && !m_isFinalized)
+ {
+ Aws::Utils::Array<char> buf(m_bufferSize);
+ m_stream.read(buf.GetUnderlyingData(), m_bufferSize);
+ size_t readSize = static_cast<size_t>(m_stream.gcount());
+
+ if (readSize > 0)
+ {
+ if (m_cipherMode == CipherMode::Encrypt)
+ {
+ newDataBuf = m_cipher.EncryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(buf.GetUnderlyingData()), readSize));
+ }
+ else
+ {
+ newDataBuf = m_cipher.DecryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(buf.GetUnderlyingData()), readSize));
+ }
+ }
+ else
+ {
+ if (m_cipherMode == CipherMode::Encrypt)
+ {
+ newDataBuf = m_cipher.FinalizeEncryption();
+ }
+ else
+ {
+ newDataBuf = m_cipher.FinalizeDecryption();
+ }
+
+ m_isFinalized = true;
+ }
+ }
+
+
+ if(newDataBuf.GetLength() > 0)
+ {
+ m_isBuf = CryptoBuffer({&putBackArea, &newDataBuf});
+
+ baseBufPtr = reinterpret_cast<char*>(m_isBuf.GetUnderlyingData());
+ setg(baseBufPtr, baseBufPtr + m_putBack, baseBufPtr + m_isBuf.GetLength());
+
+ return traits_type::to_int_type(*gptr());
+ }
+
+ return traits_type::eof();
+ }
+
+ SymmetricCryptoBufSrc::off_type SymmetricCryptoBufSrc::ComputeAbsSeekPosition(off_type pos, std::ios_base::seekdir dir, std::fpos<FPOS_TYPE> curPos)
+ {
+ switch(dir)
+ {
+ case std::ios_base::beg:
+ return pos;
+ case std::ios_base::cur:
+ return m_stream.tellg() + pos;
+ case std::ios_base::end:
+ {
+ off_type absPos = m_stream.seekg(0, std::ios_base::end).tellg() - pos;
+ m_stream.seekg(curPos);
+ return absPos;
+ }
+ default:
+ assert(0);
+ return off_type(-1);
+ }
+ }
+
+ void SymmetricCryptoBufSrc::FinalizeCipher()
+ {
+ if(m_cipher && !m_isFinalized)
+ {
+ if(m_cipherMode == CipherMode::Encrypt)
+ {
+ m_cipher.FinalizeEncryption();
+ }
+ else
+ {
+ m_cipher.FinalizeDecryption();
+ }
+ }
+ }
+
+ SymmetricCryptoBufSink::SymmetricCryptoBufSink(Aws::OStream& stream, SymmetricCipher& cipher, CipherMode cipherMode, size_t bufferSize, int16_t blockOffset)
+ :
+ m_osBuf(bufferSize), m_cipher(cipher), m_stream(stream), m_cipherMode(cipherMode), m_isFinalized(false), m_blockOffset(blockOffset)
+ {
+ assert(m_blockOffset < 16 && m_blockOffset >= 0);
+ char* outputBase = reinterpret_cast<char*>(m_osBuf.GetUnderlyingData());
+ setp(outputBase, outputBase + bufferSize - 1);
+ }
+
+ SymmetricCryptoBufSink::~SymmetricCryptoBufSink()
+ {
+ FinalizeCiphersAndFlushSink();
+ }
+
+ void SymmetricCryptoBufSink::FinalizeCiphersAndFlushSink()
+ {
+ if(m_cipher && !m_isFinalized)
+ {
+ writeOutput(true);
+ }
+ }
+
+ bool SymmetricCryptoBufSink::writeOutput(bool finalize)
+ {
+ if(!m_isFinalized)
+ {
+ CryptoBuffer cryptoBuf;
+ if (pptr() > pbase())
+ {
+ if (m_cipherMode == CipherMode::Encrypt)
+ {
+ cryptoBuf = m_cipher.EncryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(pbase()), pptr() - pbase()));
+ }
+ else
+ {
+ cryptoBuf = m_cipher.DecryptBuffer(CryptoBuffer(reinterpret_cast<unsigned char*>(pbase()), pptr() - pbase()));
+ }
+
+ pbump(-(static_cast<int>(pptr() - pbase())));
+ }
+ if(finalize)
+ {
+ CryptoBuffer finalBuffer;
+ if (m_cipherMode == CipherMode::Encrypt)
+ {
+ finalBuffer = m_cipher.FinalizeEncryption();
+ }
+ else
+ {
+ finalBuffer = m_cipher.FinalizeDecryption();
+ }
+ if(cryptoBuf.GetLength())
+ {
+ cryptoBuf = CryptoBuffer({&cryptoBuf, &finalBuffer});
+ }
+ else
+ {
+ cryptoBuf = std::move(finalBuffer);
+ }
+
+ m_isFinalized = true;
+ }
+
+ if (m_cipher)
+ {
+ if(cryptoBuf.GetLength())
+ {
+ //allow mid block decryption. We have to decrypt it, but we don't have to write it to the stream.
+ //the assumption here is that tellp() will always be 0 or >= 16 bytes. The block offset should only
+ //be the offset of the first block read.
+ size_t len = cryptoBuf.GetLength();
+ size_t blockOffset = m_stream.tellp() > m_blockOffset ? 0 : m_blockOffset;
+ if (len > blockOffset)
+ {
+ m_stream.write(reinterpret_cast<char*>(cryptoBuf.GetUnderlyingData() + blockOffset), len - blockOffset);
+ m_blockOffset = 0;
+ }
+ else
+ {
+ m_blockOffset -= static_cast<int16_t>(len);
+ }
+ }
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ SymmetricCryptoBufSink::int_type SymmetricCryptoBufSink::overflow(int_type ch)
+ {
+ if(m_cipher && m_stream)
+ {
+ if(ch != traits_type::eof())
+ {
+ *pptr() = (char)ch;
+ pbump(1);
+ }
+
+ if(writeOutput(ch == traits_type::eof()))
+ {
+ return ch;
+ }
+ }
+
+ return traits_type::eof();
+ }
+
+ int SymmetricCryptoBufSink::sync()
+ {
+ if(m_cipher && m_stream)
+ {
+ return writeOutput(false) ? 0 : -1;
+ }
+
+ return -1;
+ }
+ }
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoStream.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoStream.cpp
new file mode 100644
index 0000000000..2d645f7427
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/CryptoStream.cpp
@@ -0,0 +1,52 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+#include <aws/core/utils/crypto/CryptoStream.h>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Crypto
+ {
+ static const char* CLASS_TAG = "Aws::Utils::Crypto::SymmetricCryptoStream";
+
+ SymmetricCryptoStream::SymmetricCryptoStream(Aws::IStream& src, CipherMode mode, SymmetricCipher& cipher, size_t bufSize) :
+ Aws::IOStream(m_cryptoBuf = Aws::New<SymmetricCryptoBufSrc>(CLASS_TAG, src, cipher, mode, bufSize)), m_hasOwnership(true)
+ {
+ }
+
+ SymmetricCryptoStream::SymmetricCryptoStream(Aws::OStream& sink, CipherMode mode, SymmetricCipher& cipher, size_t bufSize, int16_t blockOffset) :
+ Aws::IOStream(m_cryptoBuf = Aws::New<SymmetricCryptoBufSink>(CLASS_TAG, sink, cipher, mode, bufSize, blockOffset)), m_hasOwnership(true)
+ {
+ }
+
+ SymmetricCryptoStream::SymmetricCryptoStream(Aws::Utils::Crypto::SymmetricCryptoBufSrc& bufSrc) :
+ Aws::IOStream(&bufSrc), m_cryptoBuf(&bufSrc), m_hasOwnership(false)
+ {
+ }
+
+ SymmetricCryptoStream::SymmetricCryptoStream(Aws::Utils::Crypto::SymmetricCryptoBufSink& bufSink) :
+ Aws::IOStream(&bufSink), m_cryptoBuf(&bufSink), m_hasOwnership(false)
+ {
+ }
+
+ SymmetricCryptoStream::~SymmetricCryptoStream()
+ {
+ Finalize();
+
+ if(m_hasOwnership && m_cryptoBuf)
+ {
+ Aws::Delete(m_cryptoBuf);
+ }
+ }
+
+ void SymmetricCryptoStream::Finalize()
+ {
+ assert(m_cryptoBuf);
+ m_cryptoBuf->Finalize();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/EncryptionMaterials.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/EncryptionMaterials.cpp
new file mode 100644
index 0000000000..d000c86baa
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/EncryptionMaterials.cpp
@@ -0,0 +1,19 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+#include <aws/core/utils/crypto/EncryptionMaterials.h>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Crypto
+ {
+ //this is here to force the linker to behave correctly since this is an interface that will need to cross the dll
+ //boundary.
+ EncryptionMaterials::~EncryptionMaterials()
+ {}
+ }
+ }
+} \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/KeyWrapAlgorithm.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/KeyWrapAlgorithm.cpp
new file mode 100644
index 0000000000..b9e098775c
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/KeyWrapAlgorithm.cpp
@@ -0,0 +1,68 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+#include <aws/core/utils/crypto/KeyWrapAlgorithm.h>
+#include <aws/core/utils/HashingUtils.h>
+#include <aws/core/utils/EnumParseOverflowContainer.h>
+#include <aws/core/Globals.h>
+
+using namespace Aws::Utils;
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Crypto
+ {
+ namespace KeyWrapAlgorithmMapper
+ {
+ static const int keyWrapAlgorithm_KMS_HASH = HashingUtils::HashString("kms");
+ static const int keyWrapAlgorithm_KMS_CONTEXT_HASH = HashingUtils::HashString("kms+context");
+ static const int keyWrapAlgorithm_KeyWrap_HASH = HashingUtils::HashString("AESWrap");
+ static const int keyWrapAlgorithm_AES_GCM_HASH = HashingUtils::HashString("AES/GCM");
+
+ KeyWrapAlgorithm GetKeyWrapAlgorithmForName(const Aws::String& name)
+ {
+ int hashcode = HashingUtils::HashString(name.c_str());
+ if (hashcode == keyWrapAlgorithm_KMS_HASH)
+ {
+ return KeyWrapAlgorithm::KMS;
+ }
+ else if (hashcode == keyWrapAlgorithm_KMS_CONTEXT_HASH)
+ {
+ return KeyWrapAlgorithm::KMS_CONTEXT;
+ }
+ else if (hashcode == keyWrapAlgorithm_KeyWrap_HASH)
+ {
+ return KeyWrapAlgorithm::AES_KEY_WRAP;
+ }
+ else if (hashcode == keyWrapAlgorithm_AES_GCM_HASH)
+ {
+ return KeyWrapAlgorithm::AES_GCM;
+ }
+ assert(0);
+ return KeyWrapAlgorithm::NONE;
+ }
+
+ Aws::String GetNameForKeyWrapAlgorithm(KeyWrapAlgorithm enumValue)
+ {
+ switch (enumValue)
+ {
+ case KeyWrapAlgorithm::KMS:
+ return "kms";
+ case KeyWrapAlgorithm::KMS_CONTEXT:
+ return "kms+context";
+ case KeyWrapAlgorithm::AES_KEY_WRAP:
+ return "AESWrap";
+ case KeyWrapAlgorithm::AES_GCM:
+ return "AES/GCM";
+ default:
+ assert(0);
+ }
+ return "";
+ }
+ }//namespace KeyWrapAlgorithmMapper
+ }//namespace Crypto
+ }//namespace Utils
+}//namespace Aws
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/MD5.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/MD5.cpp
new file mode 100644
index 0000000000..bf14ace1ad
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/MD5.cpp
@@ -0,0 +1,31 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+
+#include <aws/core/utils/crypto/MD5.h>
+#include <aws/core/utils/Outcome.h>
+#include <aws/core/utils/crypto/Factories.h>
+
+using namespace Aws::Utils::Crypto;
+
+
+MD5::MD5() :
+ m_hashImpl(CreateMD5Implementation())
+{
+}
+
+MD5::~MD5()
+{
+}
+
+HashResult MD5::Calculate(const Aws::String& str)
+{
+ return m_hashImpl->Calculate(str);
+}
+
+HashResult MD5::Calculate(Aws::IStream& stream)
+{
+ return m_hashImpl->Calculate(stream);
+} \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp
new file mode 100644
index 0000000000..178df00d37
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256.cpp
@@ -0,0 +1,30 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+
+#include <aws/core/utils/crypto/Sha256.h>
+#include <aws/core/utils/Outcome.h>
+#include <aws/core/utils/crypto/Factories.h>
+
+using namespace Aws::Utils::Crypto;
+
+Sha256::Sha256() :
+ m_hashImpl(CreateSha256Implementation())
+{
+}
+
+Sha256::~Sha256()
+{
+}
+
+HashResult Sha256::Calculate(const Aws::String& str)
+{
+ return m_hashImpl->Calculate(str);
+}
+
+HashResult Sha256::Calculate(Aws::IStream& stream)
+{
+ return m_hashImpl->Calculate(stream);
+} \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256HMAC.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256HMAC.cpp
new file mode 100644
index 0000000000..ecc1f06529
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/Sha256HMAC.cpp
@@ -0,0 +1,34 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+
+#include <aws/core/utils/crypto/Sha256HMAC.h>
+#include <aws/core/utils/crypto/Factories.h>
+#include <aws/core/utils/Outcome.h>
+
+namespace Aws
+{
+namespace Utils
+{
+namespace Crypto
+{
+
+Sha256HMAC::Sha256HMAC() :
+ m_hmacImpl(CreateSha256HMACImplementation())
+{
+}
+
+Sha256HMAC::~Sha256HMAC()
+{
+}
+
+HashResult Sha256HMAC::Calculate(const Aws::Utils::ByteBuffer& toSign, const Aws::Utils::ByteBuffer& secret)
+{
+ return m_hmacImpl->Calculate(toSign, secret);
+}
+
+} // namespace Crypto
+} // namespace Utils
+} // namespace Aws \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp
new file mode 100644
index 0000000000..bff0382241
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/factory/Factories.cpp
@@ -0,0 +1,895 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+
+#include <aws/core/utils/crypto/Factories.h>
+#include <aws/core/utils/crypto/Hash.h>
+#include <aws/core/utils/crypto/HMAC.h>
+
+#if ENABLE_BCRYPT_ENCRYPTION
+ #error #include <aws/core/utils/crypto/bcrypt/CryptoImpl.h>
+#elif ENABLE_OPENSSL_ENCRYPTION
+ #include <aws/core/utils/crypto/openssl/CryptoImpl.h>
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ #error #include <aws/core/utils/crypto/commoncrypto/CryptoImpl.h>
+ #include <aws/core/utils/logging/LogMacros.h>
+#else
+ // if you don't have any encryption you still need to pull in the interface definitions
+ #include <aws/core/utils/crypto/Hash.h>
+ #include <aws/core/utils/crypto/HMAC.h>
+ #include <aws/core/utils/crypto/Cipher.h>
+ #include <aws/core/utils/crypto/SecureRandom.h>
+ #define NO_ENCRYPTION
+#endif
+
+using namespace Aws::Utils;
+using namespace Aws::Utils::Crypto;
+
+static const char *s_allocationTag = "CryptoFactory";
+
+static std::shared_ptr<HashFactory>& GetMD5Factory()
+{
+ static std::shared_ptr<HashFactory> s_MD5Factory(nullptr);
+ return s_MD5Factory;
+}
+
+static std::shared_ptr<HashFactory>& GetSha256Factory()
+{
+ static std::shared_ptr<HashFactory> s_Sha256Factory(nullptr);
+ return s_Sha256Factory;
+}
+
+static std::shared_ptr<HMACFactory>& GetSha256HMACFactory()
+{
+ static std::shared_ptr<HMACFactory> s_Sha256HMACFactory(nullptr);
+ return s_Sha256HMACFactory;
+}
+
+static std::shared_ptr<SymmetricCipherFactory>& GetAES_CBCFactory()
+{
+ static std::shared_ptr<SymmetricCipherFactory> s_AES_CBCFactory(nullptr);
+ return s_AES_CBCFactory;
+}
+
+static std::shared_ptr<SymmetricCipherFactory>& GetAES_CTRFactory()
+{
+ static std::shared_ptr<SymmetricCipherFactory> s_AES_CTRFactory(nullptr);
+ return s_AES_CTRFactory;
+}
+
+static std::shared_ptr<SymmetricCipherFactory>& GetAES_GCMFactory()
+{
+ static std::shared_ptr<SymmetricCipherFactory> s_AES_GCMFactory(nullptr);
+ return s_AES_GCMFactory;
+}
+
+static std::shared_ptr<SymmetricCipherFactory>& GetAES_KeyWrapFactory()
+{
+ static std::shared_ptr<SymmetricCipherFactory> s_AES_KeyWrapFactory(nullptr);
+ return s_AES_KeyWrapFactory;
+}
+
+static std::shared_ptr<SecureRandomFactory>& GetSecureRandomFactory()
+{
+ static std::shared_ptr<SecureRandomFactory> s_SecureRandomFactory(nullptr);
+ return s_SecureRandomFactory;
+}
+
+static std::shared_ptr<SecureRandomBytes>& GetSecureRandom()
+{
+ static std::shared_ptr<SecureRandomBytes> s_SecureRandom(nullptr);
+ return s_SecureRandom;
+}
+
+static bool s_InitCleanupOpenSSLFlag(false);
+
+class DefaultMD5Factory : public HashFactory
+{
+public:
+ std::shared_ptr<Hash> CreateImplementation() const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<MD5BcryptImpl>(s_allocationTag);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<MD5OpenSSLImpl>(s_allocationTag);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<MD5CommonCryptoImpl>(s_allocationTag);
+#else
+ return nullptr;
+#endif
+ }
+
+ /**
+ * Opportunity to make any static initialization calls you need to make.
+ * Will only be called once.
+ */
+ void InitStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
+ }
+#endif
+ }
+
+ /**
+ * Opportunity to make any static cleanup calls you need to make.
+ * will only be called at the end of the application.
+ */
+ void CleanupStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
+ }
+#endif
+ }
+};
+
+class DefaultSHA256Factory : public HashFactory
+{
+public:
+ std::shared_ptr<Hash> CreateImplementation() const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<Sha256BcryptImpl>(s_allocationTag);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<Sha256OpenSSLImpl>(s_allocationTag);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<Sha256CommonCryptoImpl>(s_allocationTag);
+#else
+ return nullptr;
+#endif
+ }
+
+ /**
+ * Opportunity to make any static initialization calls you need to make.
+ * Will only be called once.
+ */
+ void InitStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
+ }
+#endif
+ }
+
+ /**
+ * Opportunity to make any static cleanup calls you need to make.
+ * will only be called at the end of the application.
+ */
+ void CleanupStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
+ }
+#endif
+ }
+};
+
+class DefaultSHA256HmacFactory : public HMACFactory
+{
+public:
+ std::shared_ptr<Aws::Utils::Crypto::HMAC> CreateImplementation() const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<Sha256HMACBcryptImpl>(s_allocationTag);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<Sha256HMACOpenSSLImpl>(s_allocationTag);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<Sha256HMACCommonCryptoImpl>(s_allocationTag);
+#else
+ return nullptr;
+#endif
+ }
+
+ /**
+ * Opportunity to make any static initialization calls you need to make.
+ * Will only be called once.
+ */
+ void InitStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
+ }
+#endif
+ }
+
+ /**
+ * Opportunity to make any static cleanup calls you need to make.
+ * will only be called at the end of the application.
+ */
+ void CleanupStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
+ }
+#endif
+ }
+};
+
+
+class DefaultAES_CBCFactory : public SymmetricCipherFactory
+{
+public:
+ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<AES_CBC_Cipher_BCrypt>(s_allocationTag, key);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<AES_CBC_Cipher_OpenSSL>(s_allocationTag, key);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<AES_CBC_Cipher_CommonCrypto>(s_allocationTag, key);
+#else
+ AWS_UNREFERENCED_PARAM(key);
+ return nullptr;
+#endif
+ }
+ /**
+ * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
+ */
+ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer&, const CryptoBuffer&) const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<AES_CBC_Cipher_BCrypt>(s_allocationTag, key, iv);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<AES_CBC_Cipher_OpenSSL>(s_allocationTag, key, iv);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<AES_CBC_Cipher_CommonCrypto>(s_allocationTag, key, iv);
+#else
+ AWS_UNREFERENCED_PARAM(key);
+ AWS_UNREFERENCED_PARAM(iv);
+
+ return nullptr;
+#endif
+ }
+ /**
+ * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
+ */
+ std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&&, CryptoBuffer&&) const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<AES_CBC_Cipher_BCrypt>(s_allocationTag, key, iv);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<AES_CBC_Cipher_OpenSSL>(s_allocationTag, key, iv);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<AES_CBC_Cipher_CommonCrypto>(s_allocationTag, key, iv);
+#else
+ AWS_UNREFERENCED_PARAM(key);
+ AWS_UNREFERENCED_PARAM(iv);
+
+ return nullptr;
+#endif
+ }
+
+ /**
+ * Opportunity to make any static initialization calls you need to make.
+ * Will only be called once.
+ */
+ void InitStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
+ }
+#endif
+ }
+
+ /**
+ * Opportunity to make any static cleanup calls you need to make.
+ * will only be called at the end of the application.
+ */
+ void CleanupStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
+ }
+#endif
+ }
+};
+
+class DefaultAES_CTRFactory : public SymmetricCipherFactory
+{
+public:
+ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<AES_CTR_Cipher_BCrypt>(s_allocationTag, key);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<AES_CTR_Cipher_OpenSSL>(s_allocationTag, key);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<AES_CTR_Cipher_CommonCrypto>(s_allocationTag, key);
+#else
+ AWS_UNREFERENCED_PARAM(key);
+ return nullptr;
+#endif
+ }
+ /**
+ * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
+ */
+ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer&, const CryptoBuffer&) const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<AES_CTR_Cipher_BCrypt>(s_allocationTag, key, iv);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<AES_CTR_Cipher_OpenSSL>(s_allocationTag, key, iv);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<AES_CTR_Cipher_CommonCrypto>(s_allocationTag, key, iv);
+#else
+ AWS_UNREFERENCED_PARAM(key);
+ AWS_UNREFERENCED_PARAM(iv);
+
+ return nullptr;
+#endif
+ }
+ /**
+ * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
+ */
+ std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&&, CryptoBuffer&&) const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<AES_CTR_Cipher_BCrypt>(s_allocationTag, key, iv);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<AES_CTR_Cipher_OpenSSL>(s_allocationTag, key, iv);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<AES_CTR_Cipher_CommonCrypto>(s_allocationTag, key, iv);
+#else
+ AWS_UNREFERENCED_PARAM(key);
+ AWS_UNREFERENCED_PARAM(iv);
+
+ return nullptr;
+#endif
+ }
+
+ /**
+ * Opportunity to make any static initialization calls you need to make.
+ * Will only be called once.
+ */
+ void InitStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
+ }
+#endif
+ }
+
+ /**
+ * Opportunity to make any static cleanup calls you need to make.
+ * will only be called at the end of the application.
+ */
+ void CleanupStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
+ }
+#endif
+ }
+};
+
+class DefaultAES_GCMFactory : public SymmetricCipherFactory
+{
+public:
+ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<AES_GCM_Cipher_BCrypt>(s_allocationTag, key);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, key);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<AES_GCM_Cipher_CommonCrypto>(s_allocationTag, key);
+#else
+ AWS_UNREFERENCED_PARAM(key);
+
+ return nullptr;
+#endif
+ }
+
+ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer* aad) const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<AES_GCM_Cipher_BCrypt>(s_allocationTag, key, aad);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, key, aad);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<AES_GCM_Cipher_CommonCrypto>(s_allocationTag, key, aad);
+#else
+ AWS_UNREFERENCED_PARAM(key);
+ AWS_UNREFERENCED_PARAM(aad);
+ return nullptr;
+#endif
+ }
+
+ /**
+ * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
+ */
+ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer& tag, const CryptoBuffer& aad) const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<AES_GCM_Cipher_BCrypt>(s_allocationTag, key, iv, tag, aad);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, key, iv, tag, aad);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<AES_GCM_Cipher_CommonCrypto>(s_allocationTag, key, iv, tag, aad);
+#else
+ AWS_UNREFERENCED_PARAM(key);
+ AWS_UNREFERENCED_PARAM(iv);
+ AWS_UNREFERENCED_PARAM(tag);
+ AWS_UNREFERENCED_PARAM(aad);
+ return nullptr;
+#endif
+ }
+ /**
+ * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
+ */
+ std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&& tag, CryptoBuffer&& aad) const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<AES_GCM_Cipher_BCrypt>(s_allocationTag, std::move(key), std::move(iv), std::move(tag), std::move(aad));
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<AES_GCM_Cipher_OpenSSL>(s_allocationTag, std::move(key), std::move(iv), std::move(tag), std::move(aad));
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<AES_GCM_Cipher_CommonCrypto>(s_allocationTag, std::move(key), std::move(iv), std::move(tag), std::move(aad));
+#else
+ AWS_UNREFERENCED_PARAM(key);
+ AWS_UNREFERENCED_PARAM(iv);
+ AWS_UNREFERENCED_PARAM(tag);
+ AWS_UNREFERENCED_PARAM(aad);
+ return nullptr;
+#endif
+ }
+
+ /**
+ * Opportunity to make any static initialization calls you need to make.
+ * Will only be called once.
+ */
+ void InitStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
+ }
+#endif
+ }
+
+ /**
+ * Opportunity to make any static cleanup calls you need to make.
+ * will only be called at the end of the application.
+ */
+ void CleanupStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
+ }
+#endif
+ }
+};
+
+class DefaultAES_KeyWrapFactory : public SymmetricCipherFactory
+{
+public:
+ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key) const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<AES_KeyWrap_Cipher_BCrypt>(s_allocationTag, key);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<AES_KeyWrap_Cipher_OpenSSL>(s_allocationTag, key);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<AES_KeyWrap_Cipher_CommonCrypto>(s_allocationTag, key);
+#else
+ AWS_UNREFERENCED_PARAM(key);
+ return nullptr;
+#endif
+ }
+ /**
+ * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
+ */
+ std::shared_ptr<SymmetricCipher> CreateImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer& tag, const CryptoBuffer&) const override
+ {
+ AWS_UNREFERENCED_PARAM(key);
+ AWS_UNREFERENCED_PARAM(iv);
+ AWS_UNREFERENCED_PARAM(tag);
+ return nullptr;
+ }
+ /**
+ * Factory method. Returns cipher implementation. See the SymmetricCipher class for more details.
+ */
+ std::shared_ptr<SymmetricCipher> CreateImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&& tag, CryptoBuffer&&) const override
+ {
+ AWS_UNREFERENCED_PARAM(key);
+ AWS_UNREFERENCED_PARAM(iv);
+ AWS_UNREFERENCED_PARAM(tag);
+ return nullptr;
+ }
+
+ /**
+ * Opportunity to make any static initialization calls you need to make.
+ * Will only be called once.
+ */
+ void InitStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if (s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
+ }
+#endif
+ }
+
+ /**
+ * Opportunity to make any static cleanup calls you need to make.
+ * will only be called at the end of the application.
+ */
+ void CleanupStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if (s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
+ }
+#endif
+ }
+};
+
+class DefaultSecureRandFactory : public SecureRandomFactory
+{
+ /**
+ * Factory method. Returns SecureRandom implementation.
+ */
+ std::shared_ptr<SecureRandomBytes> CreateImplementation() const override
+ {
+#if ENABLE_BCRYPT_ENCRYPTION
+ return Aws::MakeShared<SecureRandomBytes_BCrypt>(s_allocationTag);
+#elif ENABLE_OPENSSL_ENCRYPTION
+ return Aws::MakeShared<SecureRandomBytes_OpenSSLImpl>(s_allocationTag);
+#elif ENABLE_COMMONCRYPTO_ENCRYPTION
+ return Aws::MakeShared<SecureRandomBytes_CommonCrypto>(s_allocationTag);
+#else
+ return nullptr;
+#endif
+ }
+
+ /**
+ * Opportunity to make any static initialization calls you need to make.
+ * Will only be called once.
+ */
+ void InitStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.EnterRoom(&OpenSSL::init_static_state);
+ }
+#endif
+ }
+
+ /**
+ * Opportunity to make any static cleanup calls you need to make.
+ * will only be called at the end of the application.
+ */
+ void CleanupStaticState() override
+ {
+#if ENABLE_OPENSSL_ENCRYPTION
+ if(s_InitCleanupOpenSSLFlag)
+ {
+ OpenSSL::getTheLights.LeaveRoom(&OpenSSL::cleanup_static_state);
+ }
+#endif
+ }
+};
+
+void Aws::Utils::Crypto::SetInitCleanupOpenSSLFlag(bool initCleanupFlag)
+{
+ s_InitCleanupOpenSSLFlag = initCleanupFlag;
+}
+
+void Aws::Utils::Crypto::InitCrypto()
+{
+ if(GetMD5Factory())
+ {
+ GetMD5Factory()->InitStaticState();
+ }
+ else
+ {
+ GetMD5Factory() = Aws::MakeShared<DefaultMD5Factory>(s_allocationTag);
+ GetMD5Factory()->InitStaticState();
+ }
+
+ if(GetSha256Factory())
+ {
+ GetSha256Factory()->InitStaticState();
+ }
+ else
+ {
+ GetSha256Factory() = Aws::MakeShared<DefaultSHA256Factory>(s_allocationTag);
+ GetSha256Factory()->InitStaticState();
+ }
+
+ if(GetSha256HMACFactory())
+ {
+ GetSha256HMACFactory()->InitStaticState();
+ }
+ else
+ {
+ GetSha256HMACFactory() = Aws::MakeShared<DefaultSHA256HmacFactory>(s_allocationTag);
+ GetSha256HMACFactory()->InitStaticState();
+ }
+
+ if(GetAES_CBCFactory())
+ {
+ GetAES_CBCFactory()->InitStaticState();
+ }
+ else
+ {
+ GetAES_CBCFactory() = Aws::MakeShared<DefaultAES_CBCFactory>(s_allocationTag);
+ GetAES_CBCFactory()->InitStaticState();
+ }
+
+ if(GetAES_CTRFactory())
+ {
+ GetAES_CTRFactory()->InitStaticState();
+ }
+ else
+ {
+ GetAES_CTRFactory() = Aws::MakeShared<DefaultAES_CTRFactory>(s_allocationTag);
+ GetAES_CTRFactory()->InitStaticState();
+ }
+
+ if(GetAES_GCMFactory())
+ {
+ GetAES_GCMFactory()->InitStaticState();
+ }
+ else
+ {
+ GetAES_GCMFactory() = Aws::MakeShared<DefaultAES_GCMFactory>(s_allocationTag);
+ GetAES_GCMFactory()->InitStaticState();
+ }
+
+ if (!GetAES_KeyWrapFactory())
+ {
+ GetAES_KeyWrapFactory() = Aws::MakeShared<DefaultAES_KeyWrapFactory>(s_allocationTag);
+ }
+ GetAES_KeyWrapFactory()->InitStaticState();
+
+ if(GetSecureRandomFactory())
+ {
+ GetSecureRandomFactory()->InitStaticState();
+ }
+ else
+ {
+ GetSecureRandomFactory() = Aws::MakeShared<DefaultSecureRandFactory>(s_allocationTag);
+ GetSecureRandomFactory()->InitStaticState();
+ }
+
+ GetSecureRandom() = GetSecureRandomFactory()->CreateImplementation();
+}
+
+void Aws::Utils::Crypto::CleanupCrypto()
+{
+ if(GetMD5Factory())
+ {
+ GetMD5Factory()->CleanupStaticState();
+ GetMD5Factory() = nullptr;
+ }
+
+ if(GetSha256Factory())
+ {
+ GetSha256Factory()->CleanupStaticState();
+ GetSha256Factory() = nullptr;
+ }
+
+ if(GetSha256HMACFactory())
+ {
+ GetSha256HMACFactory()->CleanupStaticState();
+ GetSha256HMACFactory() = nullptr;
+ }
+
+ if(GetAES_CBCFactory())
+ {
+ GetAES_CBCFactory()->CleanupStaticState();
+ GetAES_CBCFactory() = nullptr;
+ }
+
+ if(GetAES_CTRFactory())
+ {
+ GetAES_CTRFactory()->CleanupStaticState();
+ GetAES_CTRFactory() = nullptr;
+ }
+
+ if(GetAES_GCMFactory())
+ {
+ GetAES_GCMFactory()->CleanupStaticState();
+ GetAES_GCMFactory() = nullptr;
+ }
+
+ if(GetAES_KeyWrapFactory())
+ {
+ GetAES_KeyWrapFactory()->CleanupStaticState();
+ GetAES_KeyWrapFactory() = nullptr;
+ }
+
+ if(GetSecureRandomFactory())
+ {
+ GetSecureRandom() = nullptr;
+ GetSecureRandomFactory()->CleanupStaticState();
+ GetSecureRandomFactory() = nullptr;
+ }
+}
+
+void Aws::Utils::Crypto::SetMD5Factory(const std::shared_ptr<HashFactory>& factory)
+{
+ GetMD5Factory() = factory;
+}
+
+void Aws::Utils::Crypto::SetSha256Factory(const std::shared_ptr<HashFactory>& factory)
+{
+ GetSha256Factory() = factory;
+}
+
+void Aws::Utils::Crypto::SetSha256HMACFactory(const std::shared_ptr<HMACFactory>& factory)
+{
+ GetSha256HMACFactory() = factory;
+}
+
+void Aws::Utils::Crypto::SetAES_CBCFactory(const std::shared_ptr<SymmetricCipherFactory>& factory)
+{
+ GetAES_CBCFactory() = factory;
+}
+
+void Aws::Utils::Crypto::SetAES_CTRFactory(const std::shared_ptr<SymmetricCipherFactory>& factory)
+{
+ GetAES_CTRFactory() = factory;
+}
+
+void Aws::Utils::Crypto::SetAES_GCMFactory(const std::shared_ptr<SymmetricCipherFactory>& factory)
+{
+ GetAES_GCMFactory() = factory;
+}
+
+void Aws::Utils::Crypto::SetAES_KeyWrapFactory(const std::shared_ptr<SymmetricCipherFactory>& factory)
+{
+ GetAES_KeyWrapFactory() = factory;
+}
+
+void Aws::Utils::Crypto::SetSecureRandomFactory(const std::shared_ptr<SecureRandomFactory>& factory)
+{
+ GetSecureRandomFactory() = factory;
+}
+
+std::shared_ptr<Hash> Aws::Utils::Crypto::CreateMD5Implementation()
+{
+ return GetMD5Factory()->CreateImplementation();
+}
+
+std::shared_ptr<Hash> Aws::Utils::Crypto::CreateSha256Implementation()
+{
+ return GetSha256Factory()->CreateImplementation();
+}
+
+std::shared_ptr<Aws::Utils::Crypto::HMAC> Aws::Utils::Crypto::CreateSha256HMACImplementation()
+{
+ return GetSha256HMACFactory()->CreateImplementation();
+}
+
+#ifdef _WIN32
+#pragma warning( push )
+#pragma warning( disable : 4702 )
+#endif
+
+std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CBCImplementation(const CryptoBuffer& key)
+{
+#ifdef NO_SYMMETRIC_ENCRYPTION
+ return nullptr;
+#endif
+ return GetAES_CBCFactory()->CreateImplementation(key);
+}
+
+std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CBCImplementation(const CryptoBuffer& key, const CryptoBuffer& iv)
+{
+#ifdef NO_SYMMETRIC_ENCRYPTION
+ return nullptr;
+#endif
+ return GetAES_CBCFactory()->CreateImplementation(key, iv);
+}
+
+std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CBCImplementation(CryptoBuffer&& key, CryptoBuffer&& iv)
+{
+#ifdef NO_SYMMETRIC_ENCRYPTION
+ return nullptr;
+#endif
+ return GetAES_CBCFactory()->CreateImplementation(std::move(key), std::move(iv));
+}
+
+std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CTRImplementation(const CryptoBuffer& key)
+{
+#ifdef NO_SYMMETRIC_ENCRYPTION
+ return nullptr;
+#endif
+ return GetAES_CTRFactory()->CreateImplementation(key);
+}
+
+std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CTRImplementation(const CryptoBuffer& key, const CryptoBuffer& iv)
+{
+#ifdef NO_SYMMETRIC_ENCRYPTION
+ return nullptr;
+#endif
+ return GetAES_CTRFactory()->CreateImplementation(key, iv);
+}
+
+std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_CTRImplementation(CryptoBuffer&& key, CryptoBuffer&& iv)
+{
+#ifdef NO_SYMMETRIC_ENCRYPTION
+ return nullptr;
+#endif
+ return GetAES_CTRFactory()->CreateImplementation(std::move(key), std::move(iv));
+}
+
+std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(const CryptoBuffer& key)
+{
+#ifdef NO_SYMMETRIC_ENCRYPTION
+ return nullptr;
+#endif
+ return GetAES_GCMFactory()->CreateImplementation(key);
+}
+
+std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(const CryptoBuffer& key, const CryptoBuffer* aad)
+{
+#ifdef NO_SYMMETRIC_ENCRYPTION
+ return nullptr;
+#endif
+ return GetAES_GCMFactory()->CreateImplementation(key, aad);
+}
+
+std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(const CryptoBuffer& key, const CryptoBuffer& iv, const CryptoBuffer& tag, const CryptoBuffer& aad)
+{
+#ifdef NO_SYMMETRIC_ENCRYPTION
+ return nullptr;
+#endif
+ return GetAES_GCMFactory()->CreateImplementation(key, iv, tag, aad);
+}
+
+std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_GCMImplementation(CryptoBuffer&& key, CryptoBuffer&& iv, CryptoBuffer&& tag, CryptoBuffer&& aad)
+{
+#ifdef NO_SYMMETRIC_ENCRYPTION
+ return nullptr;
+#endif
+ return GetAES_GCMFactory()->CreateImplementation(std::move(key), std::move(iv), std::move(tag), std::move(aad));
+}
+
+std::shared_ptr<SymmetricCipher> Aws::Utils::Crypto::CreateAES_KeyWrapImplementation(const CryptoBuffer& key)
+{
+#ifdef NO_SYMMETRIC_ENCRYPTION
+ return nullptr;
+#endif
+ return GetAES_KeyWrapFactory()->CreateImplementation(key);
+}
+
+#ifdef _WIN32
+#pragma warning(pop)
+#endif
+
+std::shared_ptr<SecureRandomBytes> Aws::Utils::Crypto::CreateSecureRandomBytesImplementation()
+{
+ return GetSecureRandom();
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp
new file mode 100644
index 0000000000..911838864b
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/crypto/openssl/CryptoImpl.cpp
@@ -0,0 +1,987 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <cstring>
+
+#include <aws/core/utils/memory/AWSMemory.h>
+#include <aws/core/utils/crypto/openssl/CryptoImpl.h>
+#include <aws/core/utils/Outcome.h>
+#include <openssl/md5.h>
+
+#ifdef OPENSSL_IS_BORINGSSL
+#ifdef _MSC_VER
+AWS_SUPPRESS_WARNING_PUSH(4201)
+#else
+AWS_SUPPRESS_WARNING_PUSH("-Wpedantic")
+#endif
+#endif
+
+#include <openssl/sha.h>
+
+#ifdef OPENSSL_IS_BORINGSSL
+AWS_SUPPRESS_WARNING_POP
+#endif
+
+#include <openssl/err.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <thread>
+
+using namespace Aws::Utils;
+using namespace Aws::Utils::Crypto;
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Crypto
+ {
+ namespace OpenSSL
+ {
+/**
+ * openssl with OPENSSL_VERSION_NUMBER < 0x10100003L made data type details unavailable
+ * libressl use openssl with data type details available, but mandatorily set
+ * OPENSSL_VERSION_NUMBER = 0x20000000L, insane!
+ * https://github.com/aws/aws-sdk-cpp/pull/507/commits/2c99f1fe0c4b4683280caeb161538d4724d6a179
+ */
+#if defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER == 0x20000000L)
+#undef OPENSSL_VERSION_NUMBER
+#define OPENSSL_VERSION_NUMBER 0x1000107fL
+#endif
+#define OPENSSL_VERSION_LESS_1_1 (OPENSSL_VERSION_NUMBER < 0x10100003L)
+
+#if OPENSSL_VERSION_LESS_1_1
+ static const char* OPENSSL_INTERNALS_TAG = "OpenSSLCallbackState";
+ static std::mutex* locks(nullptr);
+#endif
+
+ GetTheLights getTheLights;
+
+ void init_static_state()
+ {
+#if OPENSSL_VERSION_LESS_1_1 || defined(OPENSSL_IS_BORINGSSL)
+ ERR_load_crypto_strings();
+#else
+ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS /*options*/ ,NULL /* OpenSSL init settings*/ );
+#endif
+#if !defined(OPENSSL_IS_BORINGSSL)
+ OPENSSL_add_all_algorithms_noconf();
+#endif
+#if OPENSSL_VERSION_LESS_1_1
+ if (!CRYPTO_get_locking_callback())
+ {
+ locks = Aws::NewArray<std::mutex>(static_cast<size_t>(CRYPTO_num_locks()),
+ OPENSSL_INTERNALS_TAG);
+ CRYPTO_set_locking_callback(&locking_fn);
+ }
+
+ if (!CRYPTO_get_id_callback())
+ {
+ CRYPTO_set_id_callback(&id_fn);
+ }
+#endif
+ RAND_poll();
+ }
+
+ void cleanup_static_state()
+ {
+#if OPENSSL_VERSION_LESS_1_1
+ if (CRYPTO_get_locking_callback() == &locking_fn)
+ {
+ CRYPTO_set_locking_callback(nullptr);
+ assert(locks);
+ Aws::DeleteArray(locks);
+ locks = nullptr;
+ }
+
+ if (CRYPTO_get_id_callback() == &id_fn)
+ {
+ CRYPTO_set_id_callback(nullptr);
+ }
+#endif
+ }
+
+#if OPENSSL_VERSION_LESS_1_1
+ void locking_fn(int mode, int n, const char*, int)
+ {
+ if (mode & CRYPTO_LOCK)
+ {
+ locks[n].lock();
+ }
+ else
+ {
+ locks[n].unlock();
+ }
+ }
+
+ unsigned long id_fn()
+ {
+ return static_cast<unsigned long>(std::hash<std::thread::id>()(std::this_thread::get_id()));
+ }
+#endif
+ }
+
+ static const char* OPENSSL_LOG_TAG = "OpenSSLCipher";
+
+ void SecureRandomBytes_OpenSSLImpl::GetBytes(unsigned char* buffer, size_t bufferSize)
+ {
+ if (!bufferSize)
+ {
+ return;
+ }
+
+ if (!buffer)
+ {
+ AWS_LOGSTREAM_FATAL(OPENSSL_LOG_TAG, "Secure Random Bytes generator can't generate: " << bufferSize << " bytes with nullptr buffer.");
+ assert(buffer);
+ return;
+ }
+
+ int success = RAND_bytes(buffer, static_cast<int>(bufferSize));
+ if (success != 1)
+ {
+ m_failure = true;
+ }
+ }
+
+ class OpensslCtxRAIIGuard
+ {
+ public:
+ OpensslCtxRAIIGuard()
+ {
+ m_ctx = EVP_MD_CTX_create();
+ assert(m_ctx != nullptr);
+ }
+
+ ~OpensslCtxRAIIGuard()
+ {
+ EVP_MD_CTX_destroy(m_ctx);
+ m_ctx = nullptr;
+ }
+
+ EVP_MD_CTX* getResource()
+ {
+ return m_ctx;
+ }
+ private:
+ EVP_MD_CTX *m_ctx;
+ };
+
+ HashResult MD5OpenSSLImpl::Calculate(const Aws::String& str)
+ {
+ OpensslCtxRAIIGuard guard;
+ auto ctx = guard.getResource();
+#if !defined(OPENSSL_IS_BORINGSSL)
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#endif
+ EVP_DigestInit_ex(ctx, EVP_md5(), nullptr);
+ EVP_DigestUpdate(ctx, str.c_str(), str.size());
+
+ ByteBuffer hash(EVP_MD_size(EVP_md5()));
+ EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr);
+
+ return HashResult(std::move(hash));
+ }
+
+ HashResult MD5OpenSSLImpl::Calculate(Aws::IStream& stream)
+ {
+ OpensslCtxRAIIGuard guard;
+ auto ctx = guard.getResource();
+#if !defined(OPENSSL_IS_BORINGSSL)
+ EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#endif
+ EVP_DigestInit_ex(ctx, EVP_md5(), nullptr);
+
+ auto currentPos = stream.tellg();
+ if (currentPos == -1)
+ {
+ currentPos = 0;
+ stream.clear();
+ }
+ stream.seekg(0, stream.beg);
+
+ char streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE];
+ while (stream.good())
+ {
+ stream.read(streamBuffer, Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE);
+ auto bytesRead = stream.gcount();
+
+ if (bytesRead > 0)
+ {
+ EVP_DigestUpdate(ctx, streamBuffer, static_cast<size_t>(bytesRead));
+ }
+ }
+
+ stream.clear();
+ stream.seekg(currentPos, stream.beg);
+
+ ByteBuffer hash(EVP_MD_size(EVP_md5()));
+ EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr);
+
+ return HashResult(std::move(hash));
+ }
+
+ HashResult Sha256OpenSSLImpl::Calculate(const Aws::String& str)
+ {
+ OpensslCtxRAIIGuard guard;
+ auto ctx = guard.getResource();
+ EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr);
+ EVP_DigestUpdate(ctx, str.c_str(), str.size());
+
+ ByteBuffer hash(EVP_MD_size(EVP_sha256()));
+ EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr);
+
+ return HashResult(std::move(hash));
+ }
+
+ HashResult Sha256OpenSSLImpl::Calculate(Aws::IStream& stream)
+ {
+ OpensslCtxRAIIGuard guard;
+ auto ctx = guard.getResource();
+
+ EVP_DigestInit_ex(ctx, EVP_sha256(), nullptr);
+
+ auto currentPos = stream.tellg();
+ if (currentPos == -1)
+ {
+ currentPos = 0;
+ stream.clear();
+ }
+
+ stream.seekg(0, stream.beg);
+
+ char streamBuffer[Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE];
+ while (stream.good())
+ {
+ stream.read(streamBuffer, Aws::Utils::Crypto::Hash::INTERNAL_HASH_STREAM_BUFFER_SIZE);
+ auto bytesRead = stream.gcount();
+
+ if (bytesRead > 0)
+ {
+ EVP_DigestUpdate(ctx, streamBuffer, static_cast<size_t>(bytesRead));
+ }
+ }
+
+ stream.clear();
+ stream.seekg(currentPos, stream.beg);
+
+ ByteBuffer hash(EVP_MD_size(EVP_sha256()));
+ EVP_DigestFinal(ctx, hash.GetUnderlyingData(), nullptr);
+
+ return HashResult(std::move(hash));
+ }
+
+ class HMACRAIIGuard {
+ public:
+ HMACRAIIGuard() {
+#if OPENSSL_VERSION_LESS_1_1
+ m_ctx = Aws::New<HMAC_CTX>("AllocSha256HAMCOpenSSLContext");
+#else
+ m_ctx = HMAC_CTX_new();
+#endif
+ assert(m_ctx != nullptr);
+ }
+
+ ~HMACRAIIGuard() {
+#if OPENSSL_VERSION_LESS_1_1
+ Aws::Delete<HMAC_CTX>(m_ctx);
+#else
+ HMAC_CTX_free(m_ctx);
+#endif
+ m_ctx = nullptr;
+ }
+
+ HMAC_CTX* getResource() {
+ return m_ctx;
+ }
+ private:
+ HMAC_CTX *m_ctx;
+ };
+
+ HashResult Sha256HMACOpenSSLImpl::Calculate(const ByteBuffer& toSign, const ByteBuffer& secret)
+ {
+ unsigned int length = SHA256_DIGEST_LENGTH;
+ ByteBuffer digest(length);
+ memset(digest.GetUnderlyingData(), 0, length);
+
+ HMACRAIIGuard guard;
+ HMAC_CTX* m_ctx = guard.getResource();
+
+#if OPENSSL_VERSION_LESS_1_1
+ HMAC_CTX_init(m_ctx);
+#endif
+
+ HMAC_Init_ex(m_ctx, secret.GetUnderlyingData(), static_cast<int>(secret.GetLength()), EVP_sha256(),
+ NULL);
+ HMAC_Update(m_ctx, toSign.GetUnderlyingData(), toSign.GetLength());
+ HMAC_Final(m_ctx, digest.GetUnderlyingData(), &length);
+
+#if OPENSSL_VERSION_LESS_1_1
+ HMAC_CTX_cleanup(m_ctx);
+#else
+ HMAC_CTX_reset(m_ctx);
+#endif
+ return HashResult(std::move(digest));
+ }
+
+ void LogErrors(const char* logTag = OPENSSL_LOG_TAG)
+ {
+ unsigned long errorCode = ERR_get_error();
+ char errStr[256];
+ ERR_error_string_n(errorCode, errStr, 256);
+
+ AWS_LOGSTREAM_ERROR(logTag, errStr);
+ }
+
+ OpenSSLCipher::OpenSSLCipher(const CryptoBuffer& key, size_t blockSizeBytes, bool ctrMode) :
+ SymmetricCipher(key, blockSizeBytes, ctrMode), m_encryptor_ctx(nullptr), m_decryptor_ctx(nullptr)
+ {
+ Init();
+ }
+
+ OpenSSLCipher::OpenSSLCipher(OpenSSLCipher&& toMove) : SymmetricCipher(std::move(toMove)),
+ m_encryptor_ctx(nullptr), m_decryptor_ctx(nullptr)
+ {
+ Init();
+ EVP_CIPHER_CTX_copy(m_encryptor_ctx, toMove.m_encryptor_ctx);
+ EVP_CIPHER_CTX_copy(m_decryptor_ctx, toMove.m_decryptor_ctx);
+ EVP_CIPHER_CTX_cleanup(toMove.m_encryptor_ctx);
+ EVP_CIPHER_CTX_cleanup(toMove.m_decryptor_ctx);
+ }
+
+ OpenSSLCipher::OpenSSLCipher(CryptoBuffer&& key, CryptoBuffer&& initializationVector, CryptoBuffer&& tag) :
+ SymmetricCipher(std::move(key), std::move(initializationVector), std::move(tag)),
+ m_encryptor_ctx(nullptr), m_decryptor_ctx(nullptr)
+ {
+ Init();
+ }
+
+ OpenSSLCipher::OpenSSLCipher(const CryptoBuffer& key, const CryptoBuffer& initializationVector,
+ const CryptoBuffer& tag) :
+ SymmetricCipher(key, initializationVector, tag), m_encryptor_ctx(nullptr), m_decryptor_ctx(nullptr)
+ {
+ Init();
+ }
+
+ OpenSSLCipher::~OpenSSLCipher()
+ {
+ Cleanup();
+ if (m_encryptor_ctx)
+ {
+ EVP_CIPHER_CTX_free(m_encryptor_ctx);
+ m_encryptor_ctx = nullptr;
+ }
+ if (m_decryptor_ctx)
+ {
+ EVP_CIPHER_CTX_free(m_decryptor_ctx);
+ m_decryptor_ctx = nullptr;
+ }
+ }
+
+ void OpenSSLCipher::Init()
+ {
+ if (m_failure)
+ {
+ return;
+ }
+
+ if (!m_encryptor_ctx)
+ {
+ // EVP_CIPHER_CTX_init() will be called inside EVP_CIPHER_CTX_new().
+ m_encryptor_ctx = EVP_CIPHER_CTX_new();
+ assert(m_encryptor_ctx != nullptr);
+ }
+ else
+ { // _init is the same as _reset after openssl 1.1
+ EVP_CIPHER_CTX_init(m_encryptor_ctx);
+ }
+ if (!m_decryptor_ctx)
+ {
+ // EVP_CIPHER_CTX_init() will be called inside EVP_CIPHER_CTX_new().
+ m_decryptor_ctx = EVP_CIPHER_CTX_new();
+ assert(m_decryptor_ctx != nullptr);
+ }
+ else
+ { // _init is the same as _reset after openssl 1.1
+ EVP_CIPHER_CTX_init(m_decryptor_ctx);
+ }
+ m_emptyPlaintext = false;
+ }
+
+ CryptoBuffer OpenSSLCipher::EncryptBuffer(const CryptoBuffer& unEncryptedData)
+ {
+ if (m_failure)
+ {
+ AWS_LOGSTREAM_FATAL(OPENSSL_LOG_TAG, "Cipher not properly initialized for encryption. Aborting");
+ return CryptoBuffer();
+ }
+
+ int lengthWritten = static_cast<int>(unEncryptedData.GetLength() + (GetBlockSizeBytes() - 1));
+ CryptoBuffer encryptedText(static_cast<size_t>( lengthWritten + (GetBlockSizeBytes() - 1)));
+
+ if (!EVP_EncryptUpdate(m_encryptor_ctx, encryptedText.GetUnderlyingData(), &lengthWritten,
+ unEncryptedData.GetUnderlyingData(),
+ static_cast<int>(unEncryptedData.GetLength())))
+ {
+ m_failure = true;
+ LogErrors();
+ return CryptoBuffer();
+ }
+
+ if (static_cast<size_t>(lengthWritten) < encryptedText.GetLength())
+ {
+ return CryptoBuffer(encryptedText.GetUnderlyingData(), static_cast<size_t>(lengthWritten));
+ }
+ return encryptedText;
+ }
+
+ CryptoBuffer OpenSSLCipher::FinalizeEncryption()
+ {
+ if (m_failure)
+ {
+ AWS_LOGSTREAM_FATAL(OPENSSL_LOG_TAG, "Cipher not properly initialized for encryption finalization. Aborting");
+ return CryptoBuffer();
+ }
+
+ CryptoBuffer finalBlock(GetBlockSizeBytes());
+ int writtenSize = 0;
+ if (!EVP_EncryptFinal_ex(m_encryptor_ctx, finalBlock.GetUnderlyingData(), &writtenSize))
+ {
+ m_failure = true;
+ LogErrors();
+ return CryptoBuffer();
+ }
+ return CryptoBuffer(finalBlock.GetUnderlyingData(), static_cast<size_t>(writtenSize));
+ }
+
+ CryptoBuffer OpenSSLCipher::DecryptBuffer(const CryptoBuffer& encryptedData)
+ {
+ if (m_failure)
+ {
+ AWS_LOGSTREAM_FATAL(OPENSSL_LOG_TAG, "Cipher not properly initialized for decryption. Aborting");
+ return CryptoBuffer();
+ }
+
+ int lengthWritten = static_cast<int>(encryptedData.GetLength() + (GetBlockSizeBytes() - 1));
+ CryptoBuffer decryptedText(static_cast<size_t>(lengthWritten));
+
+ if (!EVP_DecryptUpdate(m_decryptor_ctx, decryptedText.GetUnderlyingData(), &lengthWritten,
+ encryptedData.GetUnderlyingData(),
+ static_cast<int>(encryptedData.GetLength())))
+ {
+ m_failure = true;
+ LogErrors();
+ return CryptoBuffer();
+ }
+
+ if (lengthWritten == 0)
+ {
+ m_emptyPlaintext = true;
+ }
+ if (static_cast<size_t>(lengthWritten) < decryptedText.GetLength())
+ {
+ return CryptoBuffer(decryptedText.GetUnderlyingData(), static_cast<size_t>(lengthWritten));
+ }
+ return decryptedText;
+ }
+
+ CryptoBuffer OpenSSLCipher::FinalizeDecryption()
+ {
+ if (m_failure)
+ {
+ AWS_LOGSTREAM_FATAL(OPENSSL_LOG_TAG, "Cipher not properly initialized for decryption finalization. Aborting");
+ return CryptoBuffer();
+ }
+
+ CryptoBuffer finalBlock(GetBlockSizeBytes());
+ int writtenSize = static_cast<int>(finalBlock.GetLength());
+ int ret = EVP_DecryptFinal_ex(m_decryptor_ctx, finalBlock.GetUnderlyingData(), &writtenSize);
+#if OPENSSL_VERSION_NUMBER > 0x1010104fL //1.1.1d
+ if (ret <= 0)
+#else
+ if (ret <= 0 && !m_emptyPlaintext) // see details why making exception for empty string at: https://github.com/aws/aws-sdk-cpp/issues/1413
+#endif
+ {
+ m_failure = true;
+ LogErrors();
+ return CryptoBuffer();
+ }
+ return CryptoBuffer(finalBlock.GetUnderlyingData(), static_cast<size_t>(writtenSize));
+ }
+
+ void OpenSSLCipher::Reset()
+ {
+ Cleanup();
+ Init();
+ }
+
+ void OpenSSLCipher::Cleanup()
+ {
+ m_failure = false;
+ if (m_encryptor_ctx) EVP_CIPHER_CTX_cleanup(m_encryptor_ctx);
+ if (m_decryptor_ctx) EVP_CIPHER_CTX_cleanup(m_decryptor_ctx);
+ }
+
+ bool OpenSSLCipher::CheckKeyAndIVLength(size_t expectedKeyLength, size_t expectedIVLength)
+ {
+ if (!m_failure && ((m_key.GetLength() != expectedKeyLength) || m_initializationVector.GetLength() != expectedIVLength))
+ {
+ AWS_LOGSTREAM_ERROR(OPENSSL_LOG_TAG, "Expected Key size is: " << expectedKeyLength << " and expected IV size is: " << expectedIVLength);
+ m_failure = true;
+ }
+ return !m_failure;
+ }
+
+ size_t AES_CBC_Cipher_OpenSSL::BlockSizeBytes = 16;
+ size_t AES_CBC_Cipher_OpenSSL::KeyLengthBits = 256;
+ static const char* CBC_LOG_TAG = "AES_CBC_Cipher_OpenSSL";
+
+ AES_CBC_Cipher_OpenSSL::AES_CBC_Cipher_OpenSSL(const CryptoBuffer& key) : OpenSSLCipher(key, BlockSizeBytes)
+ {
+ InitCipher();
+ }
+
+ AES_CBC_Cipher_OpenSSL::AES_CBC_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector) :
+ OpenSSLCipher(std::move(key), std::move(initializationVector))
+ {
+ InitCipher();
+ }
+
+ AES_CBC_Cipher_OpenSSL::AES_CBC_Cipher_OpenSSL(const CryptoBuffer& key,
+ const CryptoBuffer& initializationVector) :
+ OpenSSLCipher(key, initializationVector)
+ {
+ InitCipher();
+ }
+
+ void AES_CBC_Cipher_OpenSSL::InitCipher()
+ {
+ if (m_failure || !CheckKeyAndIVLength(KeyLengthBits/8, BlockSizeBytes))
+ {
+ return;
+ }
+
+ if (!EVP_EncryptInit_ex(m_encryptor_ctx, EVP_aes_256_cbc(), nullptr, m_key.GetUnderlyingData(),
+ m_initializationVector.GetUnderlyingData()) ||
+ !EVP_DecryptInit_ex(m_decryptor_ctx, EVP_aes_256_cbc(), nullptr, m_key.GetUnderlyingData(),
+ m_initializationVector.GetUnderlyingData()))
+ {
+ m_failure = true;
+ LogErrors(CBC_LOG_TAG);
+ }
+ }
+
+ size_t AES_CBC_Cipher_OpenSSL::GetBlockSizeBytes() const
+ {
+ return BlockSizeBytes;
+ }
+
+ size_t AES_CBC_Cipher_OpenSSL::GetKeyLengthBits() const
+ {
+ return KeyLengthBits;
+ }
+
+ void AES_CBC_Cipher_OpenSSL::Reset()
+ {
+ OpenSSLCipher::Reset();
+ InitCipher();
+ }
+
+ size_t AES_CTR_Cipher_OpenSSL::BlockSizeBytes = 16;
+ size_t AES_CTR_Cipher_OpenSSL::KeyLengthBits = 256;
+ static const char* CTR_LOG_TAG = "AES_CTR_Cipher_OpenSSL";
+
+ AES_CTR_Cipher_OpenSSL::AES_CTR_Cipher_OpenSSL(const CryptoBuffer& key) : OpenSSLCipher(key, BlockSizeBytes,
+ true)
+ {
+ InitCipher();
+ }
+
+ AES_CTR_Cipher_OpenSSL::AES_CTR_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector) :
+ OpenSSLCipher(std::move(key), std::move(initializationVector))
+ {
+ InitCipher();
+ }
+
+ AES_CTR_Cipher_OpenSSL::AES_CTR_Cipher_OpenSSL(const CryptoBuffer& key,
+ const CryptoBuffer& initializationVector) :
+ OpenSSLCipher(key, initializationVector)
+ {
+ InitCipher();
+ }
+
+ void AES_CTR_Cipher_OpenSSL::InitCipher()
+ {
+ if (m_failure || !CheckKeyAndIVLength(KeyLengthBits/8, BlockSizeBytes))
+ {
+ return;
+ }
+
+ if (!(EVP_EncryptInit_ex(m_encryptor_ctx, EVP_aes_256_ctr(), nullptr, m_key.GetUnderlyingData(),
+ m_initializationVector.GetUnderlyingData())
+ && EVP_CIPHER_CTX_set_padding(m_encryptor_ctx, 0)) ||
+ !(EVP_DecryptInit_ex(m_decryptor_ctx, EVP_aes_256_ctr(), nullptr, m_key.GetUnderlyingData(),
+ m_initializationVector.GetUnderlyingData())
+ && EVP_CIPHER_CTX_set_padding(m_decryptor_ctx, 0)))
+ {
+ m_failure = true;
+ LogErrors(CTR_LOG_TAG);
+ }
+ }
+
+ size_t AES_CTR_Cipher_OpenSSL::GetBlockSizeBytes() const
+ {
+ return BlockSizeBytes;
+ }
+
+ size_t AES_CTR_Cipher_OpenSSL::GetKeyLengthBits() const
+ {
+ return KeyLengthBits;
+ }
+
+ void AES_CTR_Cipher_OpenSSL::Reset()
+ {
+ OpenSSLCipher::Reset();
+ InitCipher();
+ }
+
+ size_t AES_GCM_Cipher_OpenSSL::BlockSizeBytes = 16;
+ size_t AES_GCM_Cipher_OpenSSL::KeyLengthBits = 256;
+ size_t AES_GCM_Cipher_OpenSSL::IVLengthBytes = 12;
+ size_t AES_GCM_Cipher_OpenSSL::TagLengthBytes = 16;
+
+ static const char* GCM_LOG_TAG = "AES_GCM_Cipher_OpenSSL";
+
+ AES_GCM_Cipher_OpenSSL::AES_GCM_Cipher_OpenSSL(const CryptoBuffer& key)
+ : OpenSSLCipher(key, IVLengthBytes)
+ {
+ InitCipher();
+ }
+
+ AES_GCM_Cipher_OpenSSL::AES_GCM_Cipher_OpenSSL(const CryptoBuffer& key, const CryptoBuffer* aad)
+ : OpenSSLCipher(key, IVLengthBytes), m_aad(*aad)
+ {
+ InitCipher();
+ }
+
+ AES_GCM_Cipher_OpenSSL::AES_GCM_Cipher_OpenSSL(CryptoBuffer&& key, CryptoBuffer&& initializationVector,
+ CryptoBuffer&& tag, CryptoBuffer&& aad) :
+ OpenSSLCipher(std::move(key), std::move(initializationVector), std::move(tag)), m_aad(std::move(aad))
+ {
+ InitCipher();
+ }
+
+ AES_GCM_Cipher_OpenSSL::AES_GCM_Cipher_OpenSSL(const CryptoBuffer& key, const CryptoBuffer& initializationVector,
+ const CryptoBuffer& tag, const CryptoBuffer& aad) :
+ OpenSSLCipher(key, initializationVector, tag), m_aad(std::move(aad))
+ {
+ InitCipher();
+ }
+
+ CryptoBuffer AES_GCM_Cipher_OpenSSL::FinalizeEncryption()
+ {
+ if (m_failure)
+ {
+ AWS_LOGSTREAM_FATAL(GCM_LOG_TAG, "Cipher not properly initialized for encryption finalization. Aborting");
+ return CryptoBuffer();
+ }
+
+ int writtenSize = 0;
+ CryptoBuffer finalBlock(GetBlockSizeBytes());
+ EVP_EncryptFinal_ex(m_encryptor_ctx, finalBlock.GetUnderlyingData(), &writtenSize);
+
+ m_tag = CryptoBuffer(TagLengthBytes);
+ if (!EVP_CIPHER_CTX_ctrl(m_encryptor_ctx, EVP_CTRL_GCM_GET_TAG, static_cast<int>(m_tag.GetLength()),
+ m_tag.GetUnderlyingData()))
+ {
+ m_failure = true;
+ LogErrors(GCM_LOG_TAG);
+ }
+
+ return CryptoBuffer();
+ }
+
+ void AES_GCM_Cipher_OpenSSL::InitCipher()
+ {
+ if (m_failure || !CheckKeyAndIVLength(KeyLengthBits/8, IVLengthBytes))
+ {
+ return;
+ }
+
+ if (!(EVP_EncryptInit_ex(m_encryptor_ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr) &&
+ EVP_EncryptInit_ex(m_encryptor_ctx, nullptr, nullptr, m_key.GetUnderlyingData(),
+ m_initializationVector.GetUnderlyingData()) &&
+ EVP_CIPHER_CTX_set_padding(m_encryptor_ctx, 0)) ||
+ !(EVP_DecryptInit_ex(m_decryptor_ctx, EVP_aes_256_gcm(), nullptr, nullptr, nullptr) &&
+ EVP_DecryptInit_ex(m_decryptor_ctx, nullptr, nullptr, m_key.GetUnderlyingData(),
+ m_initializationVector.GetUnderlyingData()) &&
+ EVP_CIPHER_CTX_set_padding(m_decryptor_ctx, 0)))
+ {
+ m_failure = true;
+ LogErrors(GCM_LOG_TAG);
+ return;
+ }
+
+ if (m_aad.GetLength() > 0)
+ {
+ int outLen = 0;
+ if(!EVP_EncryptUpdate(m_encryptor_ctx, nullptr, &outLen, m_aad.GetUnderlyingData(), m_aad.GetLength())
+ || !EVP_DecryptUpdate(m_decryptor_ctx, nullptr, &outLen, m_aad.GetUnderlyingData(), m_aad.GetLength()))
+ {
+ m_failure = true;
+ LogErrors(GCM_LOG_TAG);
+ return;
+ }
+ }
+
+ //tag should always be set in GCM decrypt mode
+ if (m_tag.GetLength() > 0)
+ {
+ if (m_tag.GetLength() < TagLengthBytes)
+ {
+ AWS_LOGSTREAM_ERROR(GCM_LOG_TAG, "Illegal attempt to decrypt an AES GCM payload without a valid tag set: tag length=" << m_tag.GetLength());
+ m_failure = true;
+ return;
+ }
+
+ if (!EVP_CIPHER_CTX_ctrl(m_decryptor_ctx, EVP_CTRL_GCM_SET_TAG, static_cast<int>(m_tag.GetLength()), m_tag.GetUnderlyingData()))
+ {
+ m_failure = true;
+ LogErrors(GCM_LOG_TAG);
+ }
+ }
+ }
+
+ size_t AES_GCM_Cipher_OpenSSL::GetBlockSizeBytes() const
+ {
+ return BlockSizeBytes;
+ }
+
+ size_t AES_GCM_Cipher_OpenSSL::GetKeyLengthBits() const
+ {
+ return KeyLengthBits;
+ }
+
+ size_t AES_GCM_Cipher_OpenSSL::GetTagLengthBytes() const
+ {
+ return TagLengthBytes;
+ }
+
+ void AES_GCM_Cipher_OpenSSL::Reset()
+ {
+ OpenSSLCipher::Reset();
+ InitCipher();
+ }
+
+ size_t AES_KeyWrap_Cipher_OpenSSL::KeyLengthBits = 256;
+ size_t AES_KeyWrap_Cipher_OpenSSL::BlockSizeBytes = 8;
+ static const unsigned char INTEGRITY_VALUE = 0xA6;
+ static const size_t MIN_CEK_LENGTH_BYTES = 128 / 8;
+
+ static const char* KEY_WRAP_TAG = "AES_KeyWrap_Cipher_OpenSSL";
+
+ AES_KeyWrap_Cipher_OpenSSL::AES_KeyWrap_Cipher_OpenSSL(const CryptoBuffer& key) : OpenSSLCipher(key, 0)
+ {
+ InitCipher();
+ }
+
+ CryptoBuffer AES_KeyWrap_Cipher_OpenSSL::EncryptBuffer(const CryptoBuffer& plainText)
+ {
+ if (!m_failure)
+ {
+ m_workingKeyBuffer = CryptoBuffer({&m_workingKeyBuffer, (CryptoBuffer*) &plainText});
+ }
+ return CryptoBuffer();
+ }
+
+ CryptoBuffer AES_KeyWrap_Cipher_OpenSSL::FinalizeEncryption()
+ {
+ if (m_failure)
+ {
+ AWS_LOGSTREAM_FATAL(KEY_WRAP_TAG, "Cipher not properly initialized for encryption finalization. Aborting");
+ return CryptoBuffer();
+ }
+
+ if (m_workingKeyBuffer.GetLength() < MIN_CEK_LENGTH_BYTES)
+ {
+ AWS_LOGSTREAM_ERROR(KEY_WRAP_TAG, "Incorrect input length of " << m_workingKeyBuffer.GetLength());
+ m_failure = true;
+ return CryptoBuffer();
+ }
+
+ //the following is an in place implementation of
+ //RFC 3394 using the alternate in-place implementation.
+ //we use one in-place buffer instead of the copy at the end.
+ //the one letter variable names are meant to directly reflect the variables in the RFC
+ CryptoBuffer cipherText(m_workingKeyBuffer.GetLength() + BlockSizeBytes);
+
+ //put the integrity check register in the first 8 bytes of the final buffer.
+ memset(cipherText.GetUnderlyingData(), INTEGRITY_VALUE, BlockSizeBytes);
+ unsigned char* a = cipherText.GetUnderlyingData();
+
+ //put the register buffer after the integrity check register
+ memcpy(cipherText.GetUnderlyingData() + BlockSizeBytes, m_workingKeyBuffer.GetUnderlyingData(),
+ m_workingKeyBuffer.GetLength());
+ unsigned char* r = cipherText.GetUnderlyingData() + BlockSizeBytes;
+
+ int n = static_cast<int>(m_workingKeyBuffer.GetLength() / BlockSizeBytes);
+
+ //temporary encryption buffer
+ CryptoBuffer b(BlockSizeBytes * 2);
+ int outLen = static_cast<int>(b.GetLength());
+
+ //concatenation buffer
+ CryptoBuffer tempInput(BlockSizeBytes * 2);
+
+ for (int j = 0; j <= 5; ++j)
+ {
+ for (int i = 1; i <= n; ++i)
+ {
+ //concat A and R[i], A should be most significant and then R[i] should be least significant.
+ memcpy(tempInput.GetUnderlyingData(), a, BlockSizeBytes);
+ memcpy(tempInput.GetUnderlyingData() + BlockSizeBytes, r, BlockSizeBytes);
+
+ //encrypt the concatenated A and R[I] and store it in B
+ if (!EVP_EncryptUpdate(m_encryptor_ctx, b.GetUnderlyingData(), &outLen,
+ tempInput.GetUnderlyingData(), static_cast<int>(tempInput.GetLength())))
+ {
+ LogErrors(KEY_WRAP_TAG);
+ m_failure = true;
+ return CryptoBuffer();
+ }
+
+ unsigned char t = static_cast<unsigned char>((n * j) + i);
+ //put the 64 MSB ^ T into A
+ memcpy(a, b.GetUnderlyingData(), BlockSizeBytes);
+ a[7] ^= t;
+ //put the 64 LSB into R[i]
+ memcpy(r, b.GetUnderlyingData() + BlockSizeBytes, BlockSizeBytes);
+ //increment i -> R[i]
+ r += BlockSizeBytes;
+ }
+ //reset R
+ r = cipherText.GetUnderlyingData() + BlockSizeBytes;
+ }
+
+ return cipherText;
+ }
+
+ CryptoBuffer AES_KeyWrap_Cipher_OpenSSL::DecryptBuffer(const CryptoBuffer& cipherText)
+ {
+ if (!m_failure)
+ {
+ m_workingKeyBuffer = CryptoBuffer({&m_workingKeyBuffer, (CryptoBuffer*)&cipherText});
+ }
+ return CryptoBuffer();
+ }
+
+ CryptoBuffer AES_KeyWrap_Cipher_OpenSSL::FinalizeDecryption()
+ {
+ if (m_failure)
+ {
+ AWS_LOGSTREAM_FATAL(KEY_WRAP_TAG, "Cipher not properly initialized for decryption finalization. Aborting");
+ return CryptoBuffer();
+ }
+
+ if (m_workingKeyBuffer.GetLength() < MIN_CEK_LENGTH_BYTES + BlockSizeBytes)
+ {
+ AWS_LOGSTREAM_ERROR(KEY_WRAP_TAG, "Incorrect input length of " << m_workingKeyBuffer.GetLength());
+ m_failure = true;
+ return CryptoBuffer();
+ }
+
+ //the following is an in place implementation of
+ //RFC 3394 using the alternate in-place implementation.
+ //we use one in-place buffer instead of the copy at the end.
+ //the one letter variable names are meant to directly reflect the variables in the RFC
+ CryptoBuffer plainText(m_workingKeyBuffer.GetLength() - BlockSizeBytes);
+ memcpy(plainText.GetUnderlyingData(), m_workingKeyBuffer.GetUnderlyingData() + BlockSizeBytes, plainText.GetLength());
+
+ //integrity register should be the first 8 bytes of the cipher text
+ unsigned char* a = m_workingKeyBuffer.GetUnderlyingData();
+
+ //in-place register is the plaintext. For decryption, start at the last array position (8 bytes before the end);
+ unsigned char* r = plainText.GetUnderlyingData() + plainText.GetLength() - BlockSizeBytes;
+
+ int n = static_cast<int>(plainText.GetLength() / BlockSizeBytes);
+
+ //temporary encryption buffer
+ CryptoBuffer b(BlockSizeBytes * 10);
+ int outLen = static_cast<int>(b.GetLength());
+
+ //concatenation buffer
+ CryptoBuffer tempInput(BlockSizeBytes * 2);
+
+ for(int j = 5; j >= 0; --j)
+ {
+ for(int i = n; i >= 1; --i)
+ {
+ //concat
+ //A ^ t
+ memcpy(tempInput.GetUnderlyingData(), a, BlockSizeBytes);
+ unsigned char t = static_cast<unsigned char>((n * j) + i);
+ tempInput[7] ^= t;
+ //R[i]
+ memcpy(tempInput.GetUnderlyingData() + BlockSizeBytes, r, BlockSizeBytes);
+
+ //Decrypt the concatenated buffer
+ if(!EVP_DecryptUpdate(m_decryptor_ctx, b.GetUnderlyingData(), &outLen,
+ tempInput.GetUnderlyingData(), static_cast<int>(tempInput.GetLength())))
+ {
+ m_failure = true;
+ LogErrors(KEY_WRAP_TAG);
+ return CryptoBuffer();
+ }
+
+ //set A to MSB 64 bits of decrypted result
+ memcpy(a, b.GetUnderlyingData(), BlockSizeBytes);
+ //set R[i] to LSB 64 bits of decrypted result
+ memcpy(r, b.GetUnderlyingData() + BlockSizeBytes, BlockSizeBytes);
+ //decrement i -> R[i]
+ r -= BlockSizeBytes;
+ }
+
+ r = plainText.GetUnderlyingData() + plainText.GetLength() - BlockSizeBytes;
+ }
+
+ //here we perform the integrity check to make sure A == 0xA6A6A6A6A6A6A6A6
+ for(size_t i = 0; i < BlockSizeBytes; ++i)
+ {
+ if(a[i] != INTEGRITY_VALUE)
+ {
+ m_failure = true;
+ AWS_LOGSTREAM_ERROR(KEY_WRAP_TAG, "Integrity check failed for key wrap decryption.");
+ return CryptoBuffer();
+ }
+ }
+
+ return plainText;
+ }
+
+ void AES_KeyWrap_Cipher_OpenSSL::InitCipher()
+ {
+ if (m_failure || !CheckKeyAndIVLength(KeyLengthBits/8, 0))
+ {
+ return;
+ }
+
+ if (!(EVP_EncryptInit_ex(m_encryptor_ctx, EVP_aes_256_ecb(), nullptr, m_key.GetUnderlyingData(), nullptr) &&
+ EVP_CIPHER_CTX_set_padding(m_encryptor_ctx, 0)) ||
+ !(EVP_DecryptInit_ex(m_decryptor_ctx, EVP_aes_256_ecb(), nullptr, m_key.GetUnderlyingData(), nullptr) &&
+ EVP_CIPHER_CTX_set_padding(m_decryptor_ctx, 0)))
+ {
+ m_failure = true;
+ LogErrors(KEY_WRAP_TAG);
+ }
+ }
+
+ void AES_KeyWrap_Cipher_OpenSSL::Reset()
+ {
+ m_workingKeyBuffer = CryptoBuffer();
+ OpenSSLCipher::Reset();
+ InitCipher();
+ }
+ }
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventDecoderStream.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventDecoderStream.cpp
new file mode 100644
index 0000000000..5ecd2d0444
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventDecoderStream.cpp
@@ -0,0 +1,22 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+#include <aws/core/utils/event/EventDecoderStream.h>
+#include <iostream>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Event
+ {
+ EventDecoderStream::EventDecoderStream(EventStreamDecoder& decoder, size_t bufferSize) :
+ Aws::IOStream(&m_eventStreamBuf),
+ m_eventStreamBuf(decoder, bufferSize)
+
+ {
+ }
+ }
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventEncoderStream.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventEncoderStream.cpp
new file mode 100644
index 0000000000..f8640f0e8c
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventEncoderStream.cpp
@@ -0,0 +1,28 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+#include <aws/core/utils/event/EventEncoderStream.h>
+#include <iostream>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Event
+ {
+ EventEncoderStream::EventEncoderStream(size_t bufferSize) :
+ Aws::IOStream(&m_streambuf),
+ m_streambuf(bufferSize)
+ {
+ }
+
+ EventEncoderStream& EventEncoderStream::WriteEvent(const Aws::Utils::Event::Message& msg)
+ {
+ auto bits = m_encoder.EncodeAndSign(msg);
+ write(reinterpret_cast<char*>(bits.data()), bits.size());
+ return *this;
+ }
+ }
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventHeader.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventHeader.cpp
new file mode 100644
index 0000000000..c3c989bedb
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventHeader.cpp
@@ -0,0 +1,107 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/event/EventHeader.h>
+#include <aws/core/utils/HashingUtils.h>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Event
+ {
+ static const int HASH_BOOL_TRUE = HashingUtils::HashString("BOOL_TRUE");
+ static const int HASH_BOOL_FALSE = HashingUtils::HashString("BOOL_FALSE");
+ static const int HASH_BYTE = HashingUtils::HashString("BYTE");
+ static const int HASH_INT16 = HashingUtils::HashString("INT16");
+ static const int HASH_INT32 = HashingUtils::HashString("INT32");
+ static const int HASH_INT64 = HashingUtils::HashString("INT64");
+ static const int HASH_BYTE_BUF = HashingUtils::HashString("BYTE_BUFFER");
+ static const int HASH_STRING = HashingUtils::HashString("STRING");
+ static const int HASH_TIMESTAMP = HashingUtils::HashString("TIMESTAMP");
+ static const int HASH_UUID = HashingUtils::HashString("UUID");
+
+ EventHeaderValue::EventHeaderType EventHeaderValue::GetEventHeaderTypeForName(const Aws::String& name)
+ {
+ int hashCode = Aws::Utils::HashingUtils::HashString(name.c_str());
+ if (hashCode == HASH_BOOL_TRUE)
+ {
+ return EventHeaderType::BOOL_TRUE;
+ }
+ else if (hashCode == HASH_BOOL_FALSE)
+ {
+ return EventHeaderType::BOOL_FALSE;
+ }
+ else if (hashCode == HASH_BYTE)
+ {
+ return EventHeaderType::BYTE;
+ }
+ else if (hashCode == HASH_INT16)
+ {
+ return EventHeaderType::INT16;
+ }
+ else if (hashCode == HASH_INT32)
+ {
+ return EventHeaderType::INT32;
+ }
+ else if (hashCode == HASH_INT64)
+ {
+ return EventHeaderType::INT64;
+ }
+ else if (hashCode == HASH_BYTE_BUF)
+ {
+ return EventHeaderType::BYTE_BUF;
+ }
+ else if (hashCode == HASH_STRING)
+ {
+ return EventHeaderType::STRING;
+ }
+ else if (hashCode == HASH_TIMESTAMP)
+ {
+ return EventHeaderType::TIMESTAMP;
+ }
+ else if (hashCode == HASH_UUID)
+ {
+ return EventHeaderType::UUID;
+ }
+ else
+ {
+ return EventHeaderType::UNKNOWN;
+ }
+ }
+
+ Aws::String EventHeaderValue::GetNameForEventHeaderType(EventHeaderType value)
+ {
+ switch (value)
+ {
+ case EventHeaderType::BOOL_TRUE:
+ return "BOOL_TRUE";
+ case EventHeaderType::BOOL_FALSE:
+ return "BOOL_FALSE";
+ case EventHeaderType::BYTE:
+ return "BYTE";
+ case EventHeaderType::INT16:
+ return "INT16";
+ case EventHeaderType::INT32:
+ return "INT32";
+ case EventHeaderType::INT64:
+ return "INT64";
+ case EventHeaderType::BYTE_BUF:
+ return "BYTE_BUF";
+ case EventHeaderType::STRING:
+ return "STRING";
+ case EventHeaderType::TIMESTAMP:
+ return "TIMESTAMP";
+ case EventHeaderType::UUID:
+ return "UUID";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ }
+ }
+}
+
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventMessage.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventMessage.cpp
new file mode 100644
index 0000000000..de8b904775
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventMessage.cpp
@@ -0,0 +1,132 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/event/EventMessage.h>
+#include <aws/core/utils/HashingUtils.h>
+#include <algorithm>
+#include <iterator>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Event
+ {
+ const char EVENT_TYPE_HEADER[] = ":event-type";
+ const char CONTENT_TYPE_HEADER[] = ":content-type";
+ const char MESSAGE_TYPE_HEADER[] = ":message-type";
+ const char ERROR_CODE_HEADER[] = ":error-code";
+ const char ERROR_MESSAGE_HEADER[] = ":error-message";
+ const char EXCEPTION_TYPE_HEADER[] = ":exception-type";
+
+ static const int EVENT_HASH = HashingUtils::HashString("event");
+ static const int ERROR_HASH = HashingUtils::HashString("error");
+ static const int EXCEPTION_HASH = HashingUtils::HashString("exception");
+
+ static const int CONTENT_TYPE_APPLICATION_OCTET_STREAM_HASH = HashingUtils::HashString("application/octet-stream");
+ static const int CONTENT_TYPE_APPLICATION_JSON_HASH = HashingUtils::HashString("application/json");
+ static const int CONTENT_TYPE_TEXT_PLAIN_HASH = HashingUtils::HashString("text/plain");
+
+ Message::MessageType Message::GetMessageTypeForName(const Aws::String& name)
+ {
+ int hashCode = Aws::Utils::HashingUtils::HashString(name.c_str());
+ if (hashCode == EVENT_HASH)
+ {
+ return MessageType::EVENT;
+ }
+ else if (hashCode == ERROR_HASH)
+ {
+ return MessageType::REQUEST_LEVEL_ERROR;
+ }
+ else if (hashCode == EXCEPTION_HASH)
+ {
+ return MessageType::REQUEST_LEVEL_EXCEPTION;
+ }
+ else
+ {
+ return MessageType::UNKNOWN;
+ }
+ }
+
+ Aws::String Message::GetNameForMessageType(MessageType value)
+ {
+ switch (value)
+ {
+ case MessageType::EVENT:
+ return "event";
+ case MessageType::REQUEST_LEVEL_ERROR:
+ return "error";
+ case MessageType::REQUEST_LEVEL_EXCEPTION:
+ return "exception";
+ default:
+ return "unknown";
+ }
+ }
+
+ Message::ContentType Message::GetContentTypeForName(const Aws::String& name)
+ {
+ int hashCode = Aws::Utils::HashingUtils::HashString(name.c_str());
+ if (hashCode == CONTENT_TYPE_APPLICATION_OCTET_STREAM_HASH)
+ {
+ return ContentType::APPLICATION_OCTET_STREAM;
+ }
+ else if (hashCode == CONTENT_TYPE_APPLICATION_JSON_HASH)
+ {
+ return ContentType::APPLICATION_JSON;
+ }
+ else if (hashCode == CONTENT_TYPE_TEXT_PLAIN_HASH)
+ {
+ return ContentType::TEXT_PLAIN;
+ }
+ else
+ {
+ return ContentType::UNKNOWN;
+ }
+ }
+
+ Aws::String Message::GetNameForContentType(ContentType value)
+ {
+ switch (value)
+ {
+ case ContentType::APPLICATION_OCTET_STREAM:
+ return "application/octet-stream";
+ case ContentType::APPLICATION_JSON:
+ return "application/json";
+ case ContentType::TEXT_PLAIN:
+ return "text/plain";
+ default:
+ return "unknown";
+ }
+ }
+
+ void Message::Reset()
+ {
+ m_totalLength = 0;
+ m_headersLength = 0;
+ m_payloadLength = 0;
+
+ m_eventHeaders.clear();
+ m_eventPayload.clear();
+ }
+
+ void Message::WriteEventPayload(const unsigned char* data, size_t length)
+ {
+ std::copy(data, data + length, std::back_inserter(m_eventPayload));
+ }
+
+ void Message::WriteEventPayload(const Aws::Vector<unsigned char>& bits)
+ {
+ std::copy(bits.cbegin(), bits.cend(), std::back_inserter(m_eventPayload));
+ }
+
+ void Message::WriteEventPayload(const Aws::String& bits)
+ {
+ std::copy(bits.cbegin(), bits.cend(), std::back_inserter(m_eventPayload));
+ }
+
+ } // namespace Event
+ } // namespace Utils
+} // namespace Aws
+
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamBuf.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamBuf.cpp
new file mode 100644
index 0000000000..6a1766bb9f
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamBuf.cpp
@@ -0,0 +1,147 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+#include <aws/core/utils/event/EventStreamBuf.h>
+#include <cassert>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Event
+ {
+ const size_t DEFAULT_BUF_SIZE = 1024;
+
+ EventStreamBuf::EventStreamBuf(EventStreamDecoder& decoder, size_t bufferLength) :
+ m_byteBuffer(bufferLength),
+ m_bufferLength(bufferLength),
+ m_decoder(decoder)
+ {
+ assert(decoder);
+ char* begin = reinterpret_cast<char*>(m_byteBuffer.GetUnderlyingData());
+ char* end = begin + bufferLength - 1;
+
+ setp(begin, end);
+ setg(begin, begin, begin);
+ }
+
+ EventStreamBuf::~EventStreamBuf()
+ {
+ if (m_decoder)
+ {
+ writeToDecoder();
+ }
+ }
+
+ void EventStreamBuf::writeToDecoder()
+ {
+ if (pptr() > pbase())
+ {
+ size_t length = static_cast<size_t>(pptr() - pbase());
+ m_decoder.Pump(m_byteBuffer, length);
+
+ if (!m_decoder)
+ {
+ m_err.write(reinterpret_cast<char*>(m_byteBuffer.GetUnderlyingData()), length);
+ }
+ else
+ {
+ pbump(-static_cast<int>(length));
+ }
+ }
+ }
+
+ std::streampos EventStreamBuf::seekoff(std::streamoff off, std::ios_base::seekdir dir, std::ios_base::openmode which)
+ {
+ if (dir == std::ios_base::beg)
+ {
+ return seekpos(off, which);
+ }
+ else if (dir == std::ios_base::end)
+ {
+ return seekpos(m_bufferLength - 1 - off, which);
+ }
+ else if (dir == std::ios_base::cur)
+ {
+ if (which == std::ios_base::in)
+ {
+ return seekpos((gptr() - (char*)m_byteBuffer.GetUnderlyingData()) + off, which);
+ }
+ if (which == std::ios_base::out)
+ {
+ return seekpos((pptr() - (char*)m_byteBuffer.GetUnderlyingData()) + off, which);
+ }
+ }
+
+ return std::streamoff(-1);
+ }
+
+ std::streampos EventStreamBuf::seekpos(std::streampos pos, std::ios_base::openmode which)
+ {
+ assert(static_cast<size_t>(pos) <= m_bufferLength);
+ if (static_cast<size_t>(pos) > m_bufferLength)
+ {
+ return std::streampos(std::streamoff(-1));
+ }
+
+ if (which == std::ios_base::in)
+ {
+ m_err.seekg(pos);
+ return m_err.tellg();
+ }
+
+ if (which == std::ios_base::out)
+ {
+ return pos;
+ }
+
+ return std::streampos(std::streamoff(-1));
+ }
+
+ int EventStreamBuf::underflow()
+ {
+ if (!m_err || m_err.eof() || m_decoder)
+ {
+ return std::char_traits<char>::eof();
+ }
+
+ m_err.flush();
+ m_err.read(reinterpret_cast<char*>(m_byteBuffer.GetUnderlyingData()), m_byteBuffer.GetLength());
+
+ char* begin = reinterpret_cast<char*>(m_byteBuffer.GetUnderlyingData());
+ setg(begin, begin, begin + m_err.gcount());
+ return std::char_traits<char>::to_int_type(*gptr());
+ }
+
+ int EventStreamBuf::overflow(int ch)
+ {
+ auto eof = std::char_traits<char>::eof();
+
+ if (m_decoder)
+ {
+ if (ch != eof)
+ {
+ *pptr() = (char)ch;
+ pbump(1);
+ }
+
+ writeToDecoder();
+ return ch;
+ }
+
+ return eof;
+ }
+
+ int EventStreamBuf::sync()
+ {
+ if (m_decoder)
+ {
+ writeToDecoder();
+ }
+
+ return 0;
+ }
+ }
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamDecoder.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamDecoder.cpp
new file mode 100644
index 0000000000..f70a6c88f6
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamDecoder.cpp
@@ -0,0 +1,170 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/common/common.h>
+#include <aws/core/utils/event/EventHeader.h>
+#include <aws/core/utils/event/EventMessage.h>
+#include <aws/core/utils/event/EventStreamDecoder.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <aws/core/utils/UnreferencedParam.h>
+#include <aws/core/utils/memory/AWSMemory.h>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Event
+ {
+ static const char EVENT_STREAM_DECODER_CLASS_TAG[] = "Aws::Utils::Event::EventStreamDecoder";
+
+ EventStreamDecoder::EventStreamDecoder(EventStreamHandler* handler) : m_eventStreamHandler(handler)
+ {
+ aws_event_stream_streaming_decoder_init(&m_decoder,
+ get_aws_allocator(),
+ onPayloadSegment,
+ onPreludeReceived,
+ onHeaderReceived,
+ onError,
+ (void*)handler);
+ }
+
+ EventStreamDecoder::~EventStreamDecoder()
+ {
+ aws_event_stream_streaming_decoder_clean_up(&m_decoder);
+ }
+
+ void EventStreamDecoder::Pump(const ByteBuffer& data)
+ {
+ Pump(data, data.GetLength());
+ }
+
+ void EventStreamDecoder::Pump(const ByteBuffer& data, size_t length)
+ {
+ aws_byte_buf dataBuf = aws_byte_buf_from_array(static_cast<uint8_t*>(data.GetUnderlyingData()), length);
+ aws_event_stream_streaming_decoder_pump(&m_decoder, &dataBuf);
+ }
+
+ void EventStreamDecoder::Reset()
+ {
+ m_eventStreamHandler->Reset();
+ }
+
+ void EventStreamDecoder::ResetEventStreamHandler(EventStreamHandler* handler)
+ {
+ aws_event_stream_streaming_decoder_init(&m_decoder, get_aws_allocator(),
+ onPayloadSegment,
+ onPreludeReceived,
+ onHeaderReceived,
+ onError,
+ reinterpret_cast<void *>(handler));
+ }
+
+ void EventStreamDecoder::onPayloadSegment(
+ aws_event_stream_streaming_decoder* decoder,
+ aws_byte_buf* payload,
+ int8_t isFinalSegment,
+ void* context)
+ {
+ AWS_UNREFERENCED_PARAM(decoder);
+ auto handler = static_cast<EventStreamHandler*>(context);
+ assert(handler);
+ if (!handler)
+ {
+ AWS_LOGSTREAM_ERROR(EVENT_STREAM_DECODER_CLASS_TAG, "Payload received, but decoder encountered internal errors before."
+ "ErrorCode: " << EventStreamErrorsMapper::GetNameForError(handler->GetInternalError()) << ", "
+ "ErrorMessage: " << handler->GetEventPayloadAsString());
+ return;
+ }
+ handler->WriteMessageEventPayload(static_cast<unsigned char*>(payload->buffer), payload->len);
+
+ // Complete payload received
+ if (isFinalSegment == 1)
+ {
+ assert(handler->IsMessageCompleted());
+ handler->OnEvent();
+ handler->Reset();
+ }
+ }
+
+ void EventStreamDecoder::onPreludeReceived(
+ aws_event_stream_streaming_decoder* decoder,
+ aws_event_stream_message_prelude* prelude,
+ void* context)
+ {
+ AWS_UNREFERENCED_PARAM(decoder);
+ auto handler = static_cast<EventStreamHandler*>(context);
+ handler->Reset();
+
+ //Encounter internal error in prelude received.
+ //This error will be handled by OnError callback function later.
+ if (prelude->total_len < prelude->headers_len + 16)
+ {
+ return;
+ }
+ handler->SetMessageMetadata(prelude->total_len, prelude->headers_len,
+ prelude->total_len - prelude->headers_len - 4/*total byte-length*/ - 4/*headers byte-length*/ - 4/*prelude crc*/ - 4/*message crc*/);
+ AWS_LOGSTREAM_TRACE(EVENT_STREAM_DECODER_CLASS_TAG, "Message received, the expected length of the message is: " << prelude->total_len <<
+ " bytes, and the expected length of the header is: " << prelude->headers_len << " bytes");
+
+ //Handle empty message
+ //if (handler->m_message.GetHeadersLength() == 0 && handler->m_message.GetPayloadLength() == 0)
+ if (handler->IsMessageCompleted())
+ {
+ handler->OnEvent();
+ handler->Reset();
+ }
+ }
+
+ void EventStreamDecoder::onHeaderReceived(
+ aws_event_stream_streaming_decoder* decoder,
+ aws_event_stream_message_prelude* prelude,
+ aws_event_stream_header_value_pair* header,
+ void* context)
+ {
+ AWS_UNREFERENCED_PARAM(decoder);
+ AWS_UNREFERENCED_PARAM(prelude);
+ auto handler = static_cast<EventStreamHandler*>(context);
+ assert(handler);
+ if (!handler)
+ {
+ AWS_LOGSTREAM_ERROR(EVENT_STREAM_DECODER_CLASS_TAG, "Payload received, but decoder encountered internal errors before."
+ "ErrorCode: " << EventStreamErrorsMapper::GetNameForError(handler->GetInternalError()) << ", "
+ "ErrorMessage: " << handler->GetEventPayloadAsString());
+ return;
+ }
+
+ // The length of a header = 1 byte (to represent the length of header name) + length of header name + 1 byte (to represent header type)
+ // + 2 bytes (to represent length of header value) + length of header value
+ handler->InsertMessageEventHeader(Aws::String(header->header_name, header->header_name_len),
+ 1 + header->header_name_len + 1 + 2 + header->header_value_len, EventHeaderValue(header));
+
+ // Handle messages only have headers, but without payload.
+ //if (handler->m_message.GetHeadersLength() == handler->m_headersBytesReceived() && handler->m_message.GetPayloadLength() == 0)
+ if (handler->IsMessageCompleted())
+ {
+ handler->OnEvent();
+ handler->Reset();
+ }
+ }
+
+ void EventStreamDecoder::onError(
+ aws_event_stream_streaming_decoder* decoder,
+ aws_event_stream_message_prelude* prelude,
+ int error_code,
+ const char* message,
+ void* context)
+ {
+ AWS_UNREFERENCED_PARAM(decoder);
+ AWS_UNREFERENCED_PARAM(prelude);
+ auto handler = static_cast<EventStreamHandler*>(context);
+ handler->SetFailure();
+ handler->SetInternalError(error_code);
+ handler->WriteMessageEventPayload(reinterpret_cast<const unsigned char*>(message), strlen(message));
+ handler->OnEvent();
+ }
+ } // namespace Event
+ } // namespace Utils
+} // namespace Aws
+
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamEncoder.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamEncoder.cpp
new file mode 100644
index 0000000000..ef7104e839
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamEncoder.cpp
@@ -0,0 +1,162 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/event/EventHeader.h>
+#include <aws/core/utils/event/EventMessage.h>
+#include <aws/core/utils/event/EventStreamEncoder.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <aws/core/auth/AWSAuthSigner.h>
+#include <aws/common/byte_order.h>
+#include <aws/core/utils/memory/AWSMemory.h>
+
+#include <cassert>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Event
+ {
+ static const char TAG[] = "EventStreamEncoder";
+
+ static void EncodeHeaders(const Aws::Utils::Event::Message& msg, aws_array_list* headers)
+ {
+ aws_array_list_init_dynamic(headers, get_aws_allocator(), msg.GetEventHeaders().size(), sizeof(aws_event_stream_header_value_pair));
+ for (auto&& header : msg.GetEventHeaders())
+ {
+ const uint8_t headerKeyLen = static_cast<uint8_t>(header.first.length());
+ switch(header.second.GetType())
+ {
+ case EventHeaderValue::EventHeaderType::BOOL_TRUE:
+ case EventHeaderValue::EventHeaderType::BOOL_FALSE:
+ aws_event_stream_add_bool_header(headers, header.first.c_str(), headerKeyLen, header.second.GetEventHeaderValueAsBoolean());
+ break;
+ case EventHeaderValue::EventHeaderType::BYTE:
+ aws_event_stream_add_bool_header(headers, header.first.c_str(), headerKeyLen, header.second.GetEventHeaderValueAsByte());
+ break;
+ case EventHeaderValue::EventHeaderType::INT16:
+ aws_event_stream_add_int16_header(headers, header.first.c_str(), headerKeyLen, header.second.GetEventHeaderValueAsInt16());
+ break;
+ case EventHeaderValue::EventHeaderType::INT32:
+ aws_event_stream_add_int32_header(headers, header.first.c_str(), headerKeyLen, header.second.GetEventHeaderValueAsInt32());
+ break;
+ case EventHeaderValue::EventHeaderType::INT64:
+ aws_event_stream_add_int64_header(headers, header.first.c_str(), headerKeyLen, header.second.GetEventHeaderValueAsInt64());
+ break;
+ case EventHeaderValue::EventHeaderType::BYTE_BUF:
+ {
+ const auto& bytes = header.second.GetEventHeaderValueAsBytebuf();
+ aws_event_stream_add_bytebuf_header(headers, header.first.c_str(), headerKeyLen, bytes.GetUnderlyingData(), static_cast<uint16_t>(bytes.GetLength()), 1 /*copy*/);
+ }
+ break;
+ case EventHeaderValue::EventHeaderType::STRING:
+ {
+ const auto& bytes = header.second.GetUnderlyingBuffer();
+ aws_event_stream_add_string_header(headers, header.first.c_str(), headerKeyLen, reinterpret_cast<char*>(bytes.GetUnderlyingData()), static_cast<uint16_t>(bytes.GetLength()), 0 /*copy*/);
+ }
+ break;
+ case EventHeaderValue::EventHeaderType::TIMESTAMP:
+ aws_event_stream_add_timestamp_header(headers, header.first.c_str(), headerKeyLen, header.second.GetEventHeaderValueAsTimestamp());
+ break;
+ case EventHeaderValue::EventHeaderType::UUID:
+ {
+ ByteBuffer uuidBytes = header.second.GetEventHeaderValueAsUuid();
+ aws_event_stream_add_uuid_header(headers, header.first.c_str(), headerKeyLen, uuidBytes.GetUnderlyingData());
+ }
+ break;
+ default:
+ AWS_LOG_ERROR(TAG, "Encountered unknown type of header.");
+ break;
+ }
+ }
+ }
+
+ EventStreamEncoder::EventStreamEncoder(Client::AWSAuthSigner* signer) : m_signer(signer)
+ {
+ }
+
+
+ Aws::Vector<unsigned char> EventStreamEncoder::EncodeAndSign(const Aws::Utils::Event::Message& msg)
+ {
+ aws_event_stream_message encoded = Encode(msg);
+ aws_event_stream_message signedMessage = Sign(&encoded);
+
+ const auto signedMessageLength = signedMessage.message_buffer ? aws_event_stream_message_total_length(&signedMessage) : 0;
+
+ Aws::Vector<unsigned char> outputBits(signedMessage.message_buffer, signedMessage.message_buffer + signedMessageLength);
+ aws_event_stream_message_clean_up(&encoded);
+ aws_event_stream_message_clean_up(&signedMessage);
+ return outputBits;
+ }
+
+ aws_event_stream_message EventStreamEncoder::Encode(const Aws::Utils::Event::Message& msg)
+ {
+ aws_array_list headers;
+ EncodeHeaders(msg, &headers);
+
+ aws_byte_buf payload;
+ payload.len = msg.GetEventPayload().size();
+ // this const_cast is OK because aws_byte_buf will only be "read from" by the following functions.
+ payload.buffer = const_cast<uint8_t*>(msg.GetEventPayload().data());
+ payload.capacity = 0;
+ payload.allocator = nullptr;
+
+ aws_event_stream_message encoded;
+ if(aws_event_stream_message_init(&encoded, get_aws_allocator(), &headers, &payload) == AWS_OP_ERR)
+ {
+ AWS_LOGSTREAM_ERROR(TAG, "Error creating event-stream message from payload.");
+ aws_event_stream_headers_list_cleanup(&headers);
+ // GCC 4.9.4 issues a warning with -Wextra if we simply do
+ // return {};
+ aws_event_stream_message empty{nullptr, nullptr, 0};
+ return empty;
+ }
+ aws_event_stream_headers_list_cleanup(&headers);
+ return encoded;
+ }
+
+ aws_event_stream_message EventStreamEncoder::Sign(aws_event_stream_message* msg)
+ {
+ const auto msglen = msg->message_buffer ? aws_event_stream_message_total_length(msg) : 0;
+ Event::Message signedMessage;
+ signedMessage.WriteEventPayload(msg->message_buffer, msglen);
+
+ assert(m_signer);
+ if (!m_signer->SignEventMessage(signedMessage, m_signatureSeed))
+ {
+ AWS_LOGSTREAM_ERROR(TAG, "Failed to sign event message frame.");
+ // GCC 4.9.4 issues a warning with -Wextra if we simply do
+ // return {};
+ aws_event_stream_message empty{nullptr, nullptr, 0};
+ return empty;
+ }
+
+ aws_array_list headers;
+ EncodeHeaders(signedMessage, &headers);
+
+ aws_byte_buf payload;
+ payload.len = signedMessage.GetEventPayload().size();
+ payload.buffer = signedMessage.GetEventPayload().data();
+ payload.capacity = 0;
+ payload.allocator = nullptr;
+
+ aws_event_stream_message signedmsg;
+ if(aws_event_stream_message_init(&signedmsg, get_aws_allocator(), &headers, &payload))
+ {
+ AWS_LOGSTREAM_ERROR(TAG, "Error creating event-stream message from payload.");
+ aws_event_stream_headers_list_cleanup(&headers);
+ // GCC 4.9.4 issues a warning with -Wextra if we simply do
+ // return {};
+ aws_event_stream_message empty{nullptr, nullptr, 0};
+ return empty;
+ }
+ aws_event_stream_headers_list_cleanup(&headers);
+ return signedmsg;
+ }
+
+ } // namespace Event
+ } // namespace Utils
+} // namespace Aws
+
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamErrors.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamErrors.cpp
new file mode 100644
index 0000000000..836d0b47c5
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/event/EventStreamErrors.cpp
@@ -0,0 +1,66 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+#include <aws/core/client/AWSError.h>
+#include <aws/core/utils/HashingUtils.h>
+#include <aws/core/utils/event/EventStreamErrors.h>
+
+ using namespace Aws::Client;
+// using namespace Aws::S3;
+// using namespace Aws::Utils;
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Event
+ {
+ namespace EventStreamErrorsMapper
+ {
+ /*
+ static const int EVENT_STREAM_NO_ERROR_HASH = HashingUtils::HashString("EventStreamNoError");
+ static const int EVENT_STREAM_BUFFER_LENGTH_MISMATCH_HASH = HashingUtils::HashString("EventStreamBufferLengthMismatch");
+ static const int EVENT_STREAM_INSUFFICIENT_BUFFER_LEN_HASH = HashingUtils::HashString("EventStreamInsufficientBufferLen");
+ static const int EVENT_STREAM_MESSAGE_FIELD_SIZE_EXCEEDED_HASH = HashingUtils::HashString("EventStreamMessageFieldSizeExceeded");
+ static const int EVENT_STREAM_PRELUDE_CHECKSUM_FAILURE_HASH = HashingUtils::HashString("EventStreamPreludeChecksumFailure");
+ static const int EVENT_STREAM_MESSAGE_CHECKSUM_FAILURE_HASH = HashingUtils::HashString("EventStreamMessageChecksumFailure");
+ static const int EVENT_STREAM_MESSAGE_INVALID_HEADERS_LEN_HASH = HashingUtils::HashString("EventStreamMessageInvalidHeadersLen");
+ static const int EVENT_STREAM_MESSAGE_UNKNOWN_HEADER_TYPE_HASH = HashingUtils::HashString("EventStreamMessageUnknownHeaderType");
+ static const int EVENT_STREAM_MESSAGE_PARSER_ILLEGAL_STATE_HASH = HashingUtils::HashString("EventStreamMessageParserIllegalState");
+ */
+ const char* GetNameForError(EventStreamErrors error)
+ {
+ switch (error)
+ {
+ case EventStreamErrors::EVENT_STREAM_NO_ERROR:
+ return "EventStreamNoError";
+ case EventStreamErrors::EVENT_STREAM_BUFFER_LENGTH_MISMATCH:
+ return "EventStreamBufferLengthMismatch";
+ case EventStreamErrors::EVENT_STREAM_INSUFFICIENT_BUFFER_LEN:
+ return "EventStreamInsufficientBufferLen";
+ case EventStreamErrors::EVENT_STREAM_MESSAGE_FIELD_SIZE_EXCEEDED:
+ return "EventStreamMessageFieldSizeExceeded";
+ case EventStreamErrors::EVENT_STREAM_PRELUDE_CHECKSUM_FAILURE:
+ return "EventStreamPreludeChecksumFailure";
+ case EventStreamErrors::EVENT_STREAM_MESSAGE_CHECKSUM_FAILURE:
+ return "EventStreamMessageChecksumFailure";
+ case EventStreamErrors::EVENT_STREAM_MESSAGE_INVALID_HEADERS_LEN:
+ return "EventStreamMessageInvalidHeadersLen";
+ case EventStreamErrors::EVENT_STREAM_MESSAGE_UNKNOWN_HEADER_TYPE:
+ return "EventStreamMessageUnknownHeaderType";
+ case EventStreamErrors::EVENT_STREAM_MESSAGE_PARSER_ILLEGAL_STATE:
+ return "EventStreamMessageParserIllegalState";
+ default:
+ return "EventStreamUnknownError";
+ }
+ }
+
+ AWSError<CoreErrors> GetAwsErrorForEventStreamError(EventStreamErrors error)
+ {
+ return AWSError<CoreErrors>(CoreErrors::UNKNOWN, GetNameForError(error), "", false);
+ }
+ } // namespace EventStreamErrorsMapper
+ } // namespace Event
+ } // namespace Utils
+} // namespace Aws
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp
new file mode 100644
index 0000000000..9b785d1995
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/json/JsonSerializer.cpp
@@ -0,0 +1,665 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/json/JsonSerializer.h>
+
+#include <iterator>
+#include <algorithm>
+#include <aws/core/utils/memory/stl/AWSStringStream.h>
+#include <aws/core/utils/StringUtils.h>
+
+using namespace Aws::Utils;
+using namespace Aws::Utils::Json;
+
+JsonValue::JsonValue() : m_wasParseSuccessful(true)
+{
+ m_value = nullptr;
+}
+
+JsonValue::JsonValue(cJSON* value) :
+ m_value(cJSON_Duplicate(value, true /* recurse */)),
+ m_wasParseSuccessful(true)
+{
+}
+
+JsonValue::JsonValue(const Aws::String& value) : m_wasParseSuccessful(true)
+{
+ const char* return_parse_end;
+ m_value = cJSON_ParseWithOpts(value.c_str(), &return_parse_end, 1/*require_null_terminated*/);
+
+ if (!m_value || cJSON_IsInvalid(m_value))
+ {
+ m_wasParseSuccessful = false;
+ m_errorMessage = "Failed to parse JSON at: ";
+ m_errorMessage += return_parse_end;
+ }
+}
+
+JsonValue::JsonValue(Aws::IStream& istream) : m_wasParseSuccessful(true)
+{
+ Aws::StringStream memoryStream;
+ std::copy(std::istreambuf_iterator<char>(istream), std::istreambuf_iterator<char>(), std::ostreambuf_iterator<char>(memoryStream));
+ const char* return_parse_end;
+ const auto input = memoryStream.str();
+ m_value = cJSON_ParseWithOpts(input.c_str(), &return_parse_end, 1/*require_null_terminated*/);
+
+ if (!m_value || cJSON_IsInvalid(m_value))
+ {
+ m_wasParseSuccessful = false;
+ m_errorMessage = "Failed to parse JSON. Invalid input at: ";
+ m_errorMessage += return_parse_end;
+ }
+}
+
+JsonValue::JsonValue(const JsonValue& value) :
+ m_value(cJSON_Duplicate(value.m_value, true/*recurse*/)),
+ m_wasParseSuccessful(value.m_wasParseSuccessful),
+ m_errorMessage(value.m_errorMessage)
+{
+}
+
+JsonValue::JsonValue(JsonValue&& value) :
+ m_value(value.m_value),
+ m_wasParseSuccessful(value.m_wasParseSuccessful),
+ m_errorMessage(std::move(value.m_errorMessage))
+{
+ value.m_value = nullptr;
+}
+
+void JsonValue::Destroy()
+{
+ cJSON_Delete(m_value);
+}
+
+JsonValue::~JsonValue()
+{
+ Destroy();
+}
+
+JsonValue& JsonValue::operator=(const JsonValue& other)
+{
+ if (this == &other)
+ {
+ return *this;
+ }
+
+ Destroy();
+ m_value = cJSON_Duplicate(other.m_value, true /*recurse*/);
+ m_wasParseSuccessful = other.m_wasParseSuccessful;
+ m_errorMessage = other.m_errorMessage;
+ return *this;
+}
+
+JsonValue& JsonValue::operator=(JsonValue&& other)
+{
+ if (this == &other)
+ {
+ return *this;
+ }
+
+ using std::swap;
+ swap(m_value, other.m_value);
+ swap(m_errorMessage, other.m_errorMessage);
+ m_wasParseSuccessful = other.m_wasParseSuccessful;
+ return *this;
+}
+
+static void AddOrReplace(cJSON* root, const char* key, cJSON* value)
+{
+ const auto existing = cJSON_GetObjectItemCaseSensitive(root, key);
+ if (existing)
+ {
+ cJSON_ReplaceItemInObjectCaseSensitive(root, key, value);
+ }
+ else
+ {
+ cJSON_AddItemToObject(root, key, value);
+ }
+}
+
+JsonValue& JsonValue::WithString(const char* key, const Aws::String& value)
+{
+ if (!m_value)
+ {
+ m_value = cJSON_CreateObject();
+ }
+
+ const auto val = cJSON_CreateString(value.c_str());
+ AddOrReplace(m_value, key, val);
+ return *this;
+}
+
+JsonValue& JsonValue::WithString(const Aws::String& key, const Aws::String& value)
+{
+ return WithString(key.c_str(), value);
+}
+
+JsonValue& JsonValue::AsString(const Aws::String& value)
+{
+ Destroy();
+ m_value = cJSON_CreateString(value.c_str());
+ return *this;
+}
+
+JsonValue& JsonValue::WithBool(const char* key, bool value)
+{
+ if (!m_value)
+ {
+ m_value = cJSON_CreateObject();
+ }
+
+ const auto val = cJSON_CreateBool(value);
+ AddOrReplace(m_value, key, val);
+ return *this;
+}
+
+JsonValue& JsonValue::WithBool(const Aws::String& key, bool value)
+{
+ return WithBool(key.c_str(), value);
+}
+
+JsonValue& JsonValue::AsBool(bool value)
+{
+ Destroy();
+ m_value = cJSON_CreateBool(value);
+ return *this;
+}
+
+JsonValue& JsonValue::WithInteger(const char* key, int value)
+{
+ return WithDouble(key, static_cast<double>(value));
+}
+
+JsonValue& JsonValue::WithInteger(const Aws::String& key, int value)
+{
+ return WithDouble(key.c_str(), static_cast<double>(value));
+}
+
+JsonValue& JsonValue::AsInteger(int value)
+{
+ Destroy();
+ m_value = cJSON_CreateNumber(static_cast<double>(value));
+ return *this;
+}
+
+JsonValue& JsonValue::WithInt64(const char* key, long long value)
+{
+ if (!m_value)
+ {
+ m_value = cJSON_CreateObject();
+ }
+
+ const auto val = cJSON_CreateInt64(value);
+ AddOrReplace(m_value, key, val);
+ return *this;
+}
+
+JsonValue& JsonValue::WithInt64(const Aws::String& key, long long value)
+{
+ return WithInt64(key.c_str(), value);
+}
+
+JsonValue& JsonValue::AsInt64(long long value)
+{
+ Destroy();
+ m_value = cJSON_CreateInt64(value);
+ return *this;
+}
+
+JsonValue& JsonValue::WithDouble(const char* key, double value)
+{
+ if (!m_value)
+ {
+ m_value = cJSON_CreateObject();
+ }
+
+ const auto val = cJSON_CreateNumber(value);
+ AddOrReplace(m_value, key, val);
+ return *this;
+}
+
+JsonValue& JsonValue::WithDouble(const Aws::String& key, double value)
+{
+ return WithDouble(key.c_str(), value);
+}
+
+JsonValue& JsonValue::AsDouble(double value)
+{
+ Destroy();
+ m_value = cJSON_CreateNumber(value);
+ return *this;
+}
+
+JsonValue& JsonValue::WithArray(const char* key, const Array<Aws::String>& array)
+{
+ if (!m_value)
+ {
+ m_value = cJSON_CreateObject();
+ }
+
+ auto arrayValue = cJSON_CreateArray();
+ for (unsigned i = 0; i < array.GetLength(); ++i)
+ {
+ cJSON_AddItemToArray(arrayValue, cJSON_CreateString(array[i].c_str()));
+ }
+
+ AddOrReplace(m_value, key, arrayValue);
+ return *this;
+}
+
+JsonValue& JsonValue::WithArray(const Aws::String& key, const Array<Aws::String>& array)
+{
+ return WithArray(key.c_str(), array);
+}
+
+JsonValue& JsonValue::WithArray(const Aws::String& key, const Array<JsonValue>& array)
+{
+ if (!m_value)
+ {
+ m_value = cJSON_CreateObject();
+ }
+
+ auto arrayValue = cJSON_CreateArray();
+ for (unsigned i = 0; i < array.GetLength(); ++i)
+ {
+ cJSON_AddItemToArray(arrayValue, cJSON_Duplicate(array[i].m_value, true /*recurse*/));
+ }
+
+ AddOrReplace(m_value, key.c_str(), arrayValue);
+ return *this;
+}
+
+JsonValue& JsonValue::WithArray(const Aws::String& key, Array<JsonValue>&& array)
+{
+ if (!m_value)
+ {
+ m_value = cJSON_CreateObject();
+ }
+
+ auto arrayValue = cJSON_CreateArray();
+ for (unsigned i = 0; i < array.GetLength(); ++i)
+ {
+ cJSON_AddItemToArray(arrayValue, array[i].m_value);
+ array[i].m_value = nullptr;
+ }
+
+ AddOrReplace(m_value, key.c_str(), arrayValue);
+ return *this;
+}
+
+JsonValue& JsonValue::AsArray(const Array<JsonValue>& array)
+{
+ auto arrayValue = cJSON_CreateArray();
+ for (unsigned i = 0; i < array.GetLength(); ++i)
+ {
+ cJSON_AddItemToArray(arrayValue, cJSON_Duplicate(array[i].m_value, true /*recurse*/));
+ }
+
+ Destroy();
+ m_value = arrayValue;
+ return *this;
+}
+
+JsonValue& JsonValue::AsArray(Array<JsonValue>&& array)
+{
+ auto arrayValue = cJSON_CreateArray();
+ for (unsigned i = 0; i < array.GetLength(); ++i)
+ {
+ cJSON_AddItemToArray(arrayValue, array[i].m_value);
+ array[i].m_value = nullptr;
+ }
+
+ Destroy();
+ m_value = arrayValue;
+ return *this;
+}
+
+JsonValue& JsonValue::WithObject(const char* key, const JsonValue& value)
+{
+ if (!m_value)
+ {
+ m_value = cJSON_CreateObject();
+ }
+
+ const auto copy = value.m_value == nullptr ? cJSON_CreateObject() : cJSON_Duplicate(value.m_value, true /*recurse*/);
+ AddOrReplace(m_value, key, copy);
+ return *this;
+}
+
+JsonValue& JsonValue::WithObject(const Aws::String& key, const JsonValue& value)
+{
+ return WithObject(key.c_str(), value);
+}
+
+JsonValue& JsonValue::WithObject(const char* key, JsonValue&& value)
+{
+ if (!m_value)
+ {
+ m_value = cJSON_CreateObject();
+ }
+
+ AddOrReplace(m_value, key, value.m_value == nullptr ? cJSON_CreateObject() : value.m_value);
+ value.m_value = nullptr;
+ return *this;
+}
+
+JsonValue& JsonValue::WithObject(const Aws::String& key, JsonValue&& value)
+{
+ return WithObject(key.c_str(), std::move(value));
+}
+
+JsonValue& JsonValue::AsObject(const JsonValue& value)
+{
+ *this = value;
+ return *this;
+}
+
+JsonValue& JsonValue::AsObject(JsonValue && value)
+{
+ *this = std::move(value);
+ return *this;
+}
+
+bool JsonValue::operator==(const JsonValue& other) const
+{
+ return cJSON_Compare(m_value, other.m_value, true /*case-sensitive*/) != 0;
+}
+
+bool JsonValue::operator!=(const JsonValue& other) const
+{
+ return !(*this == other);
+}
+
+JsonView JsonValue::View() const
+{
+ return *this;
+}
+
+JsonView::JsonView() : m_value(nullptr)
+{
+}
+
+JsonView::JsonView(const JsonValue& val) : m_value(val.m_value)
+{
+}
+
+JsonView::JsonView(cJSON* val) : m_value(val)
+{
+}
+
+JsonView& JsonView::operator=(const JsonValue& v)
+{
+ m_value = v.m_value;
+ return *this;
+}
+
+JsonView& JsonView::operator=(cJSON* val)
+{
+ m_value = val;
+ return *this;
+}
+
+Aws::String JsonView::GetString(const Aws::String& key) const
+{
+ assert(m_value);
+ auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str());
+ auto str = cJSON_GetStringValue(item);
+ return str ? str : "";
+}
+
+Aws::String JsonView::AsString() const
+{
+ const char* str = cJSON_GetStringValue(m_value);
+ if (str == nullptr)
+ {
+ return {};
+ }
+ return str;
+}
+
+bool JsonView::GetBool(const Aws::String& key) const
+{
+ assert(m_value);
+ auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str());
+ assert(item);
+ return item->valueint != 0;
+}
+
+bool JsonView::AsBool() const
+{
+ assert(cJSON_IsBool(m_value));
+ return cJSON_IsTrue(m_value) != 0;
+}
+
+int JsonView::GetInteger(const Aws::String& key) const
+{
+ assert(m_value);
+ auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str());
+ assert(item);
+ return item->valueint;
+}
+
+int JsonView::AsInteger() const
+{
+ assert(cJSON_IsNumber(m_value)); // can be double or value larger than int_max, but at least not UB
+ return m_value->valueint;
+}
+
+int64_t JsonView::GetInt64(const Aws::String& key) const
+{
+ assert(m_value);
+ auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str());
+ assert(item);
+ if (item->valuestring)
+ {
+ return Aws::Utils::StringUtils::ConvertToInt64(item->valuestring);
+ }
+ else
+ {
+ return static_cast<int64_t>(item->valuedouble);
+ }
+}
+
+int64_t JsonView::AsInt64() const
+{
+ assert(cJSON_IsNumber(m_value));
+ if (m_value->valuestring)
+ {
+ return Aws::Utils::StringUtils::ConvertToInt64(m_value->valuestring);
+ }
+ else
+ {
+ return static_cast<int64_t>(m_value->valuedouble);
+ }
+}
+
+double JsonView::GetDouble(const Aws::String& key) const
+{
+ assert(m_value);
+ auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str());
+ assert(item);
+ return item->valuedouble;
+}
+
+double JsonView::AsDouble() const
+{
+ assert(cJSON_IsNumber(m_value));
+ return m_value->valuedouble;
+}
+
+JsonView JsonView::GetObject(const Aws::String& key) const
+{
+ assert(m_value);
+ auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str());
+ return item;
+}
+
+JsonView JsonView::AsObject() const
+{
+ assert(cJSON_IsObject(m_value) || cJSON_IsNull(m_value));
+ return m_value;
+}
+
+Array<JsonView> JsonView::GetArray(const Aws::String& key) const
+{
+ assert(m_value);
+ auto array = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str());
+ assert(cJSON_IsArray(array));
+ Array<JsonView> returnArray(cJSON_GetArraySize(array));
+
+ auto element = array->child;
+ for (unsigned i = 0; element && i < returnArray.GetLength(); ++i, element = element->next)
+ {
+ returnArray[i] = element;
+ }
+
+ return returnArray;
+}
+
+Array<JsonView> JsonView::AsArray() const
+{
+ assert(cJSON_IsArray(m_value));
+ Array<JsonView> returnArray(cJSON_GetArraySize(m_value));
+
+ auto element = m_value->child;
+
+ for (unsigned i = 0; element && i < returnArray.GetLength(); ++i, element = element->next)
+ {
+ returnArray[i] = element;
+ }
+
+ return returnArray;
+}
+
+Aws::Map<Aws::String, JsonView> JsonView::GetAllObjects() const
+{
+ Aws::Map<Aws::String, JsonView> valueMap;
+ if (!m_value)
+ {
+ return valueMap;
+ }
+
+ for (auto iter = m_value->child; iter; iter = iter->next)
+ {
+ valueMap.emplace(std::make_pair(Aws::String(iter->string), JsonView(iter)));
+ }
+
+ return valueMap;
+}
+
+bool JsonView::ValueExists(const Aws::String& key) const
+{
+ if (!cJSON_IsObject(m_value))
+ {
+ return false;
+ }
+
+ auto item = cJSON_GetObjectItemCaseSensitive(m_value, key.c_str());
+ return !(item == nullptr || cJSON_IsNull(item));
+}
+
+bool JsonView::KeyExists(const Aws::String& key) const
+{
+ if (!cJSON_IsObject(m_value))
+ {
+ return false;
+ }
+
+ return cJSON_GetObjectItemCaseSensitive(m_value, key.c_str()) != nullptr;;
+}
+
+bool JsonView::IsObject() const
+{
+ return cJSON_IsObject(m_value) != 0;
+}
+
+bool JsonView::IsBool() const
+{
+ return cJSON_IsBool(m_value) != 0;
+}
+
+bool JsonView::IsString() const
+{
+ return cJSON_IsString(m_value) != 0;
+}
+
+bool JsonView::IsIntegerType() const
+{
+ if (!cJSON_IsNumber(m_value))
+ {
+ return false;
+ }
+
+ if (m_value->valuestring)
+ {
+ Aws::String valueString = m_value->valuestring;
+ return std::all_of(valueString.begin(), valueString.end(), [](unsigned char c){ return ::isdigit(c) || c == '+' || c == '-'; });
+ }
+ return m_value->valuedouble == static_cast<long long>(m_value->valuedouble);
+}
+
+bool JsonView::IsFloatingPointType() const
+{
+ if (!cJSON_IsNumber(m_value))
+ {
+ return false;
+ }
+
+ if (m_value->valuestring)
+ {
+ Aws::String valueString = m_value->valuestring;
+ return std::any_of(valueString.begin(), valueString.end(), [](unsigned char c){ return !::isdigit(c) && c != '+' && c != '-'; });
+ }
+ return m_value->valuedouble != static_cast<long long>(m_value->valuedouble);
+}
+
+bool JsonView::IsListType() const
+{
+ return cJSON_IsArray(m_value) != 0;
+}
+
+bool JsonView::IsNull() const
+{
+ return cJSON_IsNull(m_value) != 0;
+}
+
+Aws::String JsonView::WriteCompact(bool treatAsObject) const
+{
+ if (!m_value)
+ {
+ if (treatAsObject)
+ {
+ return "{}";
+ }
+ return {};
+ }
+
+ auto temp = cJSON_PrintUnformatted(m_value);
+ Aws::String out(temp);
+ cJSON_free(temp);
+ return out;
+}
+
+Aws::String JsonView::WriteReadable(bool treatAsObject) const
+{
+ if (!m_value)
+ {
+ if (treatAsObject)
+ {
+ return "{\n}\n";
+ }
+ return {};
+ }
+
+ auto temp = cJSON_Print(m_value);
+ Aws::String out(temp);
+ cJSON_free(temp);
+ return out;
+}
+
+JsonValue JsonView::Materialize() const
+{
+ return m_value;
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp
new file mode 100644
index 0000000000..fc1b9fcc2e
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/AWSLogging.cpp
@@ -0,0 +1,51 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+
+#include <aws/core/utils/logging/AWSLogging.h>
+#include <aws/core/utils/logging/LogSystemInterface.h>
+#include <aws/core/utils/memory/stl/AWSStack.h>
+
+#include <memory>
+
+using namespace Aws::Utils;
+using namespace Aws::Utils::Logging;
+
+static std::shared_ptr<LogSystemInterface> AWSLogSystem(nullptr);
+static std::shared_ptr<LogSystemInterface> OldLogger(nullptr);
+
+namespace Aws
+{
+namespace Utils
+{
+namespace Logging {
+
+void InitializeAWSLogging(const std::shared_ptr<LogSystemInterface> &logSystem) {
+ AWSLogSystem = logSystem;
+}
+
+void ShutdownAWSLogging(void) {
+ InitializeAWSLogging(nullptr);
+}
+
+LogSystemInterface *GetLogSystem() {
+ return AWSLogSystem.get();
+}
+
+void PushLogger(const std::shared_ptr<LogSystemInterface> &logSystem)
+{
+ OldLogger = AWSLogSystem;
+ AWSLogSystem = logSystem;
+}
+
+void PopLogger()
+{
+ AWSLogSystem = OldLogger;
+ OldLogger = nullptr;
+}
+
+} // namespace Logging
+} // namespace Utils
+} // namespace Aws \ No newline at end of file
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp
new file mode 100644
index 0000000000..dec7cef82f
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/ConsoleLogSystem.cpp
@@ -0,0 +1,22 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+
+#include <aws/core/utils/logging/ConsoleLogSystem.h>
+
+#include <iostream>
+
+using namespace Aws::Utils;
+using namespace Aws::Utils::Logging;
+
+void ConsoleLogSystem::ProcessFormattedStatement(Aws::String&& statement)
+{
+ std::cout << statement;
+}
+
+void ConsoleLogSystem::Flush()
+{
+ std::cout.flush();
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp
new file mode 100644
index 0000000000..7286bb6378
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/DefaultLogSystem.cpp
@@ -0,0 +1,117 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+
+#include <aws/core/utils/logging/DefaultLogSystem.h>
+
+#include <aws/core/utils/DateTime.h>
+#include <aws/core/utils/memory/stl/AWSVector.h>
+
+#include <fstream>
+
+using namespace Aws::Utils;
+using namespace Aws::Utils::Logging;
+
+static const char* AllocationTag = "DefaultLogSystem";
+static const int BUFFERED_MSG_COUNT = 100;
+
+static std::shared_ptr<Aws::OFStream> MakeDefaultLogFile(const Aws::String& filenamePrefix)
+{
+ Aws::String newFileName = filenamePrefix + DateTime::CalculateGmtTimestampAsString("%Y-%m-%d-%H") + ".log";
+ return Aws::MakeShared<Aws::OFStream>(AllocationTag, newFileName.c_str(), Aws::OFStream::out | Aws::OFStream::app);
+}
+
+static void LogThread(DefaultLogSystem::LogSynchronizationData* syncData, const std::shared_ptr<Aws::OStream>& logFile, const Aws::String& filenamePrefix, bool rollLog)
+{
+ // localtime requires access to env. variables to get Timezone, which is not thread-safe
+ int32_t lastRolledHour = DateTime::Now().GetHour(false /*localtime*/);
+ std::shared_ptr<Aws::OStream> log = logFile;
+
+ for(;;)
+ {
+ std::unique_lock<std::mutex> locker(syncData->m_logQueueMutex);
+ syncData->m_queueSignal.wait(locker, [&](){ return syncData->m_stopLogging == true || syncData->m_queuedLogMessages.size() > 0; } );
+
+ if (syncData->m_stopLogging && syncData->m_queuedLogMessages.size() == 0)
+ {
+ break;
+ }
+
+ Aws::Vector<Aws::String> messages(std::move(syncData->m_queuedLogMessages));
+ syncData->m_queuedLogMessages.reserve(BUFFERED_MSG_COUNT);
+
+ locker.unlock();
+
+ if (messages.size() > 0)
+ {
+ if (rollLog)
+ {
+ // localtime requires access to env. variables to get Timezone, which is not thread-safe
+ int32_t currentHour = DateTime::Now().GetHour(false /*localtime*/);
+ if (currentHour != lastRolledHour)
+ {
+ log = MakeDefaultLogFile(filenamePrefix);
+ lastRolledHour = currentHour;
+ }
+ }
+
+ for (const auto& msg : messages)
+ {
+ (*log) << msg;
+ }
+
+ log->flush();
+ }
+ }
+}
+
+DefaultLogSystem::DefaultLogSystem(LogLevel logLevel, const std::shared_ptr<Aws::OStream>& logFile) :
+ Base(logLevel),
+ m_syncData(),
+ m_loggingThread()
+{
+ m_loggingThread = std::thread(LogThread, &m_syncData, logFile, "", false);
+}
+
+DefaultLogSystem::DefaultLogSystem(LogLevel logLevel, const Aws::String& filenamePrefix) :
+ Base(logLevel),
+ m_syncData(),
+ m_loggingThread()
+{
+ m_loggingThread = std::thread(LogThread, &m_syncData, MakeDefaultLogFile(filenamePrefix), filenamePrefix, true);
+}
+
+DefaultLogSystem::~DefaultLogSystem()
+{
+ {
+ std::lock_guard<std::mutex> locker(m_syncData.m_logQueueMutex);
+ m_syncData.m_stopLogging = true;
+ }
+
+ m_syncData.m_queueSignal.notify_one();
+
+ m_loggingThread.join();
+}
+
+void DefaultLogSystem::ProcessFormattedStatement(Aws::String&& statement)
+{
+ std::unique_lock<std::mutex> locker(m_syncData.m_logQueueMutex);
+ m_syncData.m_queuedLogMessages.emplace_back(std::move(statement));
+ if(m_syncData.m_queuedLogMessages.size() >= BUFFERED_MSG_COUNT)
+ {
+ locker.unlock();
+ m_syncData.m_queueSignal.notify_one();
+ }
+ else
+ {
+ locker.unlock();
+ }
+}
+
+void DefaultLogSystem::Flush()
+{
+ m_syncData.m_queueSignal.notify_one();
+}
+
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp
new file mode 100644
index 0000000000..41c4d7e09c
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/FormattedLogSystem.cpp
@@ -0,0 +1,99 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+
+#include <aws/core/utils/logging/FormattedLogSystem.h>
+
+#include <aws/core/utils/DateTime.h>
+#include <aws/core/utils/Array.h>
+
+#include <fstream>
+#include <cstdarg>
+#include <stdio.h>
+#include <thread>
+
+using namespace Aws::Utils;
+using namespace Aws::Utils::Logging;
+
+static Aws::String CreateLogPrefixLine(LogLevel logLevel, const char* tag)
+{
+ Aws::StringStream ss;
+
+ switch(logLevel)
+ {
+ case LogLevel::Error:
+ ss << "[ERROR] ";
+ break;
+
+ case LogLevel::Fatal:
+ ss << "[FATAL] ";
+ break;
+
+ case LogLevel::Warn:
+ ss << "[WARN] ";
+ break;
+
+ case LogLevel::Info:
+ ss << "[INFO] ";
+ break;
+
+ case LogLevel::Debug:
+ ss << "[DEBUG] ";
+ break;
+
+ case LogLevel::Trace:
+ ss << "[TRACE] ";
+ break;
+
+ default:
+ ss << "[UNKOWN] ";
+ break;
+ }
+
+ ss << DateTime::Now().CalculateGmtTimeWithMsPrecision() << " " << tag << " [" << std::this_thread::get_id() << "] ";
+
+ return ss.str();
+}
+
+FormattedLogSystem::FormattedLogSystem(LogLevel logLevel) :
+ m_logLevel(logLevel)
+{
+}
+
+void FormattedLogSystem::Log(LogLevel logLevel, const char* tag, const char* formatStr, ...)
+{
+ Aws::StringStream ss;
+ ss << CreateLogPrefixLine(logLevel, tag);
+
+ std::va_list args;
+ va_start(args, formatStr);
+
+ va_list tmp_args; //unfortunately you cannot consume a va_list twice
+ va_copy(tmp_args, args); //so we have to copy it
+ #ifdef WIN32
+ const int requiredLength = _vscprintf(formatStr, tmp_args) + 1;
+ #else
+ const int requiredLength = vsnprintf(nullptr, 0, formatStr, tmp_args) + 1;
+ #endif
+ va_end(tmp_args);
+
+ Array<char> outputBuff(requiredLength);
+ #ifdef WIN32
+ vsnprintf_s(outputBuff.GetUnderlyingData(), requiredLength, _TRUNCATE, formatStr, args);
+ #else
+ vsnprintf(outputBuff.GetUnderlyingData(), requiredLength, formatStr, args);
+ #endif // WIN32
+
+ ss << outputBuff.GetUnderlyingData() << std::endl;
+
+ ProcessFormattedStatement(ss.str());
+
+ va_end(args);
+}
+
+void FormattedLogSystem::LogStream(LogLevel logLevel, const char* tag, const Aws::OStringStream &message_stream)
+{
+ ProcessFormattedStatement(CreateLogPrefixLine(logLevel, tag) + message_stream.str() + "\n");
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/LogLevel.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/LogLevel.cpp
new file mode 100644
index 0000000000..9ff1bf3126
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/logging/LogLevel.cpp
@@ -0,0 +1,45 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/logging/LogLevel.h>
+
+#include <aws/core/utils/memory/stl/AWSMap.h>
+#include <aws/core/utils/memory/stl/AWSString.h>
+#include <cassert>
+
+using namespace Aws::Utils::Logging;
+
+namespace Aws
+{
+namespace Utils
+{
+namespace Logging
+{
+
+Aws::String GetLogLevelName(LogLevel logLevel)
+{
+ switch (logLevel)
+ {
+ case LogLevel::Fatal:
+ return "FATAL";
+ case LogLevel::Error:
+ return "ERROR";
+ case LogLevel::Warn:
+ return "WARN";
+ case LogLevel::Info:
+ return "INFO";
+ case LogLevel::Debug:
+ return "DEBUG";
+ case LogLevel::Trace:
+ return "TRACE";
+ default:
+ assert(0);
+ return "";
+ }
+}
+
+} // namespace Logging
+} // namespace Utils
+} // namespace Aws
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/AWSMemory.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/AWSMemory.cpp
new file mode 100644
index 0000000000..96d339d385
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/AWSMemory.cpp
@@ -0,0 +1,134 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/memory/AWSMemory.h>
+
+#include <aws/core/utils/memory/MemorySystemInterface.h>
+#include <aws/common/common.h>
+
+#include <atomic>
+
+using namespace Aws::Utils;
+using namespace Aws::Utils::Memory;
+
+#ifdef USE_AWS_MEMORY_MANAGEMENT
+ static MemorySystemInterface* AWSMemorySystem(nullptr);
+#endif // USE_AWS_MEMORY_MANAGEMENT
+
+namespace Aws
+{
+namespace Utils
+{
+namespace Memory
+{
+
+void InitializeAWSMemorySystem(MemorySystemInterface& memorySystem)
+{
+ #ifdef USE_AWS_MEMORY_MANAGEMENT
+ if(AWSMemorySystem != nullptr)
+ {
+ AWSMemorySystem->End();
+ }
+
+ AWSMemorySystem = &memorySystem;
+ AWSMemorySystem->Begin();
+ #else
+ AWS_UNREFERENCED_PARAM(memorySystem);
+ #endif // USE_AWS_MEMORY_MANAGEMENT
+}
+
+void ShutdownAWSMemorySystem(void)
+{
+ #ifdef USE_AWS_MEMORY_MANAGEMENT
+ if(AWSMemorySystem != nullptr)
+ {
+ AWSMemorySystem->End();
+ }
+ AWSMemorySystem = nullptr;
+ #endif // USE_AWS_MEMORY_MANAGEMENT
+}
+
+MemorySystemInterface* GetMemorySystem()
+{
+ #ifdef USE_AWS_MEMORY_MANAGEMENT
+ return AWSMemorySystem;
+ #else
+ return nullptr;
+ #endif // USE_AWS_MEMORY_MANAGEMENT
+}
+
+} // namespace Memory
+} // namespace Utils
+
+void* Malloc(const char* allocationTag, size_t allocationSize)
+{
+ Aws::Utils::Memory::MemorySystemInterface* memorySystem = Aws::Utils::Memory::GetMemorySystem();
+
+ void* rawMemory = nullptr;
+ if(memorySystem != nullptr)
+ {
+ rawMemory = memorySystem->AllocateMemory(allocationSize, 1, allocationTag);
+ }
+ else
+ {
+ rawMemory = malloc(allocationSize);
+ }
+
+ return rawMemory;
+}
+
+
+void Free(void* memoryPtr)
+{
+ if(memoryPtr == nullptr)
+ {
+ return;
+ }
+
+ Aws::Utils::Memory::MemorySystemInterface* memorySystem = Aws::Utils::Memory::GetMemorySystem();
+ if(memorySystem != nullptr)
+ {
+ memorySystem->FreeMemory(memoryPtr);
+ }
+ else
+ {
+ free(memoryPtr);
+ }
+}
+
+static void* MemAcquire(aws_allocator* allocator, size_t size)
+{
+ (void)allocator; // unused;
+ return Aws::Malloc("MemAcquire", size);
+}
+
+static void MemRelease(aws_allocator* allocator, void* ptr)
+{
+ (void)allocator; // unused;
+ return Aws::Free(ptr);
+}
+
+static aws_allocator create_aws_allocator()
+{
+#if (__GNUC__ == 4) && !defined(__clang__)
+ AWS_SUPPRESS_WARNING("-Wmissing-field-initializers", aws_allocator wrapper{};);
+#else
+ aws_allocator wrapper{};
+#endif
+ wrapper.mem_acquire = MemAcquire;
+ wrapper.mem_release = MemRelease;
+ wrapper.mem_realloc = nullptr;
+ return wrapper;
+}
+
+aws_allocator* get_aws_allocator()
+{
+ static aws_allocator wrapper = create_aws_allocator();
+ return &wrapper;
+}
+
+} // namespace Aws
+
+
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/stl/SimpleStringStream.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/stl/SimpleStringStream.cpp
new file mode 100644
index 0000000000..4662749872
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/memory/stl/SimpleStringStream.cpp
@@ -0,0 +1,66 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/memory/stl/SimpleStringStream.h>
+
+namespace Aws
+{
+
+SimpleStringStream::SimpleStringStream() :
+ base(&m_streamBuffer),
+ m_streamBuffer()
+{
+}
+
+SimpleStringStream::SimpleStringStream(const Aws::String& value) :
+ base(&m_streamBuffer),
+ m_streamBuffer(value)
+{
+}
+
+void SimpleStringStream::str(const Aws::String& value)
+{
+ m_streamBuffer.str(value);
+}
+
+//
+
+SimpleIStringStream::SimpleIStringStream() :
+ base(&m_streamBuffer),
+ m_streamBuffer()
+{
+}
+
+SimpleIStringStream::SimpleIStringStream(const Aws::String& value) :
+ base(&m_streamBuffer),
+ m_streamBuffer(value)
+{
+}
+
+void SimpleIStringStream::str(const Aws::String& value)
+{
+ m_streamBuffer.str(value);
+}
+
+//
+
+SimpleOStringStream::SimpleOStringStream() :
+ base(&m_streamBuffer),
+ m_streamBuffer()
+{
+}
+
+SimpleOStringStream::SimpleOStringStream(const Aws::String& value) :
+ base(&m_streamBuffer),
+ m_streamBuffer(value)
+{
+}
+
+void SimpleOStringStream::str(const Aws::String& value)
+{
+ m_streamBuffer.str(value);
+}
+
+} // namespace Aws
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ConcurrentStreamBuf.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ConcurrentStreamBuf.cpp
new file mode 100644
index 0000000000..3f59dbe96d
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ConcurrentStreamBuf.cpp
@@ -0,0 +1,126 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+#include <aws/core/utils/stream/ConcurrentStreamBuf.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <cstdint>
+#include <cassert>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Stream
+ {
+ const char TAG[] = "ConcurrentStreamBuf";
+ ConcurrentStreamBuf::ConcurrentStreamBuf(size_t bufferLength) :
+ m_putArea(bufferLength), // we access [0] of the put area below so we must initialize it.
+ m_eof(false)
+ {
+ m_getArea.reserve(bufferLength);
+ m_backbuf.reserve(bufferLength);
+
+ char* pbegin = reinterpret_cast<char*>(&m_putArea[0]);
+ setp(pbegin, pbegin + bufferLength);
+ }
+
+ void ConcurrentStreamBuf::SetEof()
+ {
+ {
+ std::unique_lock<std::mutex> lock(m_lock);
+ m_eof = true;
+ }
+ m_signal.notify_all();
+ }
+
+ void ConcurrentStreamBuf::FlushPutArea()
+ {
+ const size_t bitslen = pptr() - pbase();
+ if (bitslen)
+ {
+ // scope the lock
+ {
+ std::unique_lock<std::mutex> lock(m_lock);
+ m_signal.wait(lock, [this, bitslen]{ return m_eof || bitslen <= (m_backbuf.capacity() - m_backbuf.size()); });
+ if (m_eof)
+ {
+ return;
+ }
+ std::copy(pbase(), pptr(), std::back_inserter(m_backbuf));
+ }
+ m_signal.notify_one();
+ char* pbegin = reinterpret_cast<char*>(&m_putArea[0]);
+ setp(pbegin, pbegin + m_putArea.size());
+ }
+ }
+
+ std::streampos ConcurrentStreamBuf::seekoff(std::streamoff, std::ios_base::seekdir, std::ios_base::openmode)
+ {
+ return std::streamoff(-1); // Seeking is not supported.
+ }
+
+ std::streampos ConcurrentStreamBuf::seekpos(std::streampos, std::ios_base::openmode)
+ {
+ return std::streamoff(-1); // Seeking is not supported.
+ }
+
+ int ConcurrentStreamBuf::underflow()
+ {
+ {
+ std::unique_lock<std::mutex> lock(m_lock);
+ m_signal.wait(lock, [this]{ return m_backbuf.empty() == false || m_eof; });
+
+ if (m_eof && m_backbuf.empty())
+ {
+ return std::char_traits<char>::eof();
+ }
+
+ m_getArea.clear(); // keep the get-area from growing unbounded.
+ std::copy(m_backbuf.begin(), m_backbuf.end(), std::back_inserter(m_getArea));
+ m_backbuf.clear();
+ }
+ m_signal.notify_one();
+ char* gbegin = reinterpret_cast<char*>(&m_getArea[0]);
+ setg(gbegin, gbegin, gbegin + m_getArea.size());
+ return std::char_traits<char>::to_int_type(*gptr());
+ }
+
+ std::streamsize ConcurrentStreamBuf::showmanyc()
+ {
+ std::unique_lock<std::mutex> lock(m_lock);
+ AWS_LOGSTREAM_TRACE(TAG, "stream how many character? " << m_backbuf.size());
+ return m_backbuf.size();
+ }
+
+ int ConcurrentStreamBuf::overflow(int ch)
+ {
+ const auto eof = std::char_traits<char>::eof();
+
+ if (ch == eof)
+ {
+ FlushPutArea();
+ return eof;
+ }
+
+ FlushPutArea();
+ {
+ std::unique_lock<std::mutex> lock(m_lock);
+ if (m_eof)
+ {
+ return eof;
+ }
+ *pptr() = static_cast<char>(ch);
+ pbump(1);
+ return ch;
+ }
+ }
+
+ int ConcurrentStreamBuf::sync()
+ {
+ FlushPutArea();
+ return 0;
+ }
+ }
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/PreallocatedStreamBuf.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/PreallocatedStreamBuf.cpp
new file mode 100644
index 0000000000..f656fc8613
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/PreallocatedStreamBuf.cpp
@@ -0,0 +1,75 @@
+
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/stream/PreallocatedStreamBuf.h>
+#include <cassert>
+
+namespace Aws
+{
+ namespace Utils
+ {
+ namespace Stream
+ {
+ PreallocatedStreamBuf::PreallocatedStreamBuf(unsigned char* buffer, uint64_t lengthToRead) :
+ m_underlyingBuffer(buffer), m_lengthToRead(lengthToRead)
+ {
+ char* end = reinterpret_cast<char*>(m_underlyingBuffer + m_lengthToRead);
+ char* begin = reinterpret_cast<char*>(m_underlyingBuffer);
+ setp(begin, end);
+ setg(begin, begin, end);
+ }
+
+ PreallocatedStreamBuf::pos_type PreallocatedStreamBuf::seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which)
+ {
+ if (dir == std::ios_base::beg)
+ {
+ return seekpos(off, which);
+ }
+ else if (dir == std::ios_base::end)
+ {
+ return seekpos(m_lengthToRead - off, which);
+ }
+ else if (dir == std::ios_base::cur)
+ {
+ if(which == std::ios_base::in)
+ {
+ return seekpos((gptr() - reinterpret_cast<char*>(m_underlyingBuffer)) + off, which);
+ }
+ else
+ {
+ return seekpos((pptr() - reinterpret_cast<char*>(m_underlyingBuffer)) + off, which);
+ }
+ }
+
+ return off_type(-1);
+ }
+
+ PreallocatedStreamBuf::pos_type PreallocatedStreamBuf::seekpos(pos_type pos, std::ios_base::openmode which)
+ {
+ assert(static_cast<size_t>(pos) <= m_lengthToRead);
+ if (static_cast<size_t>(pos) > m_lengthToRead)
+ {
+ return pos_type(off_type(-1));
+ }
+
+ char* end = reinterpret_cast<char*>(m_underlyingBuffer + m_lengthToRead);
+ char* begin = reinterpret_cast<char*>(m_underlyingBuffer);
+
+ if (which == std::ios_base::in)
+ {
+ setg(begin, begin + static_cast<size_t>(pos), end);
+ }
+
+ if (which == std::ios_base::out)
+ {
+ setp(begin + static_cast<size_t>(pos), end);
+ }
+
+ return pos;
+ }
+ }
+ }
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp
new file mode 100644
index 0000000000..6d1f90ed12
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/ResponseStream.cpp
@@ -0,0 +1,91 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/stream/ResponseStream.h>
+#include <aws/core/utils/memory/stl/AWSStringStream.h>
+
+#if defined(_GLIBCXX_FULLY_DYNAMIC_STRING) && _GLIBCXX_FULLY_DYNAMIC_STRING == 0 && defined(__ANDROID__)
+#include <aws/core/utils/stream/SimpleStreamBuf.h>
+using DefaultStreamBufType = Aws::Utils::Stream::SimpleStreamBuf;
+#else
+using DefaultStreamBufType = Aws::StringBuf;
+#endif
+
+using namespace Aws::Utils::Stream;
+
+ResponseStream::ResponseStream(void) :
+ m_underlyingStream(nullptr)
+{
+}
+
+ResponseStream::ResponseStream(Aws::IOStream* underlyingStreamToManage) :
+ m_underlyingStream(underlyingStreamToManage)
+{
+}
+
+ResponseStream::ResponseStream(const Aws::IOStreamFactory& factory) :
+ m_underlyingStream(factory())
+{
+}
+
+ResponseStream::ResponseStream(ResponseStream&& toMove) : m_underlyingStream(toMove.m_underlyingStream)
+{
+ toMove.m_underlyingStream = nullptr;
+}
+
+ResponseStream& ResponseStream::operator=(ResponseStream&& toMove)
+{
+ if(m_underlyingStream == toMove.m_underlyingStream)
+ {
+ return *this;
+ }
+
+ ReleaseStream();
+ m_underlyingStream = toMove.m_underlyingStream;
+ toMove.m_underlyingStream = nullptr;
+
+ return *this;
+}
+
+ResponseStream::~ResponseStream()
+{
+ ReleaseStream();
+}
+
+void ResponseStream::ReleaseStream()
+{
+ if (m_underlyingStream)
+ {
+ m_underlyingStream->flush();
+ Aws::Delete(m_underlyingStream);
+ }
+
+ m_underlyingStream = nullptr;
+}
+
+static const char *DEFAULT_STREAM_TAG = "DefaultUnderlyingStream";
+
+DefaultUnderlyingStream::DefaultUnderlyingStream() :
+ Base( Aws::New< DefaultStreamBufType >( DEFAULT_STREAM_TAG ) )
+{}
+
+DefaultUnderlyingStream::DefaultUnderlyingStream(Aws::UniquePtr<std::streambuf> buf) :
+ Base(buf.release())
+{}
+
+DefaultUnderlyingStream::~DefaultUnderlyingStream()
+{
+ if( rdbuf() )
+ {
+ Aws::Delete( rdbuf() );
+ }
+}
+
+static const char* RESPONSE_STREAM_FACTORY_TAG = "ResponseStreamFactory";
+
+Aws::IOStream* Aws::Utils::Stream::DefaultResponseStreamFactoryMethod()
+{
+ return Aws::New<Aws::Utils::Stream::DefaultUnderlyingStream>(RESPONSE_STREAM_FACTORY_TAG);
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/SimpleStreamBuf.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/SimpleStreamBuf.cpp
new file mode 100644
index 0000000000..6e42994744
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/stream/SimpleStreamBuf.cpp
@@ -0,0 +1,239 @@
+
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/stream/SimpleStreamBuf.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+
+namespace Aws
+{
+namespace Utils
+{
+namespace Stream
+{
+
+static const uint32_t DEFAULT_BUFFER_SIZE = 100;
+static const char* SIMPLE_STREAMBUF_ALLOCATION_TAG = "SimpleStreamBufTag";
+
+SimpleStreamBuf::SimpleStreamBuf() :
+ m_buffer(nullptr),
+ m_bufferSize(0)
+{
+ m_buffer = Aws::NewArray<char>(DEFAULT_BUFFER_SIZE, SIMPLE_STREAMBUF_ALLOCATION_TAG);
+ m_bufferSize = DEFAULT_BUFFER_SIZE;
+
+ char* begin = m_buffer;
+ char* end = begin + m_bufferSize;
+
+ setp(begin, end);
+ setg(begin, begin, begin);
+}
+
+SimpleStreamBuf::SimpleStreamBuf(const Aws::String& value) :
+ m_buffer(nullptr),
+ m_bufferSize(0)
+{
+ size_t baseSize = (std::max)(value.size(), static_cast<std::size_t>(DEFAULT_BUFFER_SIZE));
+
+ m_buffer = Aws::NewArray<char>(baseSize, SIMPLE_STREAMBUF_ALLOCATION_TAG);
+ m_bufferSize = baseSize;
+
+ std::memcpy(m_buffer, value.c_str(), value.size());
+
+ char* begin = m_buffer;
+ char* end = begin + m_bufferSize;
+
+ setp(begin + value.size(), end);
+ setg(begin, begin, begin);
+}
+
+SimpleStreamBuf::~SimpleStreamBuf()
+{
+ if(m_buffer)
+ {
+ Aws::DeleteArray<char>(m_buffer);
+ m_buffer = nullptr;
+ }
+
+ m_bufferSize = 0;
+}
+
+std::streampos SimpleStreamBuf::seekoff(std::streamoff off, std::ios_base::seekdir dir, std::ios_base::openmode which)
+{
+ if (dir == std::ios_base::beg)
+ {
+ return seekpos(off, which);
+ }
+ else if (dir == std::ios_base::end)
+ {
+ return seekpos((pptr() - m_buffer) - off, which);
+ }
+ else if (dir == std::ios_base::cur)
+ {
+ if(which == std::ios_base::in)
+ {
+ return seekpos((gptr() - m_buffer) + off, which);
+ }
+ else
+ {
+ return seekpos((pptr() - m_buffer) + off, which);
+ }
+ }
+
+ return off_type(-1);
+}
+
+std::streampos SimpleStreamBuf::seekpos(std::streampos pos, std::ios_base::openmode which)
+{
+ size_t maxSeek = pptr() - m_buffer;
+ assert(static_cast<size_t>(pos) <= maxSeek);
+ if (static_cast<size_t>(pos) > maxSeek)
+ {
+ return pos_type(off_type(-1));
+ }
+
+ if (which == std::ios_base::in)
+ {
+ setg(m_buffer, m_buffer + static_cast<size_t>(pos), pptr());
+ }
+
+ if (which == std::ios_base::out)
+ {
+ setp(m_buffer + static_cast<size_t>(pos), epptr());
+ }
+
+ return pos;
+}
+
+bool SimpleStreamBuf::GrowBuffer()
+{
+ size_t currentSize = m_bufferSize;
+ size_t newSize = currentSize * 2;
+
+ char* newBuffer = Aws::NewArray<char>(newSize, SIMPLE_STREAMBUF_ALLOCATION_TAG);
+ if(newBuffer == nullptr)
+ {
+ return false;
+ }
+
+ if(currentSize > 0)
+ {
+ std::memcpy(newBuffer, m_buffer, currentSize);
+ }
+
+ if(m_buffer)
+ {
+ Aws::DeleteArray<char>(m_buffer);
+ }
+
+ m_buffer = newBuffer;
+ m_bufferSize = newSize;
+
+ return true;
+}
+
+int SimpleStreamBuf::overflow (int c)
+{
+ auto endOfFile = std::char_traits< char >::eof();
+ if(c == endOfFile)
+ {
+ return endOfFile;
+ }
+
+ char* old_begin = m_buffer;
+
+ char *old_pptr = pptr();
+ char *old_gptr = gptr();
+ char *old_egptr = egptr();
+
+ size_t currentWritePosition = m_bufferSize;
+
+ if(!GrowBuffer())
+ {
+ return endOfFile;
+ }
+
+ char* new_begin = m_buffer;
+ char* new_end = new_begin + m_bufferSize;
+
+ setp(new_begin + (old_pptr - old_begin) + 1, new_end);
+ setg(new_begin, new_begin + (old_gptr - old_begin), new_begin + (old_egptr - old_begin));
+
+ auto val = std::char_traits< char >::to_char_type(c);
+ *(new_begin + currentWritePosition) = val;
+
+ return c;
+}
+
+std::streamsize SimpleStreamBuf::xsputn(const char* s, std::streamsize n)
+{
+ std::streamsize writeCount = 0;
+ while(writeCount < n)
+ {
+ char* current_pptr = pptr();
+ char* current_epptr = epptr();
+
+ if (current_pptr < current_epptr)
+ {
+ std::size_t copySize = (std::min)(static_cast< std::size_t >(n - writeCount),
+ static_cast< std::size_t >(current_epptr - current_pptr));
+
+ std::memcpy(current_pptr, s + writeCount, copySize);
+ writeCount += copySize;
+ setp(current_pptr + copySize, current_epptr);
+ setg(m_buffer, gptr(), pptr());
+ }
+ else if (overflow(std::char_traits< char >::to_int_type(*(s + writeCount))) != std::char_traits<char>::eof())
+ {
+ writeCount++;
+ }
+ else
+ {
+ return writeCount;
+ }
+ }
+
+ return writeCount;
+}
+
+Aws::String SimpleStreamBuf::str() const
+{
+ return Aws::String(m_buffer, pptr());
+}
+
+int SimpleStreamBuf::underflow()
+{
+ if(egptr() != pptr())
+ {
+ setg(m_buffer, gptr(), pptr());
+ }
+
+ if(gptr() != egptr())
+ {
+ return std::char_traits< char >::to_int_type(*gptr());
+ }
+ else
+ {
+ return std::char_traits< char >::eof();
+ }
+}
+
+void SimpleStreamBuf::str(const Aws::String& value)
+{
+ char* begin = m_buffer;
+ char* end = begin + m_bufferSize;
+
+ setp(begin, end);
+ setg(begin, begin, begin);
+
+ xsputn(value.c_str(), value.size());
+}
+
+}
+}
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Executor.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Executor.cpp
new file mode 100644
index 0000000000..4a3c4209c4
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Executor.cpp
@@ -0,0 +1,155 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/threading/Executor.h>
+#include <aws/core/utils/threading/ThreadTask.h>
+#include <thread>
+#include <cassert>
+
+static const char* POOLED_CLASS_TAG = "PooledThreadExecutor";
+
+using namespace Aws::Utils::Threading;
+
+bool DefaultExecutor::SubmitToThread(std::function<void()>&& fx)
+{
+ auto main = [fx, this] {
+ fx();
+ Detach(std::this_thread::get_id());
+ };
+
+ State expected;
+ do
+ {
+ expected = State::Free;
+ if(m_state.compare_exchange_strong(expected, State::Locked))
+ {
+ std::thread t(main);
+ const auto id = t.get_id(); // copy the id before we std::move the thread
+ m_threads.emplace(id, std::move(t));
+ m_state = State::Free;
+ return true;
+ }
+ }
+ while(expected != State::Shutdown);
+ return false;
+}
+
+void DefaultExecutor::Detach(std::thread::id id)
+{
+ State expected;
+ do
+ {
+ expected = State::Free;
+ if(m_state.compare_exchange_strong(expected, State::Locked))
+ {
+ auto it = m_threads.find(id);
+ assert(it != m_threads.end());
+ it->second.detach();
+ m_threads.erase(it);
+ m_state = State::Free;
+ return;
+ }
+ }
+ while(expected != State::Shutdown);
+}
+
+DefaultExecutor::~DefaultExecutor()
+{
+ auto expected = State::Free;
+ while(!m_state.compare_exchange_strong(expected, State::Shutdown))
+ {
+ //spin while currently detaching threads finish
+ assert(expected == State::Locked);
+ expected = State::Free;
+ }
+
+ auto it = m_threads.begin();
+ while(!m_threads.empty())
+ {
+ it->second.join();
+ it = m_threads.erase(it);
+ }
+}
+
+PooledThreadExecutor::PooledThreadExecutor(size_t poolSize, OverflowPolicy overflowPolicy) :
+ m_sync(0, poolSize), m_poolSize(poolSize), m_overflowPolicy(overflowPolicy)
+{
+ for (size_t index = 0; index < m_poolSize; ++index)
+ {
+ m_threadTaskHandles.push_back(Aws::New<ThreadTask>(POOLED_CLASS_TAG, *this));
+ }
+}
+
+PooledThreadExecutor::~PooledThreadExecutor()
+{
+ for(auto threadTask : m_threadTaskHandles)
+ {
+ threadTask->StopProcessingWork();
+ }
+
+ m_sync.ReleaseAll();
+
+ for (auto threadTask : m_threadTaskHandles)
+ {
+ Aws::Delete(threadTask);
+ }
+
+ while(m_tasks.size() > 0)
+ {
+ std::function<void()>* fn = m_tasks.front();
+ m_tasks.pop();
+
+ if(fn)
+ {
+ Aws::Delete(fn);
+ }
+ }
+
+}
+
+bool PooledThreadExecutor::SubmitToThread(std::function<void()>&& fn)
+{
+ //avoid the need to do copies inside the lock. Instead lets do a pointer push.
+ std::function<void()>* fnCpy = Aws::New<std::function<void()>>(POOLED_CLASS_TAG, std::forward<std::function<void()>>(fn));
+
+ {
+ std::lock_guard<std::mutex> locker(m_queueLock);
+
+ if (m_overflowPolicy == OverflowPolicy::REJECT_IMMEDIATELY && m_tasks.size() >= m_poolSize)
+ {
+ Aws::Delete(fnCpy);
+ return false;
+ }
+
+ m_tasks.push(fnCpy);
+ }
+
+ m_sync.Release();
+
+ return true;
+}
+
+std::function<void()>* PooledThreadExecutor::PopTask()
+{
+ std::lock_guard<std::mutex> locker(m_queueLock);
+
+ if (m_tasks.size() > 0)
+ {
+ std::function<void()>* fn = m_tasks.front();
+ if (fn)
+ {
+ m_tasks.pop();
+ return fn;
+ }
+ }
+
+ return nullptr;
+}
+
+bool PooledThreadExecutor::HasTasks()
+{
+ std::lock_guard<std::mutex> locker(m_queueLock);
+ return m_tasks.size() > 0;
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ReaderWriterLock.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ReaderWriterLock.cpp
new file mode 100644
index 0000000000..ddb5860563
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ReaderWriterLock.cpp
@@ -0,0 +1,64 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/threading/ReaderWriterLock.h>
+#include <cstdint>
+#include <limits>
+#include <cassert>
+
+using namespace Aws::Utils::Threading;
+
+static const int64_t MaxReaders = (std::numeric_limits<std::int32_t>::max)();
+
+ReaderWriterLock::ReaderWriterLock() :
+ m_readers(0),
+ m_holdouts(0),
+ m_readerSem(0, static_cast<size_t>(MaxReaders)),
+ m_writerSem(0, 1)
+{
+}
+
+void ReaderWriterLock::LockReader()
+{
+ if (++m_readers < 0)
+ {
+ m_readerSem.WaitOne();
+ }
+}
+
+void ReaderWriterLock::UnlockReader()
+{
+ if (--m_readers < 0 && --m_holdouts == 0)
+ {
+ m_writerSem.Release();
+ }
+}
+
+void ReaderWriterLock::LockWriter()
+{
+ m_writerLock.lock();
+ if(const auto current = m_readers.fetch_sub(MaxReaders))
+ {
+ assert(current > 0);
+ const auto holdouts = m_holdouts.fetch_add(current) + current;
+ assert(holdouts >= 0);
+ if(holdouts > 0)
+ {
+ m_writerSem.WaitOne();
+ }
+ }
+}
+
+void ReaderWriterLock::UnlockWriter()
+{
+ assert(m_holdouts == 0);
+ const auto current = m_readers.fetch_add(MaxReaders) + MaxReaders;
+ assert(current >= 0);
+ for(int64_t r = 0; r < current; r++)
+ {
+ m_readerSem.Release();
+ }
+ m_writerLock.unlock();
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Semaphore.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Semaphore.cpp
new file mode 100644
index 0000000000..86dabc9acf
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/Semaphore.cpp
@@ -0,0 +1,39 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/threading/Semaphore.h>
+#include <algorithm>
+
+using namespace Aws::Utils::Threading;
+
+Semaphore::Semaphore(size_t initialCount, size_t maxCount)
+ : m_count(initialCount), m_maxCount(maxCount)
+{
+}
+
+void Semaphore::WaitOne()
+{
+ std::unique_lock<std::mutex> locker(m_mutex);
+ if(0 == m_count)
+ {
+ m_syncPoint.wait(locker, [this] { return m_count > 0; });
+ }
+ --m_count;
+}
+
+void Semaphore::Release()
+{
+ std::lock_guard<std::mutex> locker(m_mutex);
+ m_count = (std::min)(m_maxCount, m_count + 1);
+ m_syncPoint.notify_one();
+}
+
+void Semaphore::ReleaseAll()
+{
+ std::lock_guard<std::mutex> locker(m_mutex);
+ m_count = m_maxCount;
+ m_syncPoint.notify_all();
+}
+
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ThreadTask.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ThreadTask.cpp
new file mode 100644
index 0000000000..a899fe045d
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/threading/ThreadTask.cpp
@@ -0,0 +1,46 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/threading/ThreadTask.h>
+#include <aws/core/utils/threading/Executor.h>
+
+using namespace Aws::Utils;
+using namespace Aws::Utils::Threading;
+
+ThreadTask::ThreadTask(PooledThreadExecutor& executor) : m_continue(true), m_executor(executor), m_thread(std::bind(&ThreadTask::MainTaskRunner, this))
+{
+}
+
+ThreadTask::~ThreadTask()
+{
+ StopProcessingWork();
+ m_thread.join();
+}
+
+void ThreadTask::MainTaskRunner()
+{
+ while (m_continue)
+ {
+ while (m_continue && m_executor.HasTasks())
+ {
+ auto fn = m_executor.PopTask();
+ if(fn)
+ {
+ (*fn)();
+ Aws::Delete(fn);
+ }
+ }
+
+ if(m_continue)
+ {
+ m_executor.m_sync.WaitOne();
+ }
+ }
+}
+
+void ThreadTask::StopProcessingWork()
+{
+ m_continue = false;
+}
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp
new file mode 100644
index 0000000000..c06befaf9b
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/utils/xml/XmlSerializer.cpp
@@ -0,0 +1,302 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/utils/xml/XmlSerializer.h>
+
+#include <aws/core/utils/StringUtils.h>
+#include <aws/core/external/tinyxml2/tinyxml2.h>
+
+#include <utility>
+#include <algorithm>
+#include <iostream>
+
+using namespace Aws::Utils::Xml;
+using namespace Aws::Utils;
+
+Aws::String Aws::Utils::Xml::DecodeEscapedXmlText(const Aws::String& textToDecode)
+{
+ Aws::String decodedString = textToDecode;
+ StringUtils::Replace(decodedString, "&quot;", "\"");
+ StringUtils::Replace(decodedString, "&apos;", "'");
+ StringUtils::Replace(decodedString, "&lt;", "<");
+ StringUtils::Replace(decodedString, "&gt;", ">");
+ StringUtils::Replace(decodedString, "&amp;", "&");
+
+ return decodedString;
+}
+
+XmlNode::XmlNode(const XmlNode& other) : m_node(other.m_node), m_doc(other.m_doc)
+{
+}
+
+XmlNode& XmlNode::operator=(const XmlNode& other)
+{
+ if(this == &other)
+ {
+ return *this;
+ }
+
+ m_node = other.m_node;
+ m_doc = other.m_doc;
+
+ return *this;
+}
+
+const Aws::String XmlNode::GetName() const
+{
+ return m_node->Value();
+}
+
+void XmlNode::SetName(const Aws::String& name)
+{
+ m_node->SetValue(name.c_str(), false);
+}
+
+const Aws::String XmlNode::GetAttributeValue(const Aws::String& name) const
+{
+ auto pointer = m_node->ToElement()->Attribute(name.c_str(), nullptr);
+ return pointer ? pointer : "";
+}
+
+void XmlNode::SetAttributeValue(const Aws::String& name, const Aws::String& value)
+{
+ m_node->ToElement()->SetAttribute(name.c_str(), value.c_str());
+}
+
+bool XmlNode::HasNextNode() const
+{
+ return m_node->NextSibling() != nullptr;
+}
+
+XmlNode XmlNode::NextNode() const
+{
+ return XmlNode(m_node->NextSiblingElement(), *m_doc);
+}
+
+XmlNode XmlNode::NextNode(const char* name) const
+{
+ return XmlNode(m_node->NextSiblingElement(name), *m_doc);
+}
+
+XmlNode XmlNode::NextNode(const Aws::String& name) const
+{
+ return NextNode(name.c_str());
+}
+
+XmlNode XmlNode::FirstChild() const
+{
+ return XmlNode(m_node->FirstChildElement(), *m_doc);
+}
+
+XmlNode XmlNode::FirstChild(const char* name) const
+{
+ return XmlNode(m_node->FirstChildElement(name), *m_doc);
+}
+
+XmlNode XmlNode::FirstChild(const Aws::String& name) const
+{
+ return FirstChild(name.c_str());
+}
+
+bool XmlNode::HasChildren() const
+{
+ return !m_node->NoChildren();
+}
+
+XmlNode XmlNode::Parent() const
+{
+ return XmlNode(m_node->Parent()->ToElement(), *m_doc);
+}
+
+Aws::String XmlNode::GetText() const
+{
+ if (m_node != nullptr)
+ {
+ Aws::External::tinyxml2::XMLPrinter printer;
+ Aws::External::tinyxml2::XMLNode* node = m_node->FirstChild();
+ while (node != nullptr)
+ {
+ node->Accept(&printer);
+ node = node->NextSibling();
+ }
+
+ return printer.CStr();
+ }
+
+ return {};
+}
+
+void XmlNode::SetText(const Aws::String& textValue)
+{
+ if (m_node != nullptr)
+ {
+ Aws::External::tinyxml2::XMLText* text = m_doc->m_doc->NewText(textValue.c_str());
+ m_node->InsertEndChild(text);
+ }
+}
+
+XmlNode XmlNode::CreateChildElement(const Aws::String& name)
+{
+ Aws::External::tinyxml2::XMLElement* element = m_doc->m_doc->NewElement(name.c_str());
+ return XmlNode(m_node->InsertEndChild(element), *m_doc);
+}
+
+XmlNode XmlNode::CreateSiblingElement(const Aws::String& name)
+{
+ Aws::External::tinyxml2::XMLElement* element = m_doc->m_doc->NewElement(name.c_str());
+ return XmlNode(m_node->Parent()->InsertEndChild(element), *m_doc);
+}
+
+bool XmlNode::IsNull()
+{
+ return m_node == nullptr;
+}
+
+static const char* XML_SERIALIZER_ALLOCATION_TAG = "XmlDocument";
+
+XmlDocument::XmlDocument()
+{
+ m_doc = nullptr;
+}
+
+XmlDocument::XmlDocument(const XmlDocument& doc)
+{
+ if (doc.m_doc == nullptr)
+ {
+ m_doc = nullptr;
+ }
+ else
+ {
+ InitDoc();
+ doc.m_doc->DeepCopy(m_doc);
+ }
+}
+
+XmlDocument::XmlDocument(XmlDocument&& doc) : m_doc{ doc.m_doc } // take the innards
+{
+ doc.m_doc = nullptr; // leave nothing behind
+}
+
+XmlDocument& XmlDocument::operator=(const XmlDocument& other)
+{
+ if (this == &other)
+ {
+ return *this;
+ }
+
+ if (other.m_doc == nullptr)
+ {
+ if (m_doc != nullptr)
+ {
+ m_doc->Clear();
+ m_doc = nullptr;
+ }
+ }
+ else
+ {
+ if (m_doc == nullptr)
+ {
+ InitDoc();
+ }
+ else
+ {
+ m_doc->Clear();
+ }
+ other.m_doc->DeepCopy(m_doc);
+ }
+
+ return *this;
+}
+
+XmlDocument& XmlDocument::operator=(XmlDocument&& other)
+{
+ if (this == &other)
+ {
+ return *this;
+ }
+
+ std::swap(m_doc, other.m_doc);
+ return *this;
+}
+
+XmlDocument::~XmlDocument()
+{
+ if (m_doc)
+ {
+ Aws::Delete(m_doc);
+ }
+}
+
+void XmlDocument::InitDoc()
+{
+ m_doc = Aws::New<Aws::External::tinyxml2::XMLDocument>(XML_SERIALIZER_ALLOCATION_TAG, true, Aws::External::tinyxml2::Whitespace::PRESERVE_WHITESPACE);
+}
+
+XmlNode XmlDocument::GetRootElement() const
+{
+ if (m_doc)
+ {
+ return XmlNode(m_doc->FirstChildElement(), *this);
+ }
+ else
+ {
+ return XmlNode(nullptr, *this);
+ }
+
+}
+
+bool XmlDocument::WasParseSuccessful() const
+{
+ if (m_doc)
+ {
+ return !m_doc->Error();
+ }
+ else
+ {
+ return true;
+ }
+
+}
+
+Aws::String XmlDocument::GetErrorMessage() const
+{
+ return !WasParseSuccessful() ? m_doc->ErrorName() : "";
+}
+
+Aws::String XmlDocument::ConvertToString() const
+{
+ if (!m_doc) return "";
+
+ Aws::External::tinyxml2::XMLPrinter printer;
+ printer.PushHeader(false, true);
+ m_doc->Accept(&printer);
+
+ return printer.CStr();
+}
+
+XmlDocument XmlDocument::CreateFromXmlStream(Aws::IOStream& xmlStream)
+{
+ Aws::String xmlString((Aws::IStreamBufIterator(xmlStream)), Aws::IStreamBufIterator());
+ return CreateFromXmlString(xmlString);
+}
+
+XmlDocument XmlDocument::CreateFromXmlString(const Aws::String& xmlText)
+{
+ XmlDocument xmlDocument;
+ xmlDocument.InitDoc();
+ xmlDocument.m_doc->Parse(xmlText.c_str(), xmlText.size());
+ return xmlDocument;
+}
+
+XmlDocument XmlDocument::CreateWithRootNode(const Aws::String& rootNodeName)
+{
+ XmlDocument xmlDocument;
+ xmlDocument.InitDoc();
+ Aws::External::tinyxml2::XMLElement* rootNode = xmlDocument.m_doc->NewElement(rootNodeName.c_str());
+ xmlDocument.m_doc->LinkEndChild(rootNode);
+
+ return xmlDocument;
+}
+