/* * LocalParamData.hh * * Created on: Nov 24, 2014 * Author: AKKA */ #ifndef LOCALPARAMDATA_H_ #define LOCALPARAMDATA_H_ #include "LocalFileInterfaceConfig.hh" #include #include namespace AMDA { namespace LocalFileInterface { /* * @brief Container type - CONTAINER_MATRIX not tested */ enum LocalContainerType { CONTAINER_SCALAR, CONTAINER_VECTOR, CONTAINER_MATRIX }; /* * @brief Param type */ enum LocalParamType { TYPE_UNKNOWN, TYPE_FLOAT, TYPE_DOUBLE, TYPE_SHORT, TYPE_INT }; /* * @brief Define the maximum dimension size */ #define PARAMPACKET_MAX_DIMSIZE 10000 /* * @brief Define the maximum bytes available for one packet */ #define PARAMPACKET_MAX_DATABYTES 80000 /* * @brief Define a packet to push to a ParamData */ class LocalParamDataPacket { public: /* * @brief Constructor */ LocalParamDataPacket(void) : _isInit(false), _containerType(CONTAINER_SCALAR), _paramType(TYPE_UNKNOWN), _nbData(0), _nbMaxData(0), _dims(NULL), _size(0), _times(NULL), _datas(NULL) { } /* * @brief Destructor */ ~LocalParamDataPacket(void) { //free allocated data if needed free(); } /* * @brief Init the packet. This function allocate all buffers used by a packet */ bool init(LocalContainerType containerType, LocalParamType paramType, int dim1 = 0, int dim2 = 0) { if (_isInit) //already init return false; _containerType = containerType; _paramType = paramType; _size = 0; //compute dimSize switch (_containerType) { case CONTAINER_SCALAR : //for a scalar, no dims defined and the size is 1 _size = 1; _dims = NULL; break; case CONTAINER_VECTOR : //for a vector, 1 "dims" defined and the size is egal to this dimension size if (dim1 <= 0) return false; _size = dim1; _dims = new int[1]; _dims[0] = dim1; break; case CONTAINER_MATRIX : //for a matrix, 2 "dims" defined and the size is egal to the multiplication of the two dimensions sizes if ((dim1 <= 0) || (dim2 <= 0)) return false; _size = dim1 * dim2; _dims = new int[2]; _dims[0] = dim1; _dims[1] = dim2; break; default: return false; } //check dimSize if ((_size <= 0) || (_size >= PARAMPACKET_MAX_DIMSIZE)) { if (_dims != NULL) { delete[] _dims; _dims = NULL; } return false; } //init times and datas //use the PARAMPACKET_MAX_DATABYTES to determine the maximum data that's a packet can contain _nbData = 0; switch (_paramType) { case TYPE_FLOAT : _nbMaxData = PARAMPACKET_MAX_DATABYTES / (_size * sizeof(float)); if (_nbMaxData < 1) _nbMaxData = 1; _times = new double[_nbMaxData]; _datas = new float[_nbMaxData*_size]; break; case TYPE_DOUBLE : _nbMaxData = PARAMPACKET_MAX_DATABYTES / (_size * sizeof(double)); if (_nbMaxData < 1) _nbMaxData = 1; _times = new double[_nbMaxData]; _datas = new double[_nbMaxData*_size]; break; case TYPE_SHORT : _nbMaxData = PARAMPACKET_MAX_DATABYTES / (_size * sizeof(short)); if (_nbMaxData < 1) _nbMaxData = 1; _times = new double[_nbMaxData]; _datas = new short[_nbMaxData*_size]; break; case TYPE_INT : _nbMaxData = PARAMPACKET_MAX_DATABYTES / (_size * sizeof(int)); if (_nbMaxData < 1) _nbMaxData = 1; _times = new double[_nbMaxData]; _datas = new int[_nbMaxData*_size]; break; default : if (_dims != NULL) { delete[] _dims; _dims = NULL; } return false; } _isInit = true; return true; } /* * @brief Free all allocated buffers. This function is called in the destructor */ void free() { if (!_isInit) return; //free all allocated buffers if (_dims != NULL) { delete[] _dims; _dims = NULL; } if (_times != NULL) { delete[] _times; _times = NULL; } if (_datas != NULL) { switch (_paramType) { case TYPE_FLOAT : delete[] (float*)_datas; _datas = NULL; break; case TYPE_DOUBLE : delete[] (double*)_datas; _datas = NULL; break; case TYPE_SHORT : delete[] (short*)_datas; _datas = NULL; break; case TYPE_INT : delete[] (int*)_datas; _datas = NULL; break; default : throw; } } _isInit = false; } /* * @brief Add one record (a pair of one time and a data) * If the result is false and "full" parameter is true => the packet is full */ bool addData(double time, void* data, bool& full) { //add a record in the packet full = false; if (!_isInit) return false; full = (_nbData >= _nbMaxData); if (full) //cannot add more data in the packet return false; //set data void *pos = _datas; int sizeToCopy; switch (_paramType) { case TYPE_FLOAT : sizeToCopy = _size * sizeof(float); break; case TYPE_DOUBLE : sizeToCopy = _size * sizeof(double); break; case TYPE_SHORT : sizeToCopy = _size * sizeof(short); break; case TYPE_INT : sizeToCopy = _size * sizeof(int); break; default: return false; } pos = (void*)((intptr_t)pos + (_nbData * sizeToCopy)); memcpy(pos,data,sizeToCopy); //set time _times[_nbData] = time; ++_nbData; full = (_nbData >= _nbMaxData); return true; } /* * @brief Get number of record contained by the packet */ int getNbData(void) { if (!_isInit) return 0; return _nbData; } /* * @brief Get one time by record index */ double getTime(int index) { if (!_isInit) return 0.; if (index >= _nbData) return 0.; return _times[index]; } /* * @brief Get the first dimension size. */ int getDim1Size(void) { if (!_isInit) return 0; switch (_containerType) { case CONTAINER_VECTOR : case CONTAINER_MATRIX : if (_dims != NULL) return _dims[0]; break; default: return 0; } return 0; } /* * @brief Get the second dimension size. */ int getDim2Size(void) { if (!_isInit) return 0; switch (_containerType) { case CONTAINER_MATRIX : if (_dims != NULL) return _dims[1]; break; default: return 0; } return 0; } /* * @brief Get the full size of a data of a record */ int getDimsSize(void) { return _size; } /* * @brief Get data type for a record */ LocalParamType getType() { return _paramType; } /* * @brief Get one data value from record with the index "index" * And from the dimensions indexes */ bool getDataValue(void *val, int index, int dim1Index = 0, int dim2Index = 0) { if (!_isInit) return false; void *pos = NULL; int valueSize = 0; switch (_paramType) { case TYPE_FLOAT : valueSize = sizeof(float); break; case TYPE_DOUBLE : valueSize = sizeof(double); break; case TYPE_SHORT : valueSize = sizeof(short); break; case TYPE_INT : valueSize = sizeof(int); break; default: return false; } switch (_containerType) { case CONTAINER_SCALAR : pos = (void*)((intptr_t)_datas + (valueSize * _size * index)); break; case CONTAINER_VECTOR : pos = (void*)((intptr_t)_datas + (valueSize * _size * index)); pos = (void*)((intptr_t)pos + (dim1Index * valueSize)); break; case CONTAINER_MATRIX : pos = (void*)((intptr_t)_datas + (valueSize * _size * index)); pos = (void*)((intptr_t)pos + (dim1Index * _dims[1] * valueSize)); pos = (void*)((intptr_t)pos + (dim2Index * valueSize)); break; default : return false; } memcpy(val,pos,valueSize); return true; } private: /* * @brief Flag to know if the packet is init */ bool _isInit; /* * @brief Container type for data of the packet */ LocalContainerType _containerType; /* * @brief Param type for data of the packet */ LocalParamType _paramType; /* * @brief Number of record defined in the packet */ int _nbData; /* * @brief Maximum number of record that's can be defined in the packet */ int _nbMaxData; /* * @brief Dimensions definition */ int* _dims; /* * @brief Full size of a data of a record */ int _size; /* * @brief times buffer */ double* _times; /* * @brief record data buffer */ void* _datas; }; } /* LocalFileInterface */ } /* AMDA */ #endif