/** * @file * * @copyright * @verbatim Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved. This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE file in a relevant directory) where a recipient would be likely to look for such a notice. You may add additional accurate notices of copyright ownership. @endverbatim */ #include "element.h" using namespace mapping; using namespace mapping::rt; namespace mapping { namespace rt { //define all needed error types and values locally _MAKE_RESULT(-3, ERR_UNEXPECTED) _MAKE_RESULT(-5, ERR_INVALID_ARG) _MAKE_RESULT(-42, ERR_INVALID_TYPE) } } /// Helper method that sets a casted value in the coder template static void SetCastedValue(void* pDestination, unsigned int nArrayIndex, T* pData, uint32_t type32) { switch (type32) { case e_uint8: { uint8_t ui8Temp = static_cast(*pData); a_util::memory::copy((uint8_t*)pDestination + nArrayIndex, sizeof(uint8_t), &ui8Temp, sizeof(uint8_t)); } break; case e_uint16: { uint16_t ui16Temp = static_cast(*pData); a_util::memory::copy((uint16_t*)pDestination + nArrayIndex, sizeof(uint16_t), &ui16Temp, sizeof(uint16_t)); } break; case e_uint32: { uint32_t ui32Temp = static_cast(*pData); a_util::memory::copy((uint32_t*)pDestination + nArrayIndex, sizeof(uint32_t), &ui32Temp, sizeof(uint32_t)); } break; case e_uint64: { uint64_t ui64Temp = static_cast(*pData); a_util::memory::copy((uint64_t*)pDestination + nArrayIndex, sizeof(uint64_t), &ui64Temp, sizeof(uint64_t)); } break; case e_int8: { int8_t i8Temp = static_cast(*pData); a_util::memory::copy((int8_t*)pDestination + nArrayIndex, sizeof(int8_t), &i8Temp, sizeof(int8_t)); } break; case e_int16: { int16_t i16Temp = static_cast(*pData); a_util::memory::copy((int16_t*)pDestination + nArrayIndex, sizeof(int16_t), &i16Temp, sizeof(int16_t)); } break; case e_int32: { int32_t i32Temp = static_cast(*pData); a_util::memory::copy((int32_t*)pDestination + nArrayIndex, sizeof(int32_t), &i32Temp, sizeof(int32_t)); } break; case e_int64: { int64_t i64Temp = static_cast(*pData); a_util::memory::copy((int64_t*)pDestination + nArrayIndex, sizeof(int64_t), &i64Temp, sizeof(int64_t)); } break; case e_float32: { float f32Temp = static_cast(*pData); a_util::memory::copy((float*)pDestination + nArrayIndex, sizeof(float), &f32Temp, sizeof(float)); } break; case e_float64: { double f64Temp = static_cast(*pData); a_util::memory::copy((double*)pDestination + nArrayIndex, sizeof(double), &f64Temp, sizeof(double)); } break; case e_bool: { bool bTemp = *pData != 0 ? true : false; a_util::memory::copy((bool*)pDestination + nArrayIndex, sizeof(bool), &bTemp, sizeof(bool)); } break; case e_char: { char cTemp = static_cast(*pData); a_util::memory::copy((char*)pDestination + nArrayIndex, sizeof(char), &cTemp, sizeof(char)); } break; default: assert(false); break; } } template <> void SetCastedValue(void* pDestination, unsigned int nArrayIndex, bool* pData, uint32_t type32) { int nBool = *pData ? 1 : 0; switch (type32) { case e_uint8: { uint8_t ui8Temp = static_cast(nBool); a_util::memory::copy((uint8_t*)pDestination + nArrayIndex, sizeof(uint8_t), &ui8Temp, sizeof(uint8_t)); } break; case e_uint16: { uint16_t ui16Temp = static_cast(nBool); a_util::memory::copy((uint16_t*)pDestination + nArrayIndex, sizeof(uint16_t), &ui16Temp, sizeof(uint16_t)); } break; case e_uint32: { uint32_t ui32Temp = static_cast(nBool); a_util::memory::copy((uint32_t*)pDestination + nArrayIndex, sizeof(uint32_t), &ui32Temp, sizeof(uint32_t)); } break; case e_uint64: { uint64_t ui64Temp = static_cast(nBool); a_util::memory::copy((uint64_t*)pDestination + nArrayIndex, sizeof(uint64_t), &ui64Temp, sizeof(uint64_t)); } break; case e_int8: { int8_t i8Temp = static_cast(nBool); a_util::memory::copy((int8_t*)pDestination + nArrayIndex, sizeof(int8_t), &i8Temp, sizeof(int8_t)); } break; case e_int16: { int16_t i16Temp = static_cast(nBool); a_util::memory::copy((int16_t*)pDestination + nArrayIndex, sizeof(int16_t), &i16Temp, sizeof(int16_t)); } break; case e_int32: { int32_t i32Temp = static_cast(nBool); a_util::memory::copy((int32_t*)pDestination + nArrayIndex, sizeof(int32_t), &i32Temp, sizeof(int32_t)); } break; case e_int64: { int64_t i64Temp = static_cast(nBool); a_util::memory::copy((int64_t*)pDestination + nArrayIndex, sizeof(int64_t), &i64Temp, sizeof(int64_t)); } break; case e_float32: { float f32Temp = static_cast(nBool); a_util::memory::copy((float*)pDestination + nArrayIndex, sizeof(float), &f32Temp, sizeof(float)); } break; case e_float64: { double f64Temp = static_cast(nBool); a_util::memory::copy((double*)pDestination + nArrayIndex, sizeof(double), &f64Temp, sizeof(double)); } break; case e_bool: a_util::memory::copy((bool*)pDestination + nArrayIndex, sizeof(bool), pData, sizeof(bool)); break; case e_char: { char cTemp = static_cast(nBool); a_util::memory::copy((char*)pDestination + nArrayIndex, sizeof(char), &cTemp, sizeof(char)); } break; default: assert(false); break; } } template static inline void TransformAndSetValueImpl(const void* pData, void* pDestination, unsigned int nArraySize, const oo::MapTransformationBase* pTrans, uint32_t type32) { assert(pTrans); assert(pData); for(unsigned int i = 0; i < nArraySize; i++) { double fValue = pTrans->evaluate(static_cast(*((T*)pData + i))); SetCastedValue(pDestination, i, &fValue, type32); } } template static inline void SetValueImpl(const void* pData, void* pDestination, unsigned int nArraySize, uint32_t type32) { assert(pData); for(unsigned int i = 0; i < nArraySize; i++) { SetCastedValue(pDestination, i, (T*)pData + i, type32); } } TargetElement::TargetElement(Target* pTarget) : _target(pTarget), _element_ptr(NULL), _type_int(0), _type(NULL), _struct(NULL), _array_size(0), _transformation(NULL) { _type_map["tUInt8"] = e_uint8; _type_map["tUInt16"] = e_uint16; _type_map["tUInt32"] = e_uint32; _type_map["tUInt64"] = e_uint64; _type_map["tInt8"] = e_int8; _type_map["tInt16"] = e_int16; _type_map["tInt32"] = e_int32; _type_map["tInt64"] = e_int64; _type_map["tFloat32"] = e_float32; _type_map["tFloat64"] = e_float64; _type_map["tBool"] = e_bool; _type_map["tChar"] = e_char; } TargetElement::~TargetElement() { delete _transformation; _transformation = NULL; } a_util::result::Result TargetElement::create(void* pElementPtr, ddl::IDDLDataType* pDataType, const unsigned int nArraySize, const std::string& strElementName) { _element_ptr = pElementPtr; _array_size = nArraySize; _element_name = strElementName; _type = dynamic_cast(pDataType); _struct = dynamic_cast(pDataType); _enum = dynamic_cast(pDataType); if (_enum) { _type = dynamic_cast(_enum->getTypeObject()); if (!_type) { return ERR_UNEXPECTED; } _enum = NULL; } if(_type) { TypeMap::const_iterator it = _type_map.find(_type->getName()); if(it != _type_map.end()) { _type_int = it->second; } } return a_util::result::SUCCESS; } a_util::result::Result TargetElement::setTransformation(const oo::MapTransformationBase* pTransformation) { if (_transformation) { delete _transformation; _transformation = NULL; } if (pTransformation) { _transformation = pTransformation->clone(); } return a_util::result::SUCCESS; } a_util::result::Result TargetElement::setValue(const void* pData, uint32_t ui32SrcType, size_t szMem) { // Scalars (and enums converted to scalars) if(_type) { if(_transformation) { switch(ui32SrcType) { case e_uint8: TransformAndSetValueImpl(pData, _element_ptr, _array_size, _transformation, _type_int); break; case e_uint16: TransformAndSetValueImpl(pData, _element_ptr, _array_size, _transformation, _type_int); break; case e_uint32: TransformAndSetValueImpl(pData, _element_ptr, _array_size, _transformation, _type_int); break; case e_uint64: TransformAndSetValueImpl(pData, _element_ptr, _array_size, _transformation, _type_int); break; case e_int8: TransformAndSetValueImpl(pData, _element_ptr, _array_size, _transformation, _type_int); break; case e_int16: TransformAndSetValueImpl(pData, _element_ptr, _array_size, _transformation, _type_int); break; case e_int32: TransformAndSetValueImpl(pData, _element_ptr, _array_size, _transformation, _type_int); break; case e_int64: TransformAndSetValueImpl(pData, _element_ptr, _array_size, _transformation, _type_int); break; case e_float32: TransformAndSetValueImpl(pData, _element_ptr, _array_size, _transformation, _type_int); break; case e_float64: TransformAndSetValueImpl(pData, _element_ptr, _array_size, _transformation, _type_int); break; case e_bool: TransformAndSetValueImpl(pData, _element_ptr, _array_size, _transformation, _type_int); break; case e_char: TransformAndSetValueImpl(pData, _element_ptr, _array_size, _transformation, _type_int); break; default: return ERR_INVALID_TYPE; } } else if(_type_int == ui32SrcType) { // Source and target have the same type a_util::memory::copy(_element_ptr, szMem, pData, szMem); } else { // Source and target have different types switch(ui32SrcType) { case e_uint8: SetValueImpl(pData, _element_ptr, _array_size, _type_int); break; case e_uint16: SetValueImpl(pData, _element_ptr, _array_size, _type_int); break; case e_uint32: SetValueImpl(pData, _element_ptr, _array_size, _type_int); break; case e_uint64: SetValueImpl(pData, _element_ptr, _array_size, _type_int); break; case e_int8: SetValueImpl(pData, _element_ptr, _array_size, _type_int); break; case e_int16: SetValueImpl(pData, _element_ptr, _array_size, _type_int); break; case e_int32: SetValueImpl(pData, _element_ptr, _array_size, _type_int); break; case e_int64: SetValueImpl(pData, _element_ptr, _array_size, _type_int); break; case e_float32: SetValueImpl(pData, _element_ptr, _array_size, _type_int); break; case e_float64: SetValueImpl(pData, _element_ptr, _array_size, _type_int); break; case e_bool: SetValueImpl(pData, _element_ptr, _array_size, _type_int); break; case e_char: SetValueImpl(pData, _element_ptr, _array_size, _type_int); break; default: return ERR_INVALID_TYPE; } } } else if(_struct) // Structures { // Transformations are not allowed a_util::memory::copy(_element_ptr, szMem, pData, szMem); } else { return ERR_INVALID_ARG; } return a_util::result::SUCCESS; } Target* TargetElement::getTarget() { return _target; } a_util::result::Result TargetElement::setDefaultValue(const std::string& strDefault) { // Scalars and arrays if(_type) { double fVal = 0; if(!strDefault.empty() && a_util::strings::isDouble(strDefault)) { fVal = a_util::strings::toDouble(strDefault); } for(unsigned int i = 0; i < _array_size; i++) { SetCastedValue(_element_ptr, i, &fVal, _type_int); } } //Structures if(_struct) { //TODO: What is default value for a structure? return ERR_INVALID_ARG; } return a_util::result::SUCCESS; }