Files
microser/mmslib/mvlu/mvl_dtyp.c

533 lines
16 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., */
/* 1994 - 2005, All Rights Reserved */
/* */
/* MODULE NAME : mvl_dtyp.c */
/* PRODUCT(S) : MMSEASE-LITE */
/* */
/* MODULE DESCRIPTION : */
/* */
/* GLOBAL FUNCTIONS DEFINED IN THIS MODULE : */
/* NONE */
/* */
/* MODIFICATION LOG : */
/* Date Who Rev Comments */
/* -------- --- ------ ------------------------------------------- */
/* 01/19/05 JRB 08 Use mvlu_trim_branch_name from mvl_uca.c */
/* 12/19/02 JRB 07 Use ms_comp_name_find, ms_comp_name_pres. */
/* 11/19/02 RKR 06 Corrected size in cardinality function */
/* 02/27/02 JRB 05 Del unneeded prototypes & includes. */
/* 12/04/01 RKR 04 ported to QNX cleaned up errors and warnings */
/* 11/09/01 RKR 03 resorted the num_rt_blks */
/* 01/21/00 MDE 02 Now use MEM_SMEM for dynamic memory */
/* 10/05/99 RKR 01 Created */
/************************************************************************/
#include "glbtypes.h"
#include "sysincs.h"
#include "mmsdefs.h"
#include "mms_pvar.h"
#include "mms_vvar.h"
#include "mms_pvmd.h"
#include "mms_err.h"
#include "mms_pcon.h"
#include "mvl_log.h"
#include "mvl_defs.h"
#include "mvl_uca.h" /* need mvlu_trim_branch_name */
#include "asn1defs.h"
#include "stime.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
static ST_UCHAR *create_bitstring (ST_INT num);
static ST_VOID set_bit ( ST_UCHAR *bptr, ST_INT i);
static ST_BOOLEAN ismember( ST_UCHAR *bptr,
ST_INT n);
static ST_VOID reSortRT (RUNTIME_TYPE *rt, ST_INT numRt);
static ST_VOID add_to_branch_name (ST_CHAR *branch_name, SD_CONST ST_CHAR *SD_CONST sub_branch_name);
static ST_INT cardinality (ST_UCHAR *bptr, ST_INT size);
static ST_VOID calc_offset_to_last (RUNTIME_TYPE *rt);
ST_VOID mvl_print_type( ST_CHAR *base_name, ST_INT typeIdIn);
#ifndef __ECOS
ST_BOOLEAN u_mvl_rt_element_supported (RUNTIME_TYPE *rt,
ST_CHAR *element_name,
ST_RTREF *ui, ST_CHAR *handle);
#endif
ST_VOID adjRtBlks( RUNTIME_TYPE *derived_type_table, ST_INT derived_count);
/************************************************************************/
/* mvl_derive_new_type */
/************************************************************************/
ST_RET mvl_derive_new_type (ST_CHAR *base_name, ST_INT typeIdIn, ST_INT *typeIdOut, ST_CHAR *handle)
{
ST_RET ret;
ST_RTREF rtrefs;
ST_UCHAR *membership;
ret = mvl_derive_type_members (base_name, typeIdIn, &membership, &rtrefs, handle );
mvl_print_derived_type (base_name, typeIdIn, membership, rtrefs);
ret = mvl_add_derived_type (base_name, typeIdIn, membership, rtrefs, typeIdOut);
return (ret);
}
/************************************************************************/
/* mvl_derive_type_members */
/************************************************************************/
ST_RET mvl_derive_type_members (ST_CHAR *base_name, ST_INT typeIdIn,
ST_UCHAR **membership, ST_RTREF *rtrefs, ST_CHAR *handle)
{
ST_RET ret = SD_FAILURE;
RUNTIME_TYPE *rt;
ST_INT num_rt;
ST_BOOLEAN exists;
ST_CHAR element_name[MAX_IDENT_LEN+1];
ST_CHAR branch_name[MAX_IDENT_LEN+1];
ST_RTREF *user_info;
ST_INT i;
ST_RTREF ui; /* let the user pass back widget of unknown purpose */
ST_UCHAR *bptr;
ret = mvl_get_runtime (typeIdIn, &rt, &num_rt);
if (ret != SD_SUCCESS)
{
MVL_LOG_NERR1 ("TypeId %d not found",typeIdIn);
return (ret);
}
bptr = create_bitstring (num_rt);
*membership = bptr;
user_info = (ST_RTREF *) M_CALLOC (MSMEM_GEN, num_rt, sizeof(ST_RTREF *));
*rtrefs = user_info;
for (i=0; i<num_rt; i++)
{
exists = SD_FALSE;
if ((rt[i].el_tag == RT_STR_START) && (ms_comp_name_pres(&rt[i])))
{
add_to_branch_name (branch_name, ms_comp_name_find(&rt[i]));
strcpy (element_name, branch_name);
}
else
{
if (ms_comp_name_pres(&rt[i]))
sprintf (element_name, "%s$%s", branch_name, ms_comp_name_find(&rt[i]));
else
{
if (i==0) /* This is the start of the entire RuntimeType */
{
strcpy (branch_name, base_name);
strcpy (element_name, branch_name);
}
else
element_name[0]=0; /* nobody home */
}
}
if (rt[i].el_tag == RT_STR_END)
{
strcpy( element_name, branch_name);
mvlu_trim_branch_name (branch_name);
}
ui = rt[i].mvluTypeInfo.ref;
#ifndef __ECOS
exists = u_mvl_rt_element_supported(&rt[i], element_name, &ui, handle);
#endif
if (exists)
{
set_bit (bptr, i);
user_info[i] = ui;
}
}
return (ret);
}
/************************************************************************/
/* mvl_add_derived_type */
/************************************************************************/
ST_RET mvl_add_derived_type( ST_CHAR *base_name, ST_INT typeIdIn,
ST_UCHAR *membership, ST_RTREF *rtrefs,
ST_INT *typeIdOut)
{
ST_RET ret;
ST_INT derived_elements;
RUNTIME_TYPE *derived_type_table;
ST_INT derived_count;
RUNTIME_TYPE *rt;
ST_INT num_rt;
ST_INT i;
ret = mvl_get_runtime (typeIdIn, &rt, &num_rt);
if (ret != SD_SUCCESS)
{
MVL_LOG_NERR1 ("TypeId %d not found",typeIdIn);
return (ret);
}
/* count how many elements are in the new type */
derived_elements = cardinality( membership, num_rt);
/* allocate a new RT type table about that large */
derived_type_table = (RUNTIME_TYPE *)M_CALLOC (MSMEM_GEN, derived_elements,
sizeof(RUNTIME_TYPE));
/* copy the elements marked as members of the new type into the new */
/* RT type table */
derived_count = 0;
for(i=0; i<num_rt; i++)
{
if (ismember (membership, i))
{
memcpy (&derived_type_table[derived_count], &rt[i], sizeof(RUNTIME_TYPE));
derived_type_table[derived_count].mvluTypeInfo.ref = rtrefs[i];
derived_count++;
}
}
M_FREE (MSMEM_GEN, membership);
M_FREE (MSMEM_GEN, rtrefs);
/* fix up the offsets. */
for (i=0; i<derived_count; i++)
{
calc_offset_to_last(&derived_type_table[i]);
}
/* fix up the number of RuntimeBlocks contained in arrays and structures */
adjRtBlks(derived_type_table,derived_count);
/* resort the UCA names so GNL will return sorted strings */
reSortRT (derived_type_table, derived_count);
/* we get to finally add a MVL type! */
ret = mvlu_add_rt_type (derived_type_table, derived_count, typeIdOut);
/*mvl_print_type (base_name, *typeIdOut);*/
return (ret);
}
/************************************************************************/
/* mvl_print_type */
/************************************************************************/
#if 0
ST_VOID mvl_print_type( ST_CHAR *base_name, ST_INT typeIdIn)
{
ST_RET ret;
ST_INT i;
RUNTIME_TYPE *rt;
ST_INT num_rt;
ST_CHAR element_name[MAX_IDENT_LEN+1];
ST_CHAR branch_name[MAX_IDENT_LEN+1];
ret = mvl_get_runtime (typeIdIn, &rt, &num_rt);
if (ret != SD_SUCCESS)
{
MVL_LOG_NERR1 ("TypeId %d not found",typeIdIn);
}
for (i=0; i<num_rt; i++)
{
if ((rt[i].el_tag == RT_STR_START) && (ms_comp_name_pres(&rt[i])))
{
add_to_branch_name (branch_name, ms_comp_name_find(&rt[i]));
strcpy( element_name, branch_name);
}
else
{
if (ms_comp_name_pres(&rt[i]))
sprintf( element_name, "%s$%s", branch_name, ms_comp_name_find(&rt[i]));
else
{
if ( i==0 ) /* This is the start of the entire RuntimeType */
{
strcpy( branch_name, base_name);
strcpy( element_name, branch_name);
}
else
element_name[0]=0; /* nobody home */
}
}
if (rt[i].el_tag == RT_STR_END)
{
strcpy( element_name, branch_name);
mvlu_trim_branch_name (branch_name);
}
_slogc (sLogCtrl,"RT %d '%s' - sortedNum %d",
i,element_name,rt[i].mvluTypeInfo.sortedNum);
}
}
#endif
/************************************************************************/
/* mvl_print_derived_type */
/************************************************************************/
ST_VOID mvl_print_derived_type( ST_CHAR *base_name, ST_INT typeIdIn,
ST_UCHAR *membership, ST_UCHAR **labels)
{
ST_RET ret;
ST_INT i;
RUNTIME_TYPE *rt;
ST_INT num_rt;
ST_CHAR element_name[MAX_IDENT_LEN+1];
ST_CHAR branch_name[MAX_IDENT_LEN+1];
ret = mvl_get_runtime (typeIdIn, &rt, &num_rt);
if (ret != SD_SUCCESS)
{
MVL_LOG_NERR1 ("TypeId %d not found",typeIdIn);
}
for (i=0; i<num_rt; i++)
{
if ((rt[i].el_tag == RT_STR_START) && (ms_comp_name_pres(&rt[i])))
{
add_to_branch_name (branch_name, ms_comp_name_find(&rt[i]));
strcpy( element_name, branch_name);
}
else
{
if (ms_comp_name_pres(&rt[i]))
sprintf( element_name, "%s$%s", branch_name, ms_comp_name_find(&rt[i]));
else
{
if ( i==0 ) /* This is the start of the entire RuntimeType */
{
strcpy( branch_name, base_name);
strcpy( element_name, branch_name);
}
else
element_name[0]=0; /* nobody home */
}
}
if (rt[i].el_tag == RT_STR_END)
{
strcpy( element_name, branch_name);
mvlu_trim_branch_name (branch_name);
}
/*if ( ismember( membership, i))
{
printf ( "\n RT %d element name '%s'",i,element_name);
_slogc (sLogCtrl,"RT %d '%s' - sortedNum %d",
i,element_name,rt[i].mvluTypeInfo.sortedNum);
}*/
}
}
/************************************************************************/
/* reSortRT */
/************************************************************************/
static ST_VOID reSortRT (RUNTIME_TYPE *rt, ST_INT numRt)
{
ST_INT highestSortNum;
ST_INT i;
ST_INT prevSortNum;
ST_INT newSortNum;
/* First find the highest 'used' sort number */
highestSortNum = 0;
for (i = 0; i < numRt; ++i)
{
if (rt[i].mvluTypeInfo.sortedNum > highestSortNum)
highestSortNum = rt[i].mvluTypeInfo.sortedNum;
}
newSortNum = 1;
/* compress the sort numbers */
for (prevSortNum = 1; prevSortNum <= highestSortNum; ++prevSortNum)
{
for (i = 0; i < numRt; ++i)
{
if (rt[i].mvluTypeInfo.sortedNum == prevSortNum)
{
rt[i].mvluTypeInfo.sortedNum = newSortNum;
++newSortNum;
break;
}
}
}
}
/************************************************************************/
/* adjRtBlks */
/************************************************************************/
ST_VOID adjRtBlks( RUNTIME_TYPE *derived_type_table, ST_INT derived_count)
{
RUNTIME_TYPE *nested[ASN1_MAX_LEVEL];
ST_INT i;
ST_INT curNestLevel;
RUNTIME_TYPE *start_rt_blk;
RUNTIME_TYPE *rt_ptr;
ST_INT num_rt;
curNestLevel = 0;
rt_ptr = derived_type_table;
for (i=0; i<derived_count; i++,rt_ptr++)
{
if ((rt_ptr->el_tag == RT_STR_START) ||
(rt_ptr->el_tag == RT_ARR_START))
{
nested[curNestLevel] = rt_ptr; /* remember where we started */
curNestLevel++;
}
else if ((rt_ptr->el_tag == RT_STR_END) ||
(rt_ptr->el_tag == RT_ARR_END))
{
curNestLevel--;
start_rt_blk = nested[curNestLevel];
num_rt = (rt_ptr - start_rt_blk - 1); /* figure out how many in between */
/*if (start_rt_blk->u.str.num_rt_blks != num_rt)
{
printf ("\n adjusting %s, was %d, is now %d",
ms_comp_name_find(start_rt_blk),
start_rt_blk->u.str.num_rt_blks,
num_rt);
}*/
start_rt_blk->u.str.num_rt_blks = num_rt;
rt_ptr->u.str.num_rt_blks = num_rt;
}
}
}
/************************************************************************/
/* add_to_branch_name */
/************************************************************************/
static ST_VOID add_to_branch_name (ST_CHAR *branch_name, SD_CONST ST_CHAR *SD_CONST sub_branch_name)
{
sprintf( branch_name, "%s$%s", branch_name, sub_branch_name);
}
/************************************************************************/
/* create_bitstring */
/************************************************************************/
static ST_UCHAR *create_bitstring (ST_INT n)
{
ST_INT i,j;
ST_UCHAR *s;
i = n / ( sizeof( ST_UCHAR ) * 8 );
j = n % ( sizeof( ST_UCHAR ) * 8 );
if (j)
i++; /* allocate an extra byte if string len ! a multiple of 8 */
s = (ST_UCHAR *)M_CALLOC (MSMEM_GEN, i, sizeof( ST_UCHAR));
return(s);
}
/************************************************************************/
/* set_bit */
/************************************************************************/
static ST_VOID set_bit (ST_UCHAR *s, ST_INT n)
{
ST_INT i,j;
ST_UCHAR k = 0x01; /* mask */
i = n / ( sizeof( ST_UCHAR ) * 8 );
j = n % ( sizeof( ST_UCHAR ) * 8 );
s[ i ] = s[ i ] | ( k << j );
}
/************************************************************************/
/* ismember */
/* This function returns 1 if element n belongs to Set s, 0 otherwise. */
/************************************************************************/
static ST_BOOLEAN ismember( ST_UCHAR *bptr,
ST_INT n)
{
ST_INT i,j;
ST_UCHAR k = 0x01; /* mask */
i = n / ( sizeof( ST_UCHAR ) * 8 );
j = n % ( sizeof( ST_UCHAR ) * 8 );
return( bptr[ i ] & ( k << j ));
}
/************************************************************************/
/* cardinality */
/************************************************************************/
static ST_INT cardinality (ST_UCHAR *bptr, ST_INT size)
{
ST_INT i, j, s, r, card;
ST_CHAR temp;
s = size / ( sizeof( ST_UCHAR ) * 8 );
r = size % ( sizeof( ST_UCHAR ) * 8 );
if (r)
s++;
card=0;
for ( i = 0; i < s; i++ )
{
for ( j = 0; j < 8 * sizeof( ST_UCHAR ); j++ )
{
temp = 0x01;
temp = temp << j;
if ( temp & bptr[ i ] )
card++;
}
}
return( card );
}
/************************************************************************/
/* calc_offset_to_last */
/************************************************************************/
/* This function would not be needed except that the UCA structure */
/* handling needs to know the size of each subelement too ... */
static ST_VOID calc_offset_to_last (RUNTIME_TYPE *rt)
{
ST_INT numUcaRt;
if (rt->el_tag == RT_ARR_END || rt->el_tag == RT_STR_END)
{
return;
}
if (rt->el_tag == RT_STR_START)
numUcaRt = rt->u.str.num_rt_blks+2;
else if (rt->el_tag == RT_ARR_START)
numUcaRt = rt->u.arr.num_rt_blks+2;
else
numUcaRt = 1;
/* Now we can find the size of this element and it's associates */
rt->offset_to_last = ms_get_blocked_length (rt, numUcaRt);
}