EnvronmentManagement/ESP-Temp-Humidity/lib/utils/byte_buffer.cpp

200 lines
4.8 KiB
C++

#include <byte_buffer.h>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <osapi.h>
#include <libb64/cdecode.h>
#include <libb64/cencode.h>
namespace utils
{
byte_buffer::byte_buffer(uint_fast16_t length)
: _length(length)
{
// +1 to allow this to be safely printed as a char
_buffer = reinterpret_cast<unsigned char *>(std::calloc(length + 1, sizeof(unsigned char)));
}
byte_buffer::~byte_buffer()
{
clear_buffer();
std::free(_buffer);
}
const bool byte_buffer::is_valid()
{
return _buffer != nullptr;
}
unsigned char *byte_buffer::get_ptr()
{
if (is_valid())
{
return _buffer;
}
else
{
return nullptr;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// Get the length of the buffer.
//
// Returns: The length of the buffer, or 0 if the buffer is invalid.
/////////////////////////////////////////////////////////////////////////////////////////
const uint_fast16_t byte_buffer::get_length()
{
if (is_valid())
{
return _length;
}
else
{
return 0;
}
}
/////////////////////////////////////////////////////////////////////////////////////////
// Get a pointer to a location in the buffer, length is updated to show the length
// available in that buffer
//
// index: The location to get a pointer to.
// length: The length of the data you expect to access from this pointer.
//
// Returns: A ptr to the buffer, or nullptr if reading that much data would cause
// an overflow
/////////////////////////////////////////////////////////////////////////////////////////
unsigned char *byte_buffer::get_ptr(const uint_fast16_t index, uint_fast16_t &length)
{
unsigned char *ret = nullptr;
if (is_valid() && _length > index)
{
length = _length - index;
ret = &_buffer[index];
}
else
{
length = 0;
}
return ret;
}
// Copy data into this buffer. The index value is updated to the index of the next point in the buffer
const bool byte_buffer::copy_from(const void *const sourceBuffer, uint_fast16_t &index, const uint_fast16_t &length)
{
auto ret = false;
if (is_valid() &&
sourceBuffer != nullptr &&
(index + length) <= _length)
{
std::memcpy(_buffer + index, sourceBuffer, length);
index += length;
ret = true;
}
return ret;
}
// Copy data out of this buffer. The index value is updated to the index of the next point in the buffer
const bool byte_buffer::copy_to(void *destinationBuffer, uint_fast16_t &index, const uint_fast16_t &length)
{
auto ret = false;
if (is_valid() &&
destinationBuffer != nullptr &&
(index + length) < _length)
{
std::memcpy(destinationBuffer, _buffer + index, length);
index += length;
ret = true;
}
return ret;
}
const bool byte_buffer::clone(byte_buffer &bufferToClone)
{
auto ret = false;
if (is_valid() &&
bufferToClone.is_valid() &&
bufferToClone.get_length() <= _length)
{
std::memcpy(bufferToClone.get_ptr(), 0, bufferToClone.get_length());
ret = true;
}
return ret;
}
const void byte_buffer::clear_buffer()
{
if (is_valid())
{
std::fill(_buffer, _buffer + _length, 0);
}
}
const void byte_buffer::fill_random()
{
if (is_valid())
{
os_get_random(_buffer, _length);
}
}
// Return the size of the data stored
const uint_fast16_t byte_buffer::load_base64(std::string base64Data)
{
auto read = 0u;
if (is_valid() && _length >= base64_decode_expected_len(base64Data.length()))
{
base64_decodestate state;
base64_init_decodestate(&state);
read = base64_decode_block(base64Data.c_str(), base64Data.length(), reinterpret_cast<char *>(_buffer), &state);
}
return read;
}
//// Get a base64 encoded string of this buffer.
const std::string byte_buffer::get_base64()
{
if (!is_valid())
{
return "";
}
auto b64String = std::string("");
auto size = base64_encode_expected_len_nonewlines(_length) + 1;
auto buffer = reinterpret_cast<char *>(std::calloc(size, 1));
if (buffer != nullptr)
{
base64_encodestate state;
base64_init_encodestate_nonewlines(&state);
auto encoded = base64_encode_block(reinterpret_cast<const char *>(_buffer), _length, buffer, &state);
encoded = base64_encode_blockend(buffer + encoded, &state);
b64String = std::string(buffer);
std::free(buffer);
}
return b64String;
}
const std::string byte_buffer::to_string()
{
if (!is_valid())
{
return "";
}
// Make sure that extra byte really is null!
_buffer[_length] = '\0';
return std::string(reinterpret_cast<char *>(_buffer));
}
} // namespace Control_System