new initializer list ctor #72

Merged
muellerr merged 4 commits from KSat/fsfw:mueller_initializer_list into master 2020-07-07 12:10:54 +02:00
4 changed files with 111 additions and 78 deletions
Showing only changes of commit cef5fda379 - Show all commits

View File

@ -1,26 +1,34 @@
#include <framework/datapool/PoolEntry.h> #include <framework/datapool/PoolEntry.h>
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/globalfunctions/printer.h>
#include <cstring>
template <typename T> template <typename T>
PoolEntry<T>::PoolEntry(std::initializer_list<T> initValue, uint8_t set_length, PoolEntry<T>::PoolEntry(std::initializer_list<T> initValue, uint8_t setLength,
uint8_t set_valid ) : length(set_length), valid(set_valid) { bool setValid ) : length(setLength), valid(setValid) {
this->address = new T[this->length]; this->address = new T[this->length];
if(initValue.size() == 0) { if(initValue.size() == 0) {
memset(this->address, 0, this->getByteSize()); std::memset(this->address, 0, this->getByteSize());
}
else if (initValue.size() != setLength){
sif::warning << "PoolEntry: setLength is not equal to initializer list"
"length! Performing zero initialization with given setLength"
<< std::endl;
std::memset(this->address, 0, this->getByteSize());
} }
else { else {
memcpy(this->address, initValue.begin(), this->getByteSize()); std::copy(initValue.begin(), initValue.end(), this->address);
} }
} }
template <typename T> template <typename T>
PoolEntry<T>::PoolEntry( T* initValue, uint8_t set_length, uint8_t set_valid ) : PoolEntry<T>::PoolEntry( T* initValue, uint8_t setLength, bool setValid ) :
length(set_length), valid(set_valid) { length(setLength), valid(setValid) {
this->address = new T[this->length]; this->address = new T[this->length];
if (initValue != nullptr) { if (initValue != nullptr) {
memcpy(this->address, initValue, this->getByteSize() ); std::memcpy(this->address, initValue, this->getByteSize() );
} else { } else {
memset(this->address, 0, this->getByteSize() ); std::memset(this->address, 0, this->getByteSize() );
} }
} }
@ -47,21 +55,20 @@ void* PoolEntry<T>::getRawData() {
} }
template <typename T> template <typename T>
void PoolEntry<T>::setValid( uint8_t isValid ) { void PoolEntry<T>::setValid(bool isValid) {
this->valid = isValid; this->valid = isValid;
} }
template <typename T> template <typename T>
uint8_t PoolEntry<T>::getValid() { bool PoolEntry<T>::getValid() {
return valid; return valid;
} }
template <typename T> template <typename T>
void PoolEntry<T>::print() { void PoolEntry<T>::print() {
for (uint8_t size = 0; size < this->length; size++ ) { sif::debug << "Pool Entry Validity: " <<
sif::debug << "| " << std::hex << (double)this->address[size] (this->valid? " (valid) " : " (invalid) ") << std::endl;
<< (this->valid? " (valid) " : " (invalid) "); printer::print(reinterpret_cast<uint8_t*>(address), length);
}
sif::debug << std::dec << std::endl; sif::debug << std::dec << std::endl;
} }

View File

@ -1,59 +1,86 @@
#ifndef POOLENTRY_H_ #ifndef FRAMEWORK_DATAPOOL_POOLENTRY_H_
#define POOLENTRY_H_ #define FRAMEWORK_DATAPOOL_POOLENTRY_H_
#include <framework/datapool/PoolEntryIF.h> #include <framework/datapool/PoolEntryIF.h>
#include <cstddef>
#include <cstring>
#include <initializer_list> #include <initializer_list>
#include <type_traits> #include <type_traits>
#include <cstddef>
/** /**
* @brief This is a small helper class that defines a single data pool entry. * @brief This is a small helper class that defines a single data pool entry.
* @details * @details
* The helper is used to store all information together with the data as a * The helper is used to store all information together with the data as a
* single data pool entry.The content's type is defined by the template argument. * single data pool entry. The content's type is defined by the template
* It is prepared for use with plain old data types, but may be extended to * argument.
* complex types if necessary. It can be initialized with a certain value, *
* size and validity flag. It holds a pointer to the real data and offers * It is prepared for use with plain old data types, but may be
* methods to access this data and to acquire additional information * extended to complex types if necessary. It can be initialized with a
* (such as validity and array/byte size). It is NOT intended to be used * certain value, size and validity flag.
* outside the DataPool class. *
* It holds a pointer to the real data and offers methods to access this data
* and to acquire additional information (such as validity and array/byte size).
* It is NOT intended to be used outside DataPool implementations as it performs
* dynamic memory allocation.
* *
* @ingroup data_pool * @ingroup data_pool
*
*/ */
template <typename T> template <typename T>
class PoolEntry : public PoolEntryIF { class PoolEntry : public PoolEntryIF {
public: public:
static_assert(not std::is_same<T, bool>::value, static_assert(not std::is_same<T, bool>::value,
Review

Is this compiler warning okay?

Is this compiler warning okay?
"Do not use boolean for the PoolEntry type, use uint8_t instead!" "Do not use boolean for the PoolEntry type, use uint8_t "
"Warum? Darum :-)"); "instead! The ECSS standard defines a boolean as a one bit "
"field. Therefore it is preferred to store a boolean as an "
"uint8_t");
/** /**
* @brief In the classe's constructor, space is allocated on the heap and * @brief In the classe's constructor, space is allocated on the heap and
* potential init values are copied to that space. * potential init values are copied to that space.
* @param initValue Initializer list with values to initialize with * @details
* @param set_length Defines the array length of this entry. * Not passing any arguments will initialize an non-array pool entry
* @param set_valid Sets the initialization flag. * (setLength = 1) with an initial invalid state.
* It is invalid (0) by default. * Please note that if an initializer list is passed, the correct
* corresponding length should be passed too, otherwise a zero
* initialization will be performed with the given setLength.
* @param initValue
* Initializer list with values to initialize with, for example {0,0} to
* initialize the two entries to zero.
* @param setLength
* Defines the array length of this entry. Should be equal to the
* intializer list length.
* @param setValid
* Sets the initialization flag. It is invalid by default.
*/ */
PoolEntry(std::initializer_list<T> initValue = {}, uint8_t set_length = 1, PoolEntry(std::initializer_list<T> initValue = {}, uint8_t setLength = 1,
uint8_t set_valid = 0); bool setValid = false);
Review

I don't see a reason not to use booleans for the interface. Even if the valid flag is stored internally as an uint8_, the passed value will be implictely converted.

I don't see a reason not to use booleans for the interface. Even if the valid flag is stored internally as an uint8_, the passed value will be implictely converted.
/** /**
* @brief In the classe's constructor, space is allocated on the heap and * @brief In the classe's constructor, space is allocated on the heap and
* potential init values are copied to that space. * potential init values are copied to that space.
* @param initValue A pointer to the single value or array that holds * @param initValue
* the init value. With the default value (nullptr), the entry is * A pointer to the single value or array that holds the init value.
* initalized with all 0. * With the default value (nullptr), the entry is initalized with all 0.
* @param set_length Defines the array length of this entry. * @param setLength
* @param set_valid Sets the initialization flag. It is invalid (0) by default. * Defines the array length of this entry.
* @param setValid
* Sets the initialization flag. It is invalid by default.
*/ */
PoolEntry(T* initValue = nullptr, uint8_t set_length = 1, uint8_t set_valid = 0); PoolEntry(T* initValue, uint8_t setLength = 1, bool setValid = false);
//! Explicitely deleted copy ctor, copying is not allowed!
PoolEntry(const PoolEntry&) = delete;
//! Explicitely deleted copy assignment, copying is not allowed!
PoolEntry& operator=(const PoolEntry&) = delete;
/** /**
* @brief The allocated memory for the variable is freed in the destructor. * @brief The allocated memory for the variable is freed
* @details As the data pool is global, this dtor is only called on program exit. * in the destructor.
* PoolEntries shall never be copied, as a copy might delete the variable on the heap. * @details
* As the data pool is global, this dtor is only called on program exit.
* PoolEntries shall never be copied, as a copy might delete the variable
* on the heap.
*/ */
~PoolEntry(); ~PoolEntry();
/** /**
* @brief This is the address pointing to the allocated memory. * @brief This is the address pointing to the allocated memory.
*/ */
@ -82,13 +109,15 @@ public:
*/ */
void* getRawData(); void* getRawData();
/** /**
* @brief This method allows to set the valid information of the pool entry. * @brief This method allows to set the valid information
* of the pool entry.
*/ */
void setValid( uint8_t isValid ); void setValid( bool isValid );
/** /**
* @brief This method allows to get the valid information of the pool entry. * @brief This method allows to get the valid information
* of the pool entry.
*/ */
uint8_t getValid(); bool getValid();
/** /**
* @brief This is a debug method that prints all values and the valid * @brief This is a debug method that prints all values and the valid
* information to the screen. It prints all array entries in a row. * information to the screen. It prints all array entries in a row.

View File

@ -1,62 +1,57 @@
/** #ifndef FRAMEWORK_DATAPOOL_POOLENTRYIF_H_
* \file PoolEntryIF.h #define FRAMEWORK_DATAPOOL_POOLENTRYIF_H_
*
* \brief This file holds the class that defines the Interface for Pool Entry elements.
*
* \date 10/18/2012
*
* \author Bastian Baetz
*/
#ifndef POOLENTRYIF_H_
#define POOLENTRYIF_H_
#include <framework/globalfunctions/Type.h> #include <framework/globalfunctions/Type.h>
#include <stdint.h> #include <cstdint>
/** /**
* \brief This interface defines the access possibilities to a single data pool entry. * @brief This interface defines the access possibilities to a
* single data pool entry.
* @details
* The interface provides methods to determine the size and the validity
* information of a value. It also defines a method to receive a pointer to the
* raw data content. It is mainly used by DataPool itself, but also as a
* return pointer.
* *
* \details The interface provides methods to determine the size and the validity information of a value. * @author Bastian Baetz
* It also defines a method to receive a pointer to the raw data content. * @ingroup data_pool
* It is mainly used by DataPool itself, but also as a return pointer.
*
* \ingroup data_pool
* *
*/ */
class PoolEntryIF { class PoolEntryIF {
public: public:
/** /**
* \brief This is an empty virtual destructor, as it is proposed for C++ interfaces. * @brief This is an empty virtual destructor,
* as it is required for C++ interfaces.
*/ */
virtual ~PoolEntryIF() { virtual ~PoolEntryIF() {
} }
/** /**
* \brief getSize returns the array size of the entry. A single variable parameter has size 1. * @brief getSize returns the array size of the entry.
* A single variable parameter has size 1.
*/ */
virtual uint8_t getSize() = 0; virtual uint8_t getSize() = 0;
/** /**
* \brief This operation returns the size in bytes, which is calculated by * @brief This operation returns the size in bytes, which is calculated by
* sizeof(type) * array_size. * sizeof(type) * array_size.
*/ */
virtual uint16_t getByteSize() = 0; virtual uint16_t getByteSize() = 0;
/** /**
* \brief This operation returns a the address pointer casted to void*. * @brief This operation returns a the address pointer casted to void*.
*/ */
virtual void* getRawData() = 0; virtual void* getRawData() = 0;
/** /**
* \brief This method allows to set the valid information of the pool entry. * @brief This method allows to set the valid information of the pool entry.
*/ */
virtual void setValid(uint8_t isValid) = 0; virtual void setValid(bool isValid) = 0;
Review

I don't see a reason not to use booleans for the interface. the underlying implementation can still use an uint8_t, ENUM or something else.

I don't see a reason not to use booleans for the interface. the underlying implementation can still use an uint8_t, ENUM or something else.
/** /**
* \brief This method allows to set the valid information of the pool entry. * @brief This method allows to set the valid information of the pool entry.
*/ */
virtual uint8_t getValid() = 0; virtual bool getValid() = 0;
/** /**
* \brief This is a debug method that prints all values and the valid information to the screen. * @brief This is a debug method that prints all values and the valid
* It prints all array entries in a row. * information to the screen. It prints all array entries in a row.
* @details
* Also displays whether the pool entry is valid or invalid.
*/ */
virtual void print() = 0; virtual void print() = 0;
/** /**

View File

@ -4,6 +4,8 @@
#include <framework/serviceinterface/ServiceInterfaceStream.h> #include <framework/serviceinterface/ServiceInterfaceStream.h>
#include <framework/osal/Endiness.h> #include <framework/osal/Endiness.h>
#include <cstring>
PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry, PoolRawAccess::PoolRawAccess(uint32_t set_id, uint8_t setArrayEntry,
DataSetIF* data_set, ReadWriteMode_t setReadWriteMode) : DataSetIF* data_set, ReadWriteMode_t setReadWriteMode) :
dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), type(Type::UNKNOWN_TYPE), typeSize( dataPoolId(set_id), arrayEntry(setArrayEntry), valid(false), type(Type::UNKNOWN_TYPE), typeSize(