| |
| |
| |
| |
|
|
| #pragma once |
|
|
| #include <aws/core/Core_EXPORTS.h> |
|
|
| #include <aws/core/utils/memory/AWSMemory.h> |
| #include <aws/core/utils/memory/stl/AWSVector.h> |
| #include <aws/core/utils/memory/stl/AWSString.h> |
| #include <aws/crt/Types.h> |
| #include <memory> |
| #include <cassert> |
| #include <cstring> |
| #include <algorithm> |
|
|
| #ifdef _WIN32 |
|
|
| #include <iterator> |
|
|
| #endif |
|
|
| namespace Aws |
| { |
| namespace Utils |
| { |
| static const char* ARRAY_ALLOCATION_TAG = "Aws::Array"; |
|
|
| |
| |
| |
| template<typename T> |
| class Array |
| { |
|
|
| public: |
| |
| |
| |
| Array(size_t arraySize = 0) : |
| m_capacity(arraySize), |
| m_length(arraySize), |
| m_data(arraySize > 0 ? Aws::MakeUniqueArray<T>(arraySize, ARRAY_ALLOCATION_TAG) : nullptr) |
| { |
| } |
|
|
| |
| |
| |
| Array(const T* arrayToCopy, size_t arraySize) : |
| m_capacity(arraySize), |
| m_length(arraySize), |
| m_data(nullptr) |
| { |
| if (arrayToCopy != nullptr && m_capacity > 0) |
| { |
| m_data.reset(Aws::NewArray<T>(m_capacity, ARRAY_ALLOCATION_TAG)); |
| std::copy(arrayToCopy, arrayToCopy + arraySize, m_data.get()); |
| } |
| } |
|
|
| |
| |
| |
| Array(size_t capacity, |
| size_t length, |
| UniqueArrayPtr<T> data) |
| : m_capacity(capacity), |
| m_length(length), |
| m_data(std::move(data)) |
| { |
| } |
|
|
| |
| |
| |
| Array(Aws::Vector<Array*>&& toMerge) |
| { |
| size_t totalSize = 0; |
| for(auto& array : toMerge) |
| { |
| totalSize += array->m_length; |
| } |
|
|
| m_capacity = totalSize; |
| m_data.reset(Aws::NewArray<T>(m_capacity, ARRAY_ALLOCATION_TAG)); |
|
|
| size_t location = 0; |
| for(auto& arr : toMerge) |
| { |
| if(arr->m_capacity > 0 && arr->m_data) |
| { |
| size_t arraySize = arr->m_length; |
| std::copy(arr->m_data.get(), arr->m_data.get() + arraySize, m_data.get() + location); |
| location += arraySize; |
| } |
| } |
| m_length = location; |
| } |
|
|
| Array(const Array& other) |
| { |
| m_capacity = other.m_capacity; |
| m_length = other.m_length; |
| m_data = nullptr; |
|
|
| if (m_capacity > 0) |
| { |
| m_data.reset(Aws::NewArray<T>(m_capacity, ARRAY_ALLOCATION_TAG)); |
| std::copy(other.m_data.get(), other.m_data.get() + other.m_capacity, m_data.get()); |
| } |
| } |
|
|
| |
| Array(Array&& other) noexcept: |
| m_capacity(other.m_capacity), |
| m_length(other.m_length), |
| m_data(std::move(other.m_data)) |
| { |
| other.m_capacity = 0; |
| other.m_data = nullptr; |
| } |
|
|
| virtual ~Array() = default; |
|
|
| Array& operator=(const Array& other) |
| { |
| if (this == &other) |
| { |
| return *this; |
| } |
|
|
| m_capacity = other.m_capacity; |
| m_length = other.m_length; |
| m_data = nullptr; |
|
|
| if (m_capacity > 0) |
| { |
| m_data.reset(Aws::NewArray<T>(m_capacity, ARRAY_ALLOCATION_TAG)); |
| std::copy(other.m_data.get(), other.m_data.get() + other.m_length, m_data.get()); |
| } |
|
|
| return *this; |
| } |
|
|
| Array& operator=(Array&& other) noexcept |
| { |
| m_capacity = other.m_capacity; |
| m_length = other.m_length; |
| m_data = std::move(other.m_data); |
|
|
| return *this; |
| } |
|
|
| Array(const Aws::String& string): |
| m_capacity(string.capacity()), |
| m_length(string.length()), |
| m_data(nullptr) |
| { |
| m_data.reset(Aws::NewArray<unsigned char>(m_capacity, ARRAY_ALLOCATION_TAG)); |
| std::copy(string.c_str(), string.c_str() + string.length(), m_data.get()); |
| } |
|
|
| bool operator==(const Array& other) const |
| { |
| if (this == &other) |
| return true; |
|
|
| if (m_capacity == 0 && other.m_capacity == 0) |
| { |
| return true; |
| } |
|
|
| if (m_length != other.m_length) |
| { |
| return false; |
| } |
|
|
| if (m_length == other.m_length && m_capacity == other.m_capacity && m_data && other.m_data) |
| { |
| for (unsigned i = 0; i < m_length; ++i) |
| { |
| if (m_data.get()[i] != other.m_data.get()[i]) |
| return false; |
| } |
|
|
| return true; |
| } |
|
|
| return false; |
| } |
|
|
| bool operator!=(const Array& other) const |
| { |
| return !(*this == other); |
| } |
|
|
| T const& GetItem(size_t index) const |
| { |
| assert(index < m_length); |
| return m_data.get()[index]; |
| } |
|
|
| T& GetItem(size_t index) |
| { |
| assert(index < m_length); |
| return m_data.get()[index]; |
| } |
|
|
| T& operator[](size_t index) |
| { |
| return GetItem(index); |
| } |
|
|
| T const& operator[](size_t index) const |
| { |
| return GetItem(index); |
| } |
|
|
| inline size_t GetLength() const |
| { |
| return m_length; |
| } |
|
|
| inline size_t GetSize() const |
| { |
| return m_capacity; |
| } |
|
|
| inline T* GetUnderlyingData() const |
| { |
| return m_data.get(); |
| } |
|
|
| inline void SetLength(size_t len) |
| { |
| m_length = len; |
| } |
|
|
| protected: |
| size_t m_capacity = 0; |
| size_t m_length = 0; |
| Aws::UniqueArrayPtr<T> m_data; |
| }; |
|
|
| typedef Array<unsigned char> ByteBuffer; |
|
|
| |
| |
| |
| |
| class AWS_CORE_API CryptoBuffer : public ByteBuffer |
| { |
| public: |
| CryptoBuffer(size_t arraySize = 0) : ByteBuffer(arraySize) {} |
| CryptoBuffer(const unsigned char* arrayToCopy, size_t arraySize) : ByteBuffer(arrayToCopy, arraySize) {} |
| CryptoBuffer(Aws::Vector<ByteBuffer*>&& toMerge) : ByteBuffer(std::move(toMerge)) {} |
| CryptoBuffer(const ByteBuffer& other) : ByteBuffer(other) {} |
| CryptoBuffer(const CryptoBuffer& other) : ByteBuffer(other) {} |
| CryptoBuffer(CryptoBuffer&& other) : ByteBuffer(std::move(other)) {} |
| CryptoBuffer& operator=(const CryptoBuffer& other) { Zero(); ByteBuffer::operator=(other); return *this; } |
| CryptoBuffer& operator=(CryptoBuffer&& other) { Zero(); ByteBuffer::operator=(std::move(other)); return *this; } |
|
|
| CryptoBuffer(Crt::ByteBuf&& other) noexcept : ByteBuffer( |
| other.len, |
| other.len, |
| nullptr) |
| { |
| |
| assert(get_aws_allocator() == other.allocator); |
| m_data.reset(other.buffer); |
| other.capacity = 0; |
| other.len = 0; |
| other.allocator = nullptr; |
| other.buffer = nullptr; |
| } |
|
|
| CryptoBuffer& operator=(Crt::ByteBuf&& other) noexcept |
| { |
| |
| assert(get_aws_allocator() == other.allocator); |
| m_capacity = other.len; |
| m_length = other.len; |
| m_data.reset(other.buffer); |
| other.capacity = 0; |
| other.len = 0; |
| other.allocator = nullptr; |
| other.buffer = nullptr; |
| return *this; |
| } |
|
|
| bool operator==(const CryptoBuffer& other) const { return ByteBuffer::operator==(other); } |
| bool operator!=(const CryptoBuffer& other) const { return ByteBuffer::operator!=(other); } |
|
|
| ~CryptoBuffer() override { Zero(); } |
|
|
| Array<CryptoBuffer> Slice(size_t sizeOfSlice) const; |
| CryptoBuffer& operator^(const CryptoBuffer& operand); |
| void Zero(); |
| }; |
|
|
| } |
| } |
|
|