dai_env / include /aws /core /utils /Array.h
Shenghong's picture
Add files using upload-large-folder tool
bfd87b5 verified
Raw
History Blame Contribute Delete
9.69 kB
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/
#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 // _WIN32
namespace Aws
{
namespace Utils
{
static const char* ARRAY_ALLOCATION_TAG = "Aws::Array";
/**
* Safe array class with move and copy semantics.
*/
template<typename T>
class Array
{
public:
/**
* Create new empty array of size arraySize. Default argument is 0. If it is empty then no allocation happens.
*/
Array(size_t arraySize = 0) :
m_capacity(arraySize),
m_length(arraySize),
m_data(arraySize > 0 ? Aws::MakeUniqueArray<T>(arraySize, ARRAY_ALLOCATION_TAG) : nullptr)
{
}
/**
* Create new array and initialize it to a raw array
*/
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());
}
}
/**
* Create new array with a pointer and its dimensions.
*/
Array(size_t capacity,
size_t length,
UniqueArrayPtr<T> data)
: m_capacity(capacity),
m_length(length),
m_data(std::move(data))
{
}
/**
* Merge multiple arrays into one
*/
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());
}
}
//move c_tor
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;
/**
* Buffer for cryptographic operations. It zeroes itself back out upon deletion. Everything else is identical
* to byte buffer.
*/
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)
{
// Crt::ByteBuf must be allocated using SDK not CRT allocator
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
{
// Crt::ByteBuf must be allocated using SDK not CRT allocator
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();
};
} // namespace Utils
} // namespace Aws