OpenTTCN/Developer corner/Implementing external functions/Modified/C/PA impl.cxx

From OpenTTCN

Jump to: navigation, search

  OpenTTCN DocZone

  Home | Developer's corner | Knowledge base | Working documents | Documentation | OpenTTCN IDE | Tutorials | Training | How do I | Frequently asked questions | Technical support


PA_impl.cxx


Back to main article >>

#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;
}
Views
Personal tools