OpenTTCN/Developer corner/Implementing external functions/Final/C sharp/PA impl.cs

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.cs


Back to main article >>

using System;
using System.Collections.Generic;

using OpenTTCN.Sdk;
using Etsi.Ttcn3.Tri;
using Etsi.Ttcn3.Tci;

namespace ExtFuncAdapter
{
    public class PA_impl : ITriPlatformPA
    {
        /***************************************************************************
         * Initialization of TRI interface (PA, user-provided part).
         */

        private delegate TriStatus ExtFuncPtr(
            ITriFunctionId functionId,
            ITriParameterList parameterList,
            ITriParameter returnValue);

        // Contains mappings of available external function implementations.
        // Key is function name, value is function pointer implementing the
        // external function with the specified name.
        static Dictionary<string, ExtFuncPtr> _extFuncMap;

        static PA_impl()
        {
            _extFuncMap = new Dictionary<string, ExtFuncPtr>();

            _extFuncMap.Add("ef_calc_sum", ef_calc_sum);
            _extFuncMap.Add("ef_calc_sub", ef_calc_sub);
            _extFuncMap.Add("ef_calc_mul", ef_calc_mul);
            _extFuncMap.Add("ef_calc_div", ef_calc_div);
            _extFuncMap.Add("ef_find_and_replace", ef_find_and_replace);
        }

        /***************************************************************************
         * Implementation of TRI interface (PA, user-provided part).
         */

        public TriStatus TriExternalFunction(
            ITriFunctionId functionId,
            ITriParameterList parameterList,
            ITriParameter returnValue)
        {
            string funcId = functionId.BaseName;
            Console.WriteLine("**************************************************************************");
            Console.WriteLine("*** DEBUG: TriExternalFunction() callback called. Function: " + funcId);

            if (_extFuncMap.ContainsKey(funcId))
            {
                return _extFuncMap[funcId](functionId, parameterList, returnValue);
            }

            string errMsg = "Unrecognized external function " + funcId + " called.";
            StartHere.ReportError(errMsg);

            return TriStatus.TriError;
        }

        public TriStatus TriPAReset()
        {
            return TriStatus.TriOk;
        }

        public TriStatus TriReadTimer(ITriTimerId timerId, ITriTimerDuration elapsedTime)
        {
            return TriStatus.TriError;
        }

        public TriStatus TriStartTimer(ITriTimerId timerId, ITriTimerDuration duration)
        {
            return TriStatus.TriError;
        }

        public TriStatus TriStopTimer(ITriTimerId timerId)
        {
            return TriStatus.TriError;
        }

        public TriStatus TriTimerRunning(ITriTimerId timerId, ITriBoolean running)
        {
            return TriStatus.TriError;
        }

        /***************************************************************************
         * External function implementation helpers.
         */

        public static long TriParameterToLong(ITriParameter src)
        {
            CD_impl cd = new CD_impl();
            ITciCDRequired req = StartHereCD.TciCDRequired;

            ITciIntegerValue v = (ITciIntegerValue)
                cd.Decode(new TriMessage(src.EncodedParameter), req.GetInteger());

            return v.IntegerValue;
        }

        public static void AssignLongToTriParameter(ITriParameter dst, long src)
        {
            CD_impl cd = new CD_impl();
            ITciCDRequired req = StartHereCD.TciCDRequired;

            ITciIntegerValue v = (ITciIntegerValue) req.GetInteger().NewInstance();
            v.IntegerValue = src;
            ITriMessage msg = cd.Encode(v);
            dst.EncodedParameter = msg.EncodedMessage;
        }

        public static string TriParameterToString(ITriParameter src)
        {
            CD_impl cd = new CD_impl();
            ITciCDRequired req = StartHereCD.TciCDRequired;

            ITciCharstringValue v = (ITciCharstringValue)
                cd.Decode(new TriMessage(src.EncodedParameter), req.GetCharstring());

            return v.StringValue;
        }

        public static void AssignStringToTriParameter(ITriParameter dst, string src)
        {
            CD_impl cd = new CD_impl();
            ITciCDRequired req = StartHereCD.TciCDRequired;

            ITciCharstringValue v = (ITciCharstringValue) req.GetCharstring().NewInstance();
            v.StringValue = src;
            ITriMessage msg = cd.Encode(v);
            dst.EncodedParameter = msg.EncodedMessage;
        }

        /***************************************************************************
         * External function implementations.
         */

        public static TriStatus ef_calc_sum(
            ITriFunctionId functionId,
            ITriParameterList parameterList,
            ITriParameter returnValue)
        {
            AssignLongToTriParameter(returnValue,
                TriParameterToLong(parameterList[0]) + TriParameterToLong(parameterList[1]));

            return TriStatus.TriOk;
        }

        public static TriStatus ef_calc_sub(
            ITriFunctionId functionId,
            ITriParameterList parameterList,
            ITriParameter returnValue)
        {
            AssignLongToTriParameter(returnValue,
                TriParameterToLong(parameterList[0]) - TriParameterToLong(parameterList[1]));

            return TriStatus.TriOk;
        }

        public static TriStatus ef_calc_mul(
        ITriFunctionId functionId,
        ITriParameterList parameterList,
        ITriParameter returnValue)
        {
            AssignLongToTriParameter(returnValue,
                TriParameterToLong(parameterList[0]) * TriParameterToLong(parameterList[1]));

            return TriStatus.TriOk;
        }

        public static TriStatus ef_calc_div(
        ITriFunctionId functionId,
        ITriParameterList parameterList,
        ITriParameter returnValue)
        {
            AssignLongToTriParameter(returnValue,
                TriParameterToLong(parameterList[0]) / TriParameterToLong(parameterList[1]));

            return TriStatus.TriOk;
        }

        private static void ef_find_and_replace_helper(
            ref string str /* inout */,
            string search_substr /* in */,
            string new_substr /* in */,
            out long occurences_num /* out */)
        {
            int i, len;
            int substr_size = (int) search_substr.Length;

            if (substr_size != new_substr.Length)
            {
                StartHere.ReportError("Strings size mismatch in ef_find_and_replace().");
                occurences_num = -1;
                return;
            }

            if (substr_size == 0)
            {
                StartHere.ReportError("Search string size is zero in ef_find_and_replace().");
                occurences_num = -1;
                return;
            }

            occurences_num = 0;
            if (substr_size > str.Length)
            {
                // No way bigger string can be a substring of the smaller one:
                return;
            }

            System.Text.StringBuilder sb = new System.Text.StringBuilder();

            len = str.Length - substr_size;
            for (i = 0; i <= len; i++)
            {
                if (str.Substring(i, substr_size) == search_substr)
                {
                    sb.Append(new_substr);
                    occurences_num++;
                    i += substr_size - 1;
                }
                else
                {
                    sb.Append(str[i]);
                }
            }

            if (i < str.Length) sb.Append(str.Substring(i, str.Length - i));

            str = sb.ToString();
        }

        public static TriStatus ef_find_and_replace(
            ITriFunctionId functionId,
            ITriParameterList parameterList,
            ITriParameter returnValue)
        {
            string str = TriParameterToString(parameterList[0]);
            string search_substr = TriParameterToString(parameterList[1]);
            string new_substr = TriParameterToString(parameterList[2]);
            long occurences_num;

            ef_find_and_replace_helper(
                ref str, search_substr, new_substr, out occurences_num);

            // It is safe to assume that inout str always changes:

            AssignStringToTriParameter(parameterList[0], str);

            // Perform mandatory assignment of occurences_num out parameter:

            AssignLongToTriParameter(parameterList[3], occurences_num);

            // Duplicate occurences_num in the return value:

            AssignLongToTriParameter(returnValue, occurences_num);

            return TriStatus.TriOk;
        }
    }
}
Views
Personal tools