Files
microser/mmslib/mmsl/mms_rtaa.c

1223 lines
37 KiB
C
Raw Normal View History

2026-06-15 15:48:16 +08:00
/************************************************************************/
/* SISCO SOFTWARE MODULE HEADER *****************************************/
/************************************************************************/
/* (c) Copyright Systems Integration Specialists Company, Inc., */
/* 1986 - 2002, All Rights Reserved. */
/* */
/* PROPRIETARY AND CONFIDENTIAL */
/* */
/* MODULE NAME : mms_rtaa.c */
/* PRODUCT(S) : MMSEASE */
/* */
/* MODULE DESCRIPTION : */
/* Function to decode ASN.1 type definitions into Runtime typedefs */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* _ms_mk_rt_aa_all */
/* _ms_mk_rt_aa */
/* _ms_get_rtaa_data_size */
/* _ms_log_runtime_aa */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 07/27/05 MDE 06 if m_max_rt_aa_cltr == 0 calc required size */
/* 05/11/05 MDE 05 Added _ms_calc_rt_aa_size */
/* 02/22/05 JRB 04 Make "sp" local to avoid VXWORKS conflict. */
/* 04/02/03 JRB 03 Add UTF8string support (see RT_UTF8_STRING). */
/* 03/04/02 JRB 02 Add more "SD_CONST RUNTIME_TYPE *". */
/* Make sure str_end_rtaa, arr_end_rtaa init'd. */
/* 02/06/02 JRB 01 New. Code from mms_alta.c moved here. */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "glbsem.h"
#include "mmsdefs.h"
#include "mms_pvar.h"
#include "mms_vvar.h"
#include "asn1defs.h"
/************************************************************************/
/* For debug version, use a static pointer to avoid duplication of */
/* __FILE__ strings. */
#ifdef DEBUG_SISCO
SD_CONST static ST_CHAR *SD_CONST thisFileName = __FILE__;
#endif
/************************************************************************/
/************************************************************************/
#define COPY_RTAA(dest,src) { dest->rt = src->rt;\
dest->offset_to_data = src->offset_to_data; }
/************************************************************************/
/************************************************************************/
/* This code is required for handling real alternate access data */
/* conversion via mmsdataa, and for using the ARB DATA handlers. */
/************************************************************************/
/************************************************************************/
/* Runtime AA (RTAA) Handling */
/************************************************************************/
/************************************************************************/
static ST_VOID _ms_calc_rt_aa_size (SD_CONST RUNTIME_TYPE *rt_head, ST_INT rt_num,
ST_INT *num_aa_out);
static ST_RET get_struct_comps (AA_APPLY_CTRL *aa_app, RT_AA_CTRL *w_rtaa);
static ST_RET get_arr_elmnts (AA_APPLY_CTRL *aa_app, RT_AA_CTRL *w_rtaa);
static ST_INT count_num_comp (AA_APPLY_CTRL *aa_app,
ALT_ACC_EL *aa,
ST_INT *count_out);
static RT_AA_CTRL *find_end_rtaa (AA_APPLY_CTRL *aa_app,
RT_AA_CTRL *start_rtaa);
static RT_AA_CTRL *find_named_comp (AA_APPLY_CTRL *aa_app,
ST_CHAR *name,
RT_AA_CTRL *w_rtaa);
static ST_RET get_component_elmnts (AA_APPLY_CTRL *aa_app,
RT_AA_CTRL *rtaa);
static RT_AA_CTRL *find_arr_el (AA_APPLY_CTRL *aa_app,
RT_AA_CTRL *w_rtaa,
ST_INT el_index);
static ST_VOID ms_rtaa_el_size_calc (RT_AA_CTRL *runtime_aa, ST_INT num_rt_aa);
static ST_INT arr_loop_level;
static ST_INT *arr_loops;
/************************************************************************/
/* Create a RTAA with all elements for the specified RT type */
/* This table is allocated via chk_calloc, and is sized for the max */
/* possible AA size. If desired, this may be realloc'd to the correct */
/* size by the caller. */
ST_RET _ms_mk_rt_aa_all (SD_CONST RUNTIME_TYPE *rt_head, ST_INT rt_num,
RT_AA_CTRL **rt_aa_out, ST_INT *num_aa_out)
{
RT_AA_CTRL *rtaa;
ST_INT data_offset;
SD_CONST RUNTIME_TYPE *rt_end;
SD_CONST RUNTIME_TYPE *rt;
ST_INT arr_loop_buf[ASN1_MAX_LEVEL];
ST_INT _max_rt_aa_ctrl;
S_LOCK_COMMON_RESOURCES ();
arr_loop_level = 0;
arr_loops = arr_loop_buf;
/* Allocate the output array for max size */
_max_rt_aa_ctrl = m_max_rt_aa_ctrl;
if (_max_rt_aa_ctrl == 0)
_ms_calc_rt_aa_size (rt_head, rt_num, &_max_rt_aa_ctrl);
rtaa = (RT_AA_CTRL *) chk_calloc (_max_rt_aa_ctrl, sizeof (RT_AA_CTRL));
*rt_aa_out = rtaa;
*num_aa_out = 0;
rt = rt_head; /* set runtime ptr */
rt_end = rt_head + rt_num; /* end block */
data_offset = 0;
/* Traverse the RT type as though we were doing a ASN.1 to LOCAL, and */
/* set the RTAA RT pointer and offset as each element is encountered. */
while (rt < rt_end)
{
if (rt->el_tag == RT_ARR_END) /* treat case of array ending */
{
if (--arr_loops[arr_loop_level] > 0) /* if need to do next ar elmnt */
{
rt -= rt->u.arr.num_rt_blks; /* mv rt to start of arr */
continue;
}
else
--arr_loop_level;
}
(*num_aa_out)++; /* Count this one */
rtaa->rt = rt; /* Set the RT pointer */
rtaa->offset_to_data = data_offset; /* Set the offset */
data_offset += rt->el_size; /* Offset for next */
if (rt->el_tag == RT_ARR_START) /* Set up array looping */
{
++arr_loop_level;
arr_loops[arr_loop_level] = rt->u.arr.num_elmnts;
}
rtaa++; /* point to next runtime AA element */
rt++; /* point to next runtime element */
}
/* Post process to calculate the 'rtaa->el_size' values (for packed */
/* local representation). */
ms_rtaa_el_size_calc (*rt_aa_out, *num_aa_out);
if (mms_debug_sel & MMS_LOG_RTAA)
_ms_log_runtime_aa (*rt_aa_out, *num_aa_out);
/* save the high water mark */
if (*num_aa_out > m_hw_rt_aa_ctrl)
m_hw_rt_aa_ctrl = *num_aa_out;
S_UNLOCK_COMMON_RESOURCES ();
return (SD_SUCCESS);
}
/************************************************************************/
/************************************************************************/
/* _ms_calc_rt_aa_size */
/************************************************************************/
static ST_VOID _ms_calc_rt_aa_size (SD_CONST RUNTIME_TYPE *rt_head, ST_INT rt_num,
ST_INT *num_aa_out)
{
SD_CONST RUNTIME_TYPE *rt_end;
SD_CONST RUNTIME_TYPE *rt;
ST_INT arr_loop_buf[ASN1_MAX_LEVEL];
ST_INT num_aa;
S_LOCK_COMMON_RESOURCES ();
arr_loop_level = 0;
arr_loops = arr_loop_buf;
num_aa = 0;
rt = rt_head; /* set runtime ptr */
rt_end = rt_head + rt_num; /* end block */
/* Traverse the RT type as though we were doing a ASN.1 to LOCAL, and */
/* count the RTAA elements */
while (rt < rt_end)
{
if (rt->el_tag == RT_ARR_END) /* treat case of array ending */
{
if (--arr_loops[arr_loop_level] > 0) /* if need to do next ar elmnt */
{
rt -= rt->u.arr.num_rt_blks; /* mv rt to start of arr */
continue;
}
else
--arr_loop_level;
}
++num_aa; /* Count this one */
if (rt->el_tag == RT_ARR_START) /* Set up array looping */
{
++arr_loop_level;
arr_loops[arr_loop_level] = rt->u.arr.num_elmnts;
}
rt++; /* point to next runtime element */
}
*num_aa_out = num_aa;
S_UNLOCK_COMMON_RESOURCES ();
}
/************************************************************************/
/************************************************************************/
/************************************************************************/
/* Create a RTAA with elements selected by a AA for the specified RT */
/* type */
/* This table is allocated via chk_calloc, and is sized for the max */
/* possible AA size. If desired, this may be realloc'd to the correct */
/* size by the caller. */
ST_RET _ms_mk_rt_aa (SD_CONST RUNTIME_TYPE *rt, ST_INT rt_num,
ALT_ACCESS *alt_acc,
RT_AA_CTRL **rt_aa_out, ST_INT *num_aa_out)
{
ALT_ACC_EL *aa;
ST_INT num_aa;
ST_RET ret;
ST_INT num_all_rtaa;
RT_AA_CTRL *all_rtaa;
RT_AA_CTRL *rtaa;
AA_APPLY_CTRL aa_app_ctrl;
ST_UINT32 mms_log_mask_save;
ST_INT _max_rt_aa_ctrl;
S_LOCK_COMMON_RESOURCES ();
aa = alt_acc->aa;
num_aa = alt_acc->num_aa;
/* Make the 'all' rtaa - has all elements expanded, with offsets. */
/* This is used with the AA to select the elements for the new RTAA */
/* Don't allow logging of the 'all' runtime aa table */
mms_log_mask_save = mms_debug_sel;
mms_debug_sel &= ~MMS_LOG_RTAA;
ret = _ms_mk_rt_aa_all (rt, rt_num, &all_rtaa, &num_all_rtaa);
mms_debug_sel = mms_log_mask_save;
if (ret)
{
S_UNLOCK_COMMON_RESOURCES ();
return (ret);
}
/* Allocate the output (new) RT AA table */
_max_rt_aa_ctrl = m_max_rt_aa_ctrl;
if (_max_rt_aa_ctrl == 0)
_ms_calc_rt_aa_size (rt, rt_num, &_max_rt_aa_ctrl);
rtaa = (RT_AA_CTRL *) chk_calloc (_max_rt_aa_ctrl, sizeof (RT_AA_CTRL));
*rt_aa_out = rtaa;
*num_aa_out = 0;
/* Initialize the AA process control structure components */
/* Alternate Access */
aa_app_ctrl.num_aa = num_aa;
aa_app_ctrl.aa_head = aa;
aa_app_ctrl.aa_end = aa + num_aa - 1;
aa_app_ctrl.curr_aa = aa;
/* Default RTAA */
aa_app_ctrl.num_all_rtaa = num_all_rtaa;
aa_app_ctrl.all_rtaa_head = all_rtaa;
aa_app_ctrl.all_rtaa_end = all_rtaa + (num_all_rtaa -1);
/* New RTAA */
aa_app_ctrl.num_rtaa = 0;
aa_app_ctrl.rtaa_head = rtaa;
aa_app_ctrl.curr_rtaa = rtaa;
/* Nest Level */
aa_app_ctrl.nest = 0;
/* Get the appropriate rt_aa_ctrl elements */
/* Start by getting the first nest level elements, based on the RT. */
/* Note that these functions will call recursively to get handle */
/* further nest levels */
if (rt->el_tag == RT_ARR_START)
{
ret = get_arr_elmnts (&aa_app_ctrl, all_rtaa);
}
else if (rt->el_tag == RT_STR_START)
{
ret = get_struct_comps (&aa_app_ctrl, all_rtaa);
}
else
{
MLOG_NERR0 ("Runtime Type must be a Structure or Array for AA");
ret = MVE_RT_TYPE;
}
/* If successful, set the output AA count and log if enabled */
if (ret == SD_SUCCESS)
{
*num_aa_out = aa_app_ctrl.num_rtaa;
/* Post process to calculate the 'rtaa->el_size' values (for packed */
/* local representation). */
ms_rtaa_el_size_calc (*rt_aa_out, *num_aa_out);
if (mms_debug_sel & MMS_LOG_RTAA)
_ms_log_runtime_aa (*rt_aa_out, *num_aa_out);
/* save the high water mark */
if (*num_aa_out > m_hw_rt_aa_ctrl)
m_hw_rt_aa_ctrl = *num_aa_out;
}
else
{
chk_free (rtaa); /* If error, need to free the RTAA */
}
chk_free (all_rtaa); /* we are done with the 'all' RTAA */
S_UNLOCK_COMMON_RESOURCES ();
return (ret);
}
/************************************************************************/
/* We are working on a structure level, and need to copy the selected */
/* RTAA components for this nest level. This function can be called */
/* recursively as further nesting levels are encountered. */
/* The 'w_rtaa' parameter is the 'working' RTAA, and is used to select */
/* the scope (nest) for the operation */
static ST_RET get_struct_comps (AA_APPLY_CTRL *aa_app, RT_AA_CTRL *w_rtaa)
{
ST_RET ret;
RT_AA_CTRL *o_rtaa;
ALT_ACC_EL *aa;
ST_INT num_str_comp;
RT_AA_CTRL *start_rtaa;
RT_AA_CTRL *str_end_rtaa = NULL;
ST_BOOLEAN done;
/* get working pointers */
aa = aa_app->curr_aa; /* Current AA */
o_rtaa = aa_app->curr_rtaa; /* Output RTAA */
/* Check to see if we need to have the outer structure */
/* We need this if there are more than 1 named components selected */
if (count_num_comp (aa_app, aa, &num_str_comp))
return (MVE_AA_SELECT);
if (num_str_comp != 1)
{
str_end_rtaa = find_end_rtaa (aa_app, w_rtaa);
if (!str_end_rtaa)
return (MVE_AA_SELECT);
/* Write the start component of the output rtaa */
COPY_RTAA (o_rtaa,w_rtaa);
aa_app->num_rtaa++;
aa_app->curr_rtaa++;
}
/* Get all selected named components */
ret = SD_SUCCESS;
done = SD_FALSE;
while (!done && ret == SD_SUCCESS)
{
aa = aa_app->curr_aa; /* get current AA pointer */
o_rtaa = aa_app->curr_rtaa; /* get the output RTAA pointer */
/* This AA sel type can be a named component (w/wo further nesting) */
/* or a 'end nest' element. */
switch (aa->sel_type)
{
case AA_COMP :
/* This AA selects a entire named component. Just find the */
/* component name in the ALL RTAA and copy it's RTAA elements */
start_rtaa = find_named_comp (aa_app, aa->u.component, w_rtaa);
if (!start_rtaa)
{
return (MVE_AA_SELECT);
}
ret = get_component_elmnts (aa_app, start_rtaa);
++aa_app->curr_aa;
break;
case AA_COMP_NEST :
/* This AA selects a named component, with further selection. */
/* Find the component name in the ALL RTAA and call recursively */
/* to get the components. */
/* This component must be a structure or an array, so that we */
/* need to call recursively to get the selected RT AA elements */
start_rtaa = find_named_comp (aa_app, aa->u.component, w_rtaa);
if (!start_rtaa)
return (MVE_AA_SELECT);
++aa_app->nest; /* Increment the nest level */
/* Point to the next AA */
if (aa_app->curr_aa < aa_app->aa_end)
++aa_app->curr_aa;
else
{
MLOG_NERR0 ("AA table too small");
return (MVE_AA_SELECT);
}
/* Based on the RT type, get the next level with the scope */
/* defined by the start RTAA. */
if (start_rtaa->rt->el_tag == RT_ARR_START)
{
ret = get_arr_elmnts (aa_app, start_rtaa);
}
else if (start_rtaa->rt->el_tag == RT_STR_START)
{
ret = get_struct_comps (aa_app, start_rtaa);
}
else
{
MLOG_NERR0 ("Incorrect RT Type for further nesting");
return (MVE_RT_TYPE);
}
--aa_app->nest; /* Decrement the nest level */
/* curr_aa should now point to our END_NEST, consume it */
if (aa_app->curr_aa->sel_type != AA_END_NEST)
{
MLOG_NERR0 ("Required AA_END_NEST not present");
return (MVE_AA_SELECT);
}
else /* Consume the AA_END_NEST */
++aa_app->curr_aa;
break;
case AA_END_NEST :
done = SD_TRUE; /* This level is complete */
break;
case AA_ALL :
case AA_ALL_NEST :
case AA_INDEX_NEST :
case AA_INDEX_RANGE_NEST :
case AA_INDEX :
case AA_INDEX_RANGE :
MLOG_NERR0 ("Incorrect AA sel_type for structure component selection");
return (MVE_AA_SELECT);
break;
default :
MLOG_NERR0 ("Invalid AA sel_type");
return (MVE_AA_SELECT);
break;
}
/* Prepare to look at next AA, if this was not the last */
if (aa_app->curr_aa > aa_app->aa_end)
done = SD_TRUE;
} /* End while getting named components at this level */
/* Don't continue if an error was detected */
if (ret)
return (ret);
/* Now copy the structure end element if required */
if (num_str_comp != 1)
{
o_rtaa = aa_app->curr_rtaa;
COPY_RTAA (o_rtaa, str_end_rtaa);
aa_app->num_rtaa++;
aa_app->curr_rtaa++;
}
return (ret);
}
/************************************************************************/
/* We are working on a array selection, and need to copy the selected */
/* RTAA components for this selection. This function can be called */
/* recusively as further nesting levels are encountered. */
/* The 'w_rtaa' parameter is the 'working' RTAA, and is used to select */
/* the scope (nest) for the operation */
static ST_RET get_arr_elmnts (AA_APPLY_CTRL *aa_app, RT_AA_CTRL *w_rtaa)
{
ST_RET ret;
ST_INT i;
RT_AA_CTRL *el_rtaa;
RT_AA_CTRL *o_rtaa;
RT_AA_CTRL *arr_end_rtaa = NULL;
ST_INT nest;
ALT_ACC_EL *aa;
ST_INT num_el;
ST_INT start_el;
ST_INT curr_el;
ret = SD_SUCCESS;
/* get working pointers */
aa = aa_app->curr_aa; /* Current AA */
o_rtaa = aa_app->curr_rtaa; /* Output RTAA */
/* This AA sel type must be one of the array selection types, */
/* (w/wo further nesting) */
/* Start by determining the number of elements and the start element */
switch (aa->sel_type)
{
case AA_INDEX :
case AA_INDEX_NEST :
num_el = 1;
start_el = (ST_INT) aa->u.index;
break;
case AA_INDEX_RANGE :
case AA_INDEX_RANGE_NEST :
num_el = (ST_INT) aa->u.ir.num_elmnts;
start_el = (ST_INT) aa->u.ir.low_index;
if (!num_el && !start_el)
{
num_el = w_rtaa->rt->u.arr.num_elmnts;
start_el = 0;
}
break;
case AA_ALL :
case AA_ALL_NEST :
num_el = w_rtaa->rt->u.arr.num_elmnts;
start_el = 0;
break;
case AA_COMP :
case AA_COMP_NEST :
MLOG_NERR0 ("Invalid AA Type");
return (MVE_AA_SELECT);
break;
default :
MLOG_NERR0 ("Bad AA Type");
return (MVE_AA_SELECT);
break;
}
/* num_el is the number of elements to get, start_el is the base index */
/* w_rtaa points to the start of the array in the default RTAA */
/* Determine whether the array elements have further AA select ... */
if (aa->sel_type == AA_INDEX_NEST ||
aa->sel_type == AA_INDEX_RANGE_NEST ||
aa->sel_type == AA_ALL_NEST)
{
nest = SD_TRUE;
}
else
nest = SD_FALSE;
/* Check to see if we need to have the outer array */
/* We need this if there are more than 1 element selected */
if (num_el != 1)
{
arr_end_rtaa = find_end_rtaa (aa_app, w_rtaa);
if (!arr_end_rtaa)
return (MVE_AA_SELECT);
/* Write the start component of the output rtaa */
COPY_RTAA (o_rtaa,w_rtaa);
aa_app->num_rtaa++;
aa_app->curr_rtaa++;
}
/* Now we work through the array elements, getting them one at a time */
curr_el = start_el;
for (i = 0; i < num_el && ret == SD_SUCCESS; ++i, ++curr_el)
{
aa_app->curr_aa = aa; /* Restore the working AA position */
o_rtaa = aa_app->curr_rtaa; /* Output RTAA */
/* Move the working RTAA pointer to the next element to be selected */
el_rtaa = find_arr_el (aa_app, w_rtaa, curr_el);
if (!el_rtaa)
return (MVE_AA_SELECT);
/* If further selection is to take place, do it */
if (nest)
{
/* Set up working parameters for the nest level of nesting */
if (aa_app->curr_aa < aa_app->aa_end)
++aa_app->curr_aa;
else
{
MLOG_NERR0 ("AA table too small");
return (MVE_AA_SELECT);
}
++aa_app->nest; /* Increment the nest level */
if (el_rtaa->rt->el_tag == RT_ARR_START)
{
ret = get_arr_elmnts (aa_app, el_rtaa);
}
else if (el_rtaa->rt->el_tag == RT_STR_START)
{
ret = get_struct_comps (aa_app, el_rtaa);
}
else /* Whoops, internal error */
{
MLOG_NERR0 ("Bad RT Type for further AA selection");
return (MVE_RT_TYPE);
}
--aa_app->nest; /* Decrement the nest level */
}
else /* No further selection, copy the compoment */
{
ret = get_component_elmnts (aa_app, el_rtaa);
}
} /* end for each selected element */
/* Now copy the array end element if required */
if (ret == SD_SUCCESS && num_el != 1)
{
o_rtaa = aa_app->curr_rtaa;
COPY_RTAA (o_rtaa, arr_end_rtaa);
aa_app->num_rtaa++;
aa_app->curr_rtaa++;
}
if (nest)
{
/* curr_aa should now point to our END_NEST, consume it */
if (aa_app->curr_aa->sel_type != AA_END_NEST)
{
MLOG_NERR0 ("Required AA_END_NEST not present");
ret = MVE_AA_SELECT;
}
else /* Consume the AA_END_NEST */
++aa_app->curr_aa;
}
else
++aa_app->curr_aa; /* Point to the next AA */
return (ret);
}
/************************************************************************/
/************************************************************************/
/* Given the array or structure start RTAA pointer, return a pointer to */
/* the corresponding end element */
static RT_AA_CTRL *find_end_rtaa (AA_APPLY_CTRL *aa_app,
RT_AA_CTRL *start_rtaa)
{
SD_CONST RUNTIME_TYPE *start_rt;
SD_CONST RUNTIME_TYPE *end_rt;
ST_INT num_rt;
RT_AA_CTRL *rtaa;
start_rt = start_rtaa->rt;
if (start_rt->el_tag == RT_ARR_START)
{
num_rt = start_rt->u.arr.num_rt_blks;
}
else if (start_rt->el_tag == RT_STR_START)
{
num_rt = start_rt->u.str.num_rt_blks;
}
else
{
MLOG_NERR0 ("Bad RT Type");
return (NULL);
}
end_rt = start_rt + (num_rt + 1);
/* Just a trivial sanity check */
if (end_rt->el_tag != RT_ARR_END &&
end_rt->el_tag != RT_STR_END)
{
MLOG_NERR0 ("Bad RT Type");
return (NULL);
}
/* Now find the RTAA that has a reference to the end structure */
/* within this scope (we hope!) */
for (rtaa = start_rtaa; rtaa <= aa_app->all_rtaa_end; ++rtaa)
{
if (rtaa->rt == end_rt)
return (rtaa);
}
MLOG_NERR0 ("End RT Not Found");
return (NULL);
}
/************************************************************************/
/* Copy the current RTAA element, including any sub-elements */
static ST_RET get_component_elmnts (AA_APPLY_CTRL *aa_app, RT_AA_CTRL *rtaa)
{
RT_AA_CTRL *last_rtaa;
RT_AA_CTRL *dest_rtaa;
if (rtaa->rt->el_tag == RT_ARR_START ||
rtaa->rt->el_tag == RT_STR_START)
{
last_rtaa = find_end_rtaa (aa_app, rtaa);
if (!last_rtaa)
return (MVE_AA_SELECT);
}
else /* Simple element, just copy one */
last_rtaa = rtaa;
dest_rtaa = aa_app->curr_rtaa;
while (rtaa <= last_rtaa)
{
COPY_RTAA (dest_rtaa, rtaa);
aa_app->num_rtaa++;
aa_app->curr_rtaa++;
++dest_rtaa;
++rtaa;
}
return (SD_SUCCESS);
}
/************************************************************************/
/************************************************************************/
/* Count the number of named components selected at this level */
/* by the alternate access select */
static ST_INT count_num_comp (AA_APPLY_CTRL *aa_app,
ALT_ACC_EL *aa,
ST_INT *count_out)
{
ST_INT count;
ST_INT nest;
ST_INT done;
done = SD_FALSE;
nest = 0;
count = 0;
while (done == SD_FALSE)
{
switch (aa->sel_type)
{
case AA_COMP :
if (nest == 0)
++count;
break;
case AA_COMP_NEST :
if (nest == 0)
++count;
nest++;
break;
case AA_INDEX :
case AA_INDEX_RANGE :
case AA_ALL :
break;
case AA_INDEX_NEST :
case AA_INDEX_RANGE_NEST :
case AA_ALL_NEST :
nest++;
break;
case AA_END_NEST :
if (--nest < 0)
done = SD_TRUE;
break;
default :
MLOG_NERR0 ("Bad AA Type");
return (MVE_AA_SELECT);
break;
}
if (aa >= aa_app->aa_end) /* If we are done (level 0 only) */
done = SD_TRUE;
aa++; /* Point to next */
}
*count_out = count;
return (SD_SUCCESS);
}
/************************************************************************/
/* Given a RTAA pointer, find a named component at the current nest */
/* The 'w_rtaa' parameter is the 'working' RTAA, and is used to select */
/* the scope (nest) for the operation */
static RT_AA_CTRL *find_named_comp (AA_APPLY_CTRL *aa_app,
ST_CHAR *name,
RT_AA_CTRL *w_rtaa)
{
ST_INT nest;
ST_INT err;
if (w_rtaa->rt->el_tag != RT_STR_START)
{
MLOG_NERR0 ("Bad RT Type - must be structure start");
return (NULL);
}
w_rtaa++;
nest = 0;
err = SD_FALSE;
while (!err)
{
if (nest == 0 &&
!strcmp (name, ms_comp_name_find (w_rtaa->rt)))
{
return (w_rtaa);
}
switch (w_rtaa->rt->el_tag)
{
case RT_ARR_START :
case RT_STR_START :
nest++;
break;
case RT_STR_END :
case RT_ARR_END :
if (--nest < 0)
break;
break;
case RT_BOOL :
case RT_BIT_STRING :
case RT_INTEGER :
case RT_UNSIGNED :
case RT_FLOATING_POINT :
case RT_OCTET_STRING :
case RT_VISIBLE_STRING :
case RT_GENERAL_TIME :
case RT_BINARY_TIME :
case RT_BCD :
case RT_UTC_TIME :
case RT_BOOLEANARRAY :
case RT_UTF8_STRING :
break;
default :
err = SD_TRUE;
MLOG_NERR0 ("Bad RT Type");
break;
}
w_rtaa++;
if (w_rtaa >= aa_app->all_rtaa_end)
break;
}
MLOG_NERR1 ("AA Named component (%s) not found", name);
return (NULL);
}
/************************************************************************/
/************************************************************************/
/* Given a 'working' RTAA pointer to the RT_ARR_START element and the */
/* element index, return a pointer to the start RTAA for the element */
/* The 'w_rtaa' parameter is the 'working' RTAA, and is used to select */
/* the scope (nest) for the operation */
static RT_AA_CTRL *find_arr_el (AA_APPLY_CTRL *aa_app,
RT_AA_CTRL *w_rtaa,
ST_INT el_index)
{
RT_AA_CTRL *ret_rtaa;
SD_CONST RUNTIME_TYPE *arr_rt;
SD_CONST RUNTIME_TYPE *start_rt;
ST_INT el;
arr_rt = w_rtaa->rt;
if (arr_rt->el_tag != RT_ARR_START)
{
MLOG_NERR0 ("RTAA is not RT_ARR_START");
return (NULL);
}
if (el_index >= arr_rt->u.arr.num_elmnts)
{
MLOG_NERR0 ("Index out of range");
return (NULL);
}
/* Now we need to locate the el_index'th element. To do this, we first */
/* get a pointer to the 0'th element's first RT block, then search for */
/* the el_index'th occurance of the RT within the RTAA */
w_rtaa++; /* 0'th element */
start_rt = w_rtaa->rt; /* Start RT block */
el = 0;
while (w_rtaa <= aa_app->all_rtaa_end) /* while still in RTAA */
{
if (w_rtaa->rt == start_rt) /* if start of an element */
{
if (el == el_index) /* if selected element */
return (w_rtaa); /* we found it */
else
++el; /* maybe next time */
}
w_rtaa++; /* look at next RTAA */
}
ret_rtaa = (w_rtaa+1) + (el_index * arr_rt->u.arr.num_rt_blks);
return (ret_rtaa);
}
/************************************************************************/
/* ms_rtaa_el_size_calc */
/************************************************************************/
/* Given a RTAA table, calculate the 'el_size' for each element. This */
/* is done by using the alignment control table, and is used only for */
/* encoding/decoding AA data that is 'packed' in local memory. */
static ST_VOID ms_rtaa_el_size_calc (RT_AA_CTRL *runtime_aa,
ST_INT num_rt_aa)
{
ST_INT ellen;
SD_CONST RUNTIME_TYPE *rt;
RT_AA_CTRL *rtaa_above;
ST_INT curr_offset;
ST_INT pad;
ST_INT algn;
ST_INT i;
curr_offset = 0; /* Offset from start of data */
rtaa_above = NULL;
for (i = 0; i < num_rt_aa; ++i, ++runtime_aa)
{
rt = runtime_aa->rt;
/* Get 'algnment index' and size of the element (excluding padding) */
_ms_m_get_rt_info (rt, &algn, &ellen);
/* Set the base element size, before padding */
runtime_aa->el_size = ellen;
/* Check to see if padding on the element above is required for */
/* alignment for this element, add it if so. */
/* Increment the offset until no bits are set that shouldn't be */
pad = 0;
while (curr_offset & algn)
{
curr_offset++;
pad++;
}
if (pad)
{
if (!rtaa_above) /* First element better not require alignment */
{
MLOG_ERR0 ("Alignment table error");
}
else /* add pad to element above */
rtaa_above->el_size += pad;
}
/* Save the pointer to the previous RT element (not this one's name) */
rtaa_above = runtime_aa;
/* Point past the current element */
curr_offset += ellen;
}
}
/************************************************************************/
/* _ms_get_rtaa_data_size */
/************************************************************************/
ST_INT _ms_get_rtaa_data_size (RT_AA_CTRL *runtime_aa,
ST_INT num_rt_aa)
{
ST_INT i;
ST_INT size;
size = 0;
for (i = 0; i < num_rt_aa; ++i, ++runtime_aa)
size += runtime_aa->el_size;
return (size);
}
/************************************************************************/
/************************************************************************/
/* LOGGING FUNCTIONS */
/************************************************************************/
/************************************************************************/
/************************************************************************/
/* _ms_log_runtime_aa */
/************************************************************************/
ST_VOID _ms_log_runtime_aa (RT_AA_CTRL *rt_aa, ST_INT num_aa)
{
#ifdef DEBUG_SISCO
SD_CONST RUNTIME_TYPE *rt;
ST_INT i;
ST_INT indent;
SD_CONST ST_CHAR *comp_name;
/* Use these strings to keep logging aligned and indented as desired */
#define MAX_INDENT 5
SD_CONST ST_CHAR *sp[MAX_INDENT] =
{
" ",
" ",
" ",
" ",
" ",
};
SD_CONST ST_CHAR *sp2[MAX_INDENT] =
{
" ",
" ",
" ",
" ",
"",
};
S_LOCK_COMMON_RESOURCES ();
indent = 0;
MLOG_ALWAYS1 ("RTAA : %d elements", num_aa);
for (i = 0; i < num_aa; ++i, rt_aa++)
{
rt = rt_aa->rt;
comp_name = ms_comp_name_find (rt);
if (strlen (comp_name))
{
MLOG_CALWAYS3 ("%sNamed comp %s: %s",
sp[indent],
sp2[indent],
comp_name);
}
switch (rt->el_tag)
{
case RT_ARR_START :
MLOG_CALWAYS5 ("%sArray start %s: size %02d, %02d elmnts, %02d rt",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.arr.num_elmnts,
rt->u.arr.num_rt_blks);
if (++indent >= MAX_INDENT)
indent--;
break;
case RT_ARR_END :
if (--indent < 0)
indent++;
MLOG_CALWAYS5 ("%sArray end %s: size %02d, %02d elmnts, %02d rt",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.arr.num_elmnts,
rt->u.arr.num_rt_blks);
break;
case RT_STR_START :
MLOG_CALWAYS3 ("%sStruct start%s: size %02d",
sp[indent],
sp2[indent],
rt_aa->el_size);
if (++indent >= MAX_INDENT)
indent--;
break;
case RT_STR_END :
if (--indent < 0)
indent++;
MLOG_CALWAYS3 ("%sStruct end %s: size %02d",
sp[indent],
sp2[indent],
rt_aa->el_size);
break;
case RT_BOOL :
MLOG_CALWAYS5 ("%sBoolean %s: size %02d, precision %02d, offset %d",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.p.el_len,
rt_aa->offset_to_data);
break;
case RT_BIT_STRING :
MLOG_CALWAYS5 ("%sBitstring %s: size %02d, precision %02d, offset %d",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.p.el_len,
rt_aa->offset_to_data);
break;
case RT_INTEGER :
MLOG_CALWAYS5 ("%sInteger %s: size %02d, precision %02d, offset %d",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.p.el_len,
rt_aa->offset_to_data);
break;
case RT_UNSIGNED :
MLOG_CALWAYS5 ("%sUnsigned %s: size %02d, precision %02d, offset %d",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.p.el_len,
rt_aa->offset_to_data);
break;
case RT_FLOATING_POINT :
MLOG_CALWAYS5 ("%sFloat %s: size %02d, precision %02d, offset %d",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.p.el_len,
rt_aa->offset_to_data);
break;
case RT_OCTET_STRING :
MLOG_CALWAYS5 ("%sOctet Str %s: size %02d, precision %02d, offset %d",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.p.el_len,
rt_aa->offset_to_data);
break;
case RT_VISIBLE_STRING :
MLOG_CALWAYS5 ("%sVisible Str %s: size %02d, precision %02d, offset %d",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.p.el_len,
rt_aa->offset_to_data);
break;
case RT_GENERAL_TIME :
MLOG_CALWAYS5 ("%sGen Time %s: size %02d, precision %02d, offset %d",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.p.el_len,
rt_aa->offset_to_data);
break;
case RT_BINARY_TIME :
MLOG_CALWAYS5 ("%sBin Time %s: size %02d, precision %02d, offset %d",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.p.el_len,
rt_aa->offset_to_data);
break;
case RT_BCD :
MLOG_CALWAYS5 ("%sBCD %s: size %02d, precision %02d, offset %d",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.p.el_len,
rt_aa->offset_to_data);
break;
case RT_UTC_TIME :
MLOG_CALWAYS5 ("%sUtc Time %s: size %02d, precision %02d, offset %d",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.p.el_len,
rt_aa->offset_to_data);
break;
case RT_UTF8_STRING :
MLOG_CALWAYS5 ("%sUTF8 Str %s: size %02d, precision %02d, offset %d",
sp[indent],
sp2[indent],
rt_aa->el_size,
rt->u.p.el_len,
rt_aa->offset_to_data);
break;
default : /* should not be any other tag */
MLOG_CALWAYS1 (" **** UNKNOWN ELEMENT %02d ",i);
break;
}
}
S_UNLOCK_COMMON_RESOURCES ();
#endif
}