365 lines
11 KiB
C++
365 lines
11 KiB
C++
/**
|
|
* @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 "map_assignment.h"
|
|
|
|
namespace mapping
|
|
{
|
|
namespace oo
|
|
{
|
|
//define all needed error types and values locally
|
|
_MAKE_RESULT(-5, ERR_INVALID_ARG)
|
|
}
|
|
}
|
|
|
|
using namespace mapping::oo;
|
|
|
|
MapAssignment::MapAssignment() : _is_valid(true)
|
|
{
|
|
}
|
|
|
|
MapAssignment::MapAssignment(std::string strTo) : _to(strTo), _is_valid(true)
|
|
{
|
|
}
|
|
|
|
bool MapAssignment::isValid() const
|
|
{
|
|
return _is_valid;
|
|
}
|
|
|
|
const std::string& MapAssignment::getFrom() const
|
|
{
|
|
return _from;
|
|
}
|
|
|
|
const std::string& MapAssignment::getSource() const
|
|
{
|
|
return _source;
|
|
}
|
|
|
|
a_util::result::Result MapAssignment::connect(const std::string& strSourceElementPath)
|
|
{
|
|
_constant.clear();
|
|
_function.clear();
|
|
_modulo.clear();
|
|
_transform.clear();
|
|
|
|
_from = strSourceElementPath;
|
|
a_util::strings::trim(_from);
|
|
_source.clear();
|
|
// parse source out of <from>
|
|
// parse source
|
|
size_t idx = _from.find('.');
|
|
if (idx != std::string::npos)
|
|
{
|
|
_source = _from.substr(0, idx);
|
|
_from = _from.substr(idx + 1);
|
|
}
|
|
else
|
|
{
|
|
// no path when the signal itself is referenced
|
|
_source = _from;
|
|
_from.clear();
|
|
}
|
|
|
|
if(_source.empty())
|
|
{
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
|
|
return a_util::result::SUCCESS;
|
|
}
|
|
|
|
const std::string& MapAssignment::getConstant() const
|
|
{
|
|
return _constant;
|
|
}
|
|
|
|
a_util::result::Result MapAssignment::setConstant(const std::string& strConstant)
|
|
{
|
|
_from.clear();
|
|
_source.clear();
|
|
_function.clear();
|
|
_modulo.clear();
|
|
_transform.clear();
|
|
|
|
_constant = strConstant;
|
|
a_util::strings::trim(_constant);
|
|
if(_constant.empty())
|
|
{
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
return a_util::result::SUCCESS;
|
|
}
|
|
|
|
const std::string& MapAssignment::getFunction() const
|
|
{
|
|
return _function;
|
|
}
|
|
|
|
a_util::result::Result MapAssignment::setSimulationTimeFunction()
|
|
{
|
|
_from.clear();
|
|
_source.clear();
|
|
_constant.clear();
|
|
_modulo.clear();
|
|
_transform.clear();
|
|
|
|
_function = "simulation_time";
|
|
return a_util::result::SUCCESS;
|
|
}
|
|
|
|
a_util::result::Result MapAssignment::setTriggerCounterFunction(const std::string& strModulo)
|
|
{
|
|
_from.clear();
|
|
_source.clear();
|
|
_constant.clear();
|
|
_transform.clear();
|
|
_function.clear();
|
|
|
|
_modulo = strModulo;
|
|
a_util::strings::trim(_modulo);
|
|
_function = "trigger_counter";
|
|
return a_util::result::SUCCESS;
|
|
}
|
|
|
|
a_util::result::Result MapAssignment::setReceivedFunction(const std::string& strSource)
|
|
{
|
|
_from.clear();
|
|
_source.clear();
|
|
_constant.clear();
|
|
_modulo.clear();
|
|
_transform.clear();
|
|
|
|
_source = strSource;
|
|
a_util::strings::trim(_source);
|
|
if(_source.empty())
|
|
{
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
_function = "received";
|
|
return a_util::result::SUCCESS;
|
|
}
|
|
|
|
const std::string& MapAssignment::getModulo() const
|
|
{
|
|
return _modulo;
|
|
}
|
|
|
|
const std::string& MapAssignment::getTo() const
|
|
{
|
|
return _to;
|
|
}
|
|
|
|
const std::string& MapAssignment::getTransformation() const
|
|
{
|
|
return _transform;
|
|
}
|
|
|
|
a_util::result::Result MapAssignment::setTransformation(const std::string& strTransformationName)
|
|
{
|
|
_transform.clear();
|
|
if(_source.empty()||_from.empty())
|
|
{
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
_transform = strTransformationName;
|
|
a_util::strings::trim(_transform);
|
|
return a_util::result::SUCCESS;
|
|
}
|
|
|
|
a_util::result::Result MapAssignment::removeTransformation()
|
|
{
|
|
_transform.clear();
|
|
return a_util::result::SUCCESS;
|
|
}
|
|
|
|
a_util::result::Result MapAssignment::loadFromDOM(const a_util::xml::DOMElement& oAssignment, MapErrorList& lstErrors)
|
|
{
|
|
// parse attributes
|
|
const a_util::xml::DOMAttributes mapAttrs = oAssignment.getAttributes();
|
|
// find target element
|
|
a_util::xml::DOMAttributes::const_iterator itAttrTo = mapAttrs.find("to");
|
|
if (itAttrTo == mapAttrs.end() || itAttrTo->second.empty())
|
|
{
|
|
lstErrors.push_back("Missing <to> attribute for an <assignment>");
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
_to = itAttrTo->second;
|
|
a_util::strings::trim(_to);
|
|
|
|
// find Source or constant
|
|
a_util::xml::DOMAttributes::const_iterator itAttrFrom = mapAttrs.find("from");
|
|
a_util::xml::DOMAttributes::const_iterator itAttrConst = mapAttrs.find("constant");
|
|
a_util::xml::DOMAttributes::const_iterator itAttrFct = mapAttrs.find("function");
|
|
if (itAttrFrom == mapAttrs.end() && itAttrConst == mapAttrs.end() && itAttrFct == mapAttrs.end())
|
|
{
|
|
lstErrors.push_back(a_util::strings::format("Missing <from>, <constant> or <function> attribute for <assignment> to '%s'",
|
|
itAttrTo->second.c_str()));
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
if (itAttrFrom != mapAttrs.end() && itAttrConst != mapAttrs.end())
|
|
{
|
|
lstErrors.push_back(a_util::strings::format("<from> and <constant> attributes set at the same time for <assignment> to '%s'",
|
|
itAttrTo->second.c_str()));
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
if (itAttrFrom != mapAttrs.end() && itAttrFct != mapAttrs.end())
|
|
{
|
|
lstErrors.push_back(a_util::strings::format("<from> and <function> attributes set at the same time for <assignment> to '%s'",
|
|
itAttrTo->second.c_str()));
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
if (itAttrFct != mapAttrs.end() && itAttrConst != mapAttrs.end())
|
|
{
|
|
lstErrors.push_back(a_util::strings::format("<function> and <constant> attributes set at the same time for <assignment> to '%s'",
|
|
itAttrTo->second.c_str()));
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
|
|
if (itAttrFrom != mapAttrs.end())
|
|
{
|
|
if(itAttrFrom->second.empty())
|
|
{
|
|
lstErrors.push_back(a_util::strings::format("<from> attribute empty for <assignment> to '%s'",
|
|
itAttrTo->second.c_str()));
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
connect(itAttrFrom->second);
|
|
}
|
|
else if(itAttrConst != mapAttrs.end())
|
|
{
|
|
if(isFailed(setConstant(itAttrConst->second)))
|
|
{
|
|
lstErrors.push_back(a_util::strings::format("<constant> attribute empty for <assignment> \
|
|
to '%s'", itAttrTo->second.c_str()));
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(itAttrFct->second.empty())
|
|
{
|
|
lstErrors.push_back(a_util::strings::format("<function> attribute empty for <assignment> \
|
|
to '%s'", itAttrTo->second.c_str()));
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
_function = itAttrFct->second;
|
|
|
|
size_t nIdx1 = _function.find('(');
|
|
size_t nIdx2 = _function.find(')');
|
|
if (nIdx1 == std::string::npos || nIdx2 == std::string::npos ||
|
|
nIdx1 == 0 || nIdx2 == 0 || nIdx1 > nIdx2
|
|
|| !(_function.find("simulation_time") == 0
|
|
|| _function.find("trigger_counter") == 0
|
|
|| _function.find("received") == 0))
|
|
{
|
|
lstErrors.push_back(a_util::strings::format("<function> should be of type 'simulation_time()', \
|
|
'trigger_counter([Modulo])' or 'received([Signal])' for <assignment> \
|
|
to '%s'", itAttrTo->second.c_str()));
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
|
|
int64_t nLength = (int64_t)nIdx2 - (int64_t)nIdx1 - 1;
|
|
if(_function.find("simulation_time") == 0)
|
|
{
|
|
if(nLength > 0)
|
|
{
|
|
lstErrors.push_back(a_util::strings::format("<function> of type 'simulation_time()' takes no argument for <assignment> \
|
|
to '%s'", itAttrTo->second.c_str()));
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
setSimulationTimeFunction();
|
|
}
|
|
if(_function.find("trigger_counter") == 0)
|
|
{
|
|
if(isFailed(setTriggerCounterFunction(_function.substr(nIdx1 + 1, (size_t)nLength))))
|
|
{
|
|
lstErrors.push_back(a_util::strings::format("<function> of type 'trigger_counter()' takes a positive Integer as argument for <assignment> \
|
|
to '%s'", itAttrTo->second.c_str()));
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
}
|
|
else if(_function.find("received") == 0)
|
|
{
|
|
if(isFailed(setReceivedFunction(_function.substr(nIdx1 + 1, (size_t)nLength))))
|
|
{
|
|
lstErrors.push_back(a_util::strings::format("<function> of type'received([Signal])' has no argument for <assignment> \
|
|
to '%s'", itAttrTo->second.c_str()));
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
}
|
|
}
|
|
|
|
a_util::xml::DOMAttributes::const_iterator itAttr = mapAttrs.find("transformation");
|
|
if (itAttr != mapAttrs.end() && !itAttr->second.empty())
|
|
{
|
|
if(isFailed(setTransformation(itAttr->second)))
|
|
{
|
|
lstErrors.push_back(a_util::strings::format("<transformation> is only accepted for connection for <assignment> \
|
|
to '%s'", itAttrTo->second.c_str()));
|
|
return ERR_INVALID_ARG;
|
|
}
|
|
}
|
|
|
|
return a_util::result::SUCCESS;
|
|
}
|
|
|
|
a_util::result::Result MapAssignment::writeToDOM(a_util::xml::DOMElement& oDOMElement) const
|
|
{
|
|
oDOMElement.setName("assignment");
|
|
oDOMElement.setAttribute("to", _to);
|
|
if(!_function.empty())
|
|
{
|
|
std::string strDOMFunction = _function;
|
|
if(strDOMFunction == "simulation_time")
|
|
{
|
|
strDOMFunction.append("()");
|
|
}
|
|
else if(strDOMFunction == "trigger_counter")
|
|
{
|
|
strDOMFunction.append(a_util::strings::format("(%s)", _modulo.c_str()));
|
|
}
|
|
else if(strDOMFunction == "received")
|
|
{
|
|
strDOMFunction.append(a_util::strings::format("(%s)", _source.c_str()));
|
|
}
|
|
oDOMElement.setAttribute("function", strDOMFunction);
|
|
}
|
|
else if(!_source.empty())
|
|
{
|
|
std::string strDOMFrom = _source;
|
|
if(!_from.empty())
|
|
{
|
|
strDOMFrom.push_back('.');
|
|
strDOMFrom.append(_from);
|
|
}
|
|
oDOMElement.setAttribute("from", strDOMFrom);
|
|
if(!_transform.empty())
|
|
{
|
|
oDOMElement.setAttribute("transformation", _transform);
|
|
}
|
|
}
|
|
else if(!_constant.empty())
|
|
{
|
|
oDOMElement.setAttribute("constant", _constant);
|
|
}
|
|
return a_util::result::SUCCESS;
|
|
}
|