/*
* Copyright (C) 2020 Embedded AMS B.V. - All Rights Reserved
*
* This file is part of Embedded Proto.
*
* Embedded Proto is open source software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation, version 3 of the license.
*
* Embedded Proto is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Embedded Proto. If not, see .
*
* For commercial and closed source application please visit:
* .
*
* Embedded AMS B.V.
* Info:
* info at EmbeddedProto dot com
*
* Postal address:
* Johan Huizingalaan 763a
* 1066 VH, Amsterdam
* the Netherlands
*/
#ifndef _REPEATED_FIELD_SIZE_H_
#define _REPEATED_FIELD_SIZE_H_
#include "RepeatedField.h"
#include "Errors.h"
#include
#include
#include
namespace EmbeddedProto
{
//! A template class that actually holds some data.
/*!
This is a separate class to make it possible to not have the size defined in every function or
class using this type of object.
*/
template
class RepeatedFieldFixedSize : public RepeatedField
{
static constexpr uint32_t BYTES_PER_ELEMENT = sizeof(DATA_TYPE);
public:
RepeatedFieldFixedSize()
: current_length_(0),
data_{}
{
}
~RepeatedFieldFixedSize() override = default;
//! Assign one repieted field to the other, but only when the length and type matches.
RepeatedFieldFixedSize& operator=(const
RepeatedFieldFixedSize& rhs)
{
for(uint32_t i = 0; i < rhs.get_length(); ++i)
{
data_[i] = rhs.get_const(i);
}
current_length_ = rhs.get_length();
return *this;
}
//! Obtain the total number of DATA_TYPE items in the array.
uint32_t get_length() const override { return current_length_; }
//! Obtain the maximum number of DATA_TYPE items which can at most be stored in the array.
uint32_t get_max_length() const override { return MAX_LENGTH; }
//! Obtain the total number of bytes currently stored in the array.
uint32_t get_size() const override { return BYTES_PER_ELEMENT * current_length_; }
//! Obtain the maximum number of bytes which can at most be stored in the array.
uint32_t get_max_size() const override { return BYTES_PER_ELEMENT * MAX_LENGTH; }
DATA_TYPE& get(uint32_t index) override
{
uint32_t limited_index = std::min(index, MAX_LENGTH-1);
// Check if we need to update the number of elements in the array.
if(limited_index >= current_length_) {
current_length_ = limited_index + 1;
}
return data_[limited_index];
}
const DATA_TYPE& get_const(uint32_t index) const override
{
uint32_t limited_index = std::min(index, MAX_LENGTH-1);
return data_[limited_index];
}
void set(uint32_t index, const DATA_TYPE& value) override
{
uint32_t limited_index = std::min(index, MAX_LENGTH-1);
// Check if we need to update the number of elements in the array.
if(limited_index >= current_length_) {
current_length_ = limited_index + 1;
}
data_[limited_index] = value;
}
Error set_data(const DATA_TYPE* data, const uint32_t length) override
{
Error return_value = Error::NO_ERRORS;
if(MAX_LENGTH >= length)
{
const DATA_TYPE* d = data;
for(uint32_t i = 0; i < length; ++i)
{
data_[i] = *d;
++d;
}
current_length_ = length;
}
else
{
return_value = Error::ARRAY_FULL;
}
return return_value;
}
Error add(const DATA_TYPE& value) override
{
Error return_value = Error::NO_ERRORS;
if(MAX_LENGTH > current_length_)
{
data_[current_length_] = value;
++current_length_;
}
else
{
return_value = Error::ARRAY_FULL;
}
return return_value;
}
void clear() override
{
for(uint32_t i = 0; i < current_length_; ++i)
{
data_[i].clear();
}
current_length_ = 0;
}
private:
//! Number of item in the data array.
uint32_t current_length_;
//! The actual data
DATA_TYPE data_[MAX_LENGTH];
};
} // End of namespace EmbeddedProto
#endif // End of _REPEATED_FIELD_SIZE_H_