OpenTTCN/Developer corner/Implementing external functions/Modified/C/PA impl.cxx
From OpenTTCN
Home | Developer's corner | Knowledge base | Working documents | Documentation | OpenTTCN IDE | Tutorials | Training | How do I | Frequently asked questions | Technical support |
PA_impl.cxx
#include <tri/tri.h>
#include <isl/TTCN3.h>
#include <stdio.h>
#include <stdlib.h>
#include <map>
#include <string>
/***************************************************************************
* Forward declarations of external functions implemented in the following
* sections of code in this file.
*/
TriStatus ef_calc_sum(const TriFunctionId* functionId,
TriParameterList* parameterList, TriParameter* returnValue);
TriStatus ef_calc_sub(const TriFunctionId* functionId,
TriParameterList* parameterList, TriParameter* returnValue);
TriStatus ef_calc_mul(const TriFunctionId* functionId,
TriParameterList* parameterList, TriParameter* returnValue);
TriStatus ef_calc_div(const TriFunctionId* functionId,
TriParameterList* parameterList, TriParameter* returnValue);
/***************************************************************************
* Initialization of TRI interface (PA, user-provided part).
*/
typedef TriStatus (*ExtFuncPtr)(
const TriFunctionId*, TriParameterList*, TriParameter*);
// Key is function name, value is function pointer implementing the
// external function with the specified name.
typedef std::map<std::string, ExtFuncPtr> ExtFuncMapType;
// Contains mappings of available external function implementations.
static ExtFuncMapType _extFuncMap;
void initializePA()
{
_extFuncMap["ef_calc_sum"] = &ef_calc_sum;
_extFuncMap["ef_calc_sub"] = &ef_calc_sub;
_extFuncMap["ef_calc_mul"] = &ef_calc_mul;
_extFuncMap["ef_calc_div"] = &ef_calc_div;
}
/***************************************************************************
* Implementation of TRI interface (PA, user-provided part).
*/
TriStatus triExternalFunction
(const TriFunctionId* functionId, /* in parameter */
TriParameterList* parameterList, /* inout parameter */
TriParameter* returnValue /* out parameter */)
{
std::string funcId = functionId->objectName;
printf("**************************************************************************\n");
printf("*** DEBUG: triExternalFunction() callback called. Function: %s\n", funcId.c_str());
ExtFuncMapType::iterator iter = _extFuncMap.find(funcId);
if (iter != _extFuncMap.end())
{
return (*(iter->second))(functionId, parameterList, returnValue);
}
std::string errMsg = "Unrecognized external function " + funcId + " called.";
otReportError(errMsg.c_str());
return TRI_ERROR;
}
/***************************************************************************
* External function implementation helpers.
*/
long triParameterToLong(TriParameter* src)
{
return *((long *) src->par.data);
}
void assignLongToTriParameter(TriParameter* dst, long src)
{
int len = sizeof(long);
dst->par.data = (unsigned char *) malloc(len);
memcpy(dst->par.data, &src, len);
dst->par.bits = len << 3;
}
/***************************************************************************
* External function implementations.
*/
TriStatus ef_calc_sum(const TriFunctionId* functionId,
TriParameterList* parameterList, TriParameter* returnValue)
{
TriParameter** pars = parameterList->parList;
assignLongToTriParameter(returnValue,
triParameterToLong(pars[0]) + triParameterToLong(pars[1]));
return TRI_OK;
}
TriStatus ef_calc_sub(const TriFunctionId* functionId,
TriParameterList* parameterList, TriParameter* returnValue)
{
TriParameter** pars = parameterList->parList;
assignLongToTriParameter(returnValue,
triParameterToLong(pars[0]) - triParameterToLong(pars[1]));
return TRI_OK;
}
TriStatus ef_calc_mul(const TriFunctionId* functionId,
TriParameterList* parameterList, TriParameter* returnValue)
{
TriParameter** pars = parameterList->parList;
assignLongToTriParameter(returnValue,
triParameterToLong(pars[0]) * triParameterToLong(pars[1]));
return TRI_OK;
}
TriStatus ef_calc_div(const TriFunctionId* functionId,
TriParameterList* parameterList, TriParameter* returnValue)
{
TriParameter** pars = parameterList->parList;
assignLongToTriParameter(returnValue,
triParameterToLong(pars[0]) / triParameterToLong(pars[1]));
return TRI_OK;
}
