Pusher.hh 6.64 KB
/*
 * Pusher.hh
 *
 *  Created on: Jan 30, 2019
 *      Author: AKKA
 */

#ifndef PUSHER_H_
#define PUSHER_H_

#include <vector>
#include "ParamData.hh"


#include "ConstantParamData.hh"

namespace AMDA {
namespace ConstantInterface {

int getNbDataByPacket(ConstantParamType paramType, int dim1, int dim2);

/**
 * @class PusherBase
 * @details This class is the operation responsible to transform raw data from local file into a ParamData
 * of the corresponding type ( scalar or vector of short or int or float or double or ... type).
 */
struct PusherBase {
public:
	/*
	 * @brief Constructor
	 */
	PusherBase (double sampling, double value, int dim1 = 1, int dim2 = 1) : _paramData(NULL), _sampling(sampling), _value(value), _dim1(dim1), _dim2(dim2), _nbDataByPacket(PARAMPACKET_MIN_NBDATABYPACKET)
	{
	}

	/*
	 * @brief Destructor
	 */
	virtual ~PusherBase()
	{
	}

	/*
	 * @brief Get the ParamData
	 */
	AMDA::Parameters::ParamData* getParamData(void)
	{
		return _paramData;
	}

	/*
	 * @brief Virtual method to put a packet in the ParamData
	 */
	virtual int put(double startTime, double stopTime, int lastIndex) = 0;

protected:
	/*
	 * @brief Pointer to the paramData
	 */
	AMDA::Parameters::ParamData* _paramData;

	/*
	 * @brief Sampling value
	 */
	double _sampling;

	/*
	 * @brief Constant value
	 */
	double _value;

	/*
	 * @brief For Vector and Tab2D dimension
	 */
	int _dim1;

	/*
	 * @brief For Tab2D dimension
	 */
	int _dim2;

	/*
	 * @brief Nb data returned by one packet
	 */
	int _nbDataByPacket;
};


template <ConstantParamType type>
struct MapType { typedef void Type; };

template <> struct MapType<ConstantParamType::TYPE_SHORT>  { typedef short Type; };
template <> struct MapType<ConstantParamType::TYPE_INT>  { typedef int Type; };
template <> struct MapType<ConstantParamType::TYPE_FLOAT>  { typedef float Type; };
template <> struct MapType<ConstantParamType::TYPE_DOUBLE> { typedef double Type; };


template<ConstantParamType type, ConstantContainerType container = CONTAINER_VECTOR>
class Pusher;

/**
 * @brief Pusher implementation for the Tab2D.
 */
template<ConstantParamType type>
class Pusher<type,CONTAINER_MATRIX> : public PusherBase
{
public:
	/*
	 * @brief Define some usefull types
	 */
	typedef typename MapType<type>::Type BaseElemenType;
	typedef AMDA::Parameters::Tab2DData<BaseElemenType> ElemenType;
	typedef AMDA::Parameters::ParamDataSpec<ElemenType> SpecParamData;

	SpecParamData* _specParamData;

	/*
	 * @brief Constructor
	 */
	Pusher(double sampling, double value, int dim1, int dim2) : PusherBase(sampling, value, dim1, dim2)
	{
		_paramData = _specParamData = createParamData();
		_nbDataByPacket = getNbDataByPacket(type, dim1, dim2);
	}

	/*
	 * @brief Put packet in a "vector" ParamData
	 */
	virtual int put(double startTime, double stopTime, int lastIndex)
	{
		_specParamData->getDataList().resize(_nbDataByPacket);

		for (int index = 0; index < _nbDataByPacket; ++index)
		{
			//get time
			double time = startTime + (lastIndex + index) * _sampling;
			if (time > stopTime) {
				return index;
			}
			//this element will be deleted by the Container designed by "_specParamData->getDataList()"
			ElemenType elem = ElemenType(_dim1,_dim2);
			for (int dim1Index = 0;  dim1Index < _dim1; ++dim1Index)
			{
				for (int dim2Index = 0;  dim2Index < _dim2; ++dim2Index)
				{
					BaseElemenType baseElem = _value;
					elem[dim1Index][dim2Index] = baseElem;
				}
			}

			//push time and element in the ParamData
			_specParamData->getDataList().push_back(elem);
			_specParamData->getTimeList().push_back(time);
		}

		//return nb of processed records
		return _nbDataByPacket;
	}

	/*
	 * @brief ParamData creation
	 */
	SpecParamData* createParamData()
	{
		return new AMDA::Parameters::ParamDataSpec<AMDA::Parameters::Tab2DData<typename MapType<type>::Type> >(_dim1,_dim2);
	}
};

/**
 * @brief Pusher implementation for the vector.
 */
template<ConstantParamType type>
class Pusher<type,CONTAINER_VECTOR> : public PusherBase
{
public:
	/*
	 * @brief Define some usefull types
	 */
	typedef typename MapType<type>::Type BaseElemenType;
	typedef std::vector<BaseElemenType> ElemenType;
	typedef AMDA::Parameters::ParamDataSpec<ElemenType> SpecParamData;

	SpecParamData* _specParamData;

	/*
	 * @brief Constructor
	 */
	Pusher(double sampling, double value, int dim) : PusherBase(sampling, value, dim)
	{
		_paramData = _specParamData = createParamData();
		_nbDataByPacket = getNbDataByPacket(type, dim, 1);
	}

	/*
	 * @brief Put packet in a "vector" ParamData
	 */
	virtual int put(double startTime, double stopTime, int lastIndex)
	{
		_specParamData->getDataList().resize(_nbDataByPacket);

		for (int index = 0; index < _nbDataByPacket; ++index)
		{
			//get time
			double time = startTime + (lastIndex + index) * _sampling;
			if (time > stopTime) {
				return index;
			};

			ElemenType elem;
			for (int dimIndex = 0;  dimIndex < _dim1; ++dimIndex)
			{
				BaseElemenType baseElem = _value;
				elem.push_back(baseElem);
			}

			//push time and element in the ParamData
			_specParamData->getDataList().push_back(elem);
			_specParamData->getTimeList().push_back(time);
		}

		//return nb of processed records
		return _nbDataByPacket;
	}

	/*
	 * @brief ParamData creation
	 */
	SpecParamData* createParamData()
	{
		return new AMDA::Parameters::ParamDataSpec< std::vector<typename MapType<type>::Type> >(_dim1);
	}
};

/**
 * @brief Pusher implementation for the scalar.
 */
template<ConstantParamType type>
class Pusher<type,CONTAINER_SCALAR> : public PusherBase {
public:
	/*
	 * @brief Define some usefull types
	 */
	typedef typename MapType<type>::Type BaseElemenType;
	typedef BaseElemenType ElemenType;
	typedef AMDA::Parameters::ParamDataSpec<ElemenType> SpecParamData;

	SpecParamData* _specParamData;

	/*
	 * @brief Constructor
	 */
	Pusher(double sampling, double value) : PusherBase(sampling, value)
	{
		_paramData = _specParamData = createParamData();
		_nbDataByPacket = getNbDataByPacket(type, 1, 1);
	}

	/*
	 * @brief Put packet in a "scalar" ParamData
	 */
	virtual int put(double startTime, double stopTime, int lastIndex)
	{
		//ParamData is created, add data
		_specParamData->getDataList().resize(_nbDataByPacket);

		for (int index = 0; index < _nbDataByPacket; ++index)
		{
			//get time
			double time = startTime + (lastIndex + index) * _sampling;
			if (time > stopTime) {
				return index;
			}

			BaseElemenType baseElem = _value;

			//push time and element in the ParamData
			_specParamData->getDataList().push_back(baseElem);
			_specParamData->getTimeList().push_back(time);
		}

		return _nbDataByPacket;
	}

	SpecParamData* createParamData() {
		return new SpecParamData();
	}
};

} /* namespace ConstantInterface */
} /* namespace AMDA */
#endif /* PUSHER_H_ */