| RE: .0,
>Can anyone tell me what the MCC_K_DICT_MEMBER dictionary class is used for ? or
>point me to documentation where I can read about it ?
Which document is this in? Which ECO number is this?
>Basically, I want to get the datatype of constructed attrs/args from the
>dictionary but want to find out if there is a quicker (and cleaner) way than to
>get the MCC_K_DD_CONSTRUCTOR_DATA_TYPE definition and then ILV decode it (it
>can potentially be nested).
Have you got an example of how this can be read from the dictionary?
Which dict routine is needed to retrieve this information?
>Has MCC_K_DICT_MEMBER got anything to do with constructed datatypes ?
Where is this described?
RE: .1,
> Anyways, here's an example of its usage. If you have a RECORD datatype
> where your Record is defined to be:
>
> TYPE newrecord = 1 RECORD
> first = 1 : Integer8
> second = 2 : Latin1String
> END;
>
> You can create a dictionary spec where the MEMBER class appears below
> the attr/arg, and then append on Definitions to fetch datatypes or
> presentation names for each element in the Record. In this case, the
> two valid MEMBER instances are of codes 1 and 2 because that is the
> field codes defined in the MSL.
>
> Since Records are the only constructor types that allow field codes
> to be defined by the developer, the other constructor types have
> pre-defined Member instance codes:
>
> SETOF and SEQUENCEOF --> always use 1
> SET and SEQUENCE --> start with 1, and increment by 1 for each
> element
But how can I read this info from the dictionary? I would like to be
able to read all the info about a constructed data type from the dictionary.
What routine would I use to do this?
>That sounds good. I assume that for nested constructions, I need more than one
>MEMBER CI pair with each corresponding to the construction level.
>
>For example to get at the datatype of a record field of an attribute whose
>datatype is a set of a record, I need two MEMBER levels with the first having
>an instance of 1 and the second CI pair having an instance equal to the field
>code. Is that right ?
So if object class x had the previous data type, then I would have to
construct CI pairs for class x, instance x, class 1 (newrecord), instance 1
(newrecord), class 1 (member), instance 1 (first field)?
I'm sorry but I don't understand hwo this would work.
Carl
|
| {
.
.
.
.
/*
** SECTION OF PROGRAM THAT CALLS DICTIONARY ACCESS ROUTINES.
** NOTE this section is not complete but it gives an idea on how to call the
** routines listed below.
*/
/* get ILV mode based on directive */
mode = get_ilv_mode( p_callargs ) ;
if ( mode == MCC_K_ILV_LIST_VALUE )
{
argument_or_attribute = MCC_K_DICT_ATTRIBUTE ;
}
else
{
argument_or_attribute = MCC_K_DICT_ARGUMENT ;
}
/*
** Build dictionary access entity specifications to get definitions from the MCC dictionary.
*/
status = mcc_dict_build_spec ( p_callargs->p_in_entity , &p_dict_entity , MCC_K_NULL_PTR, MCC_K_NULL_PTR ) ;
if ( status == MCC_S_NORMAL )
{
/*
** Append The required CI pairs to get the attribute or the argument definitions from the dictionary.
*/
status = build_arg_or_attr_dict_spec
(
p_dict_entity,
p_callargs->p_verb,
0, /* idcode is not needed yet */
argument_or_attribute /* build dictionary specs. for an attribute or for an argument */
) ;
}
do {
status = mcc_ilv_get_id ( &ilv_ctx, &(p_mcc_desc->mcc_l_id) ) ;
if ( status != MCC_S_NORMAL )
{
break ;
}
/*
** Update the attribute or argument MSL IDCode at the lowest CI level in the Entity dictionary Specs.
*/
status = update_mslcode_in_dict_spec( p_dict_entity, argument_or_attribute, p_mcc_desc->mcc_l_id ) ;
if ( status != MCC_S_NORMAL )
{
break ;
}
if ( mode == MCC_K_ILV_LIST_VALUE )
{
/* Get datatype from attrib_list directly. */
status = mcc_ilv_list_get_datatype ( &ilv_ctx, &(p_mcc_desc->mcc_l_dt) ) ;
}
else
{
/* Get the datatype of this argument from the MCC dictionary. */
status = get_dict_datatype
(
p_dict_entity,
p_mcc_desc,
&(p_mcc_desc->mcc_l_dt)
) ;
}
if ( status != MCC_S_NORMAL )
{
break ;
}
switch ( p_mcc_desc->mcc_l_dt )
{
case MCC_K_DT_SET_OF : /* NOTE: example on how to get the SETOF datatype */
/* member_id is 1 for SETOF/SEQUENCEOF, MSL field code for RECORD */
status = append_member_to_dict_spec( p_dict_member_entity, 1 ) ;
if ( status != MCC_S_NORMAL) break ;
status = get_dict_datatype
(
p_dict_member_entity,
p_value_desc,
&element_datatype /* All elements in a SETOF datatype have the same datatype. */
) ;
/* NOTE LOOP HERE (perhaps recursively) TO GET EACH ELEMENT */
break ;
default:
/* All other datatypes: get attr/arg value directly. */
if ( mode == MCC_K_ILV_LIST_VALUE )
status = mcc_ilv_get ( &ilv_ctx, p_mcc_desc, &reason_code ) ;
else
status = mcc_ilv_get ( &ilv_ctx, p_mcc_desc, MCC_K_NULL_PTR ) ;
break ;
}
} while ( status == MCC_S_NORMAL ) ;
/*
** if End-Of-Construction, reset status to MCC_S_NORMAL
*/
status = ( status == MCC_S_ILVEOC) ? MCC_S_NORMAL : status ;
.
.
.
.
}
/*
* Function Name:
*
* get_ilv_mode
*
* Routine Description:
*
* This routine returns the mode that the ILV encoding of in_p parameters is in.
*
* Arguments:
*
* p_callargs Pointer to the structure containing the required
* arguments of the MCC_CALL interface.
*
* Return Value:
* mode The mode that the ILV lists in in_p must is in.
*
* Error Handling:
*
* Side Effects:
*
* Comments:
*
*/
static unsigned long int get_ilv_mode
(
dt_callargs *p_callargs
)
{
unsigned long int mode ;
switch ( *(p_callargs->p_verb) )
{
case MCC_K_VERB_SHOW:
mode = MCC_K_ILV_LIST_VALUE ;
break ;
case MCC_K_VERB_SET:
case MCC_K_VERB_ADD:
case MCC_K_VERB_REMOVE:
mode = MCC_K_ILV_LIST_VALUE ;
break ;
default:
mode = MCC_K_ILV_NATIVE_VALUE ;
break ;
} /*-switch-*/
return (mode) ;
}
/*
* Function Name:
*
* build_arg_or_attr_dict_spec
*
* Routine Description:
*
* This routine appends either a request argument or an attribute CI pair(s) to an
* MCC dictionary specifications.
* It assumes that the dict specs was already converted from the AES
* entity by the caller.
*
* Arguments:
*
* p_dict_entity Abstract Entity Specs used to access the MCC dictionary.
* p_verb ptr to the verb.
* idcode MSL idcode of the request argument or the attribute.
* argument_or_attribute flag that indicates what the dictionary spec will access: An argument or an attribute.
* The only two legal values are: MCC_K_DICT_ARGUMENT and MCC_K_DICT_ATTRIBUTE.
* Return Value:
*
* MCC_S_NORMAL
* error status returned by mcc_aes_create.
*
* Error Handling:
*
* Side Effects:
*
* p_dict_entity is modified with the appended CI pairs.
*
* Comments:
*
*/
static unsigned long int build_arg_or_attr_dict_spec
(
MCC_A_AES p_dict_entity,
unsigned long int * p_verb,
unsigned long int idcode,
unsigned long int argument_or_attribute
)
{
unsigned long int status = MCC_S_NORMAL,
step = 1 ;
unsigned long int stat;
unsigned long int class, instance, datatype ;
unsigned long int not_wild = MCC_K_AES_NOT_WILD ;
MCC_T_Descriptor inst_desc , *p_inst_desc ;
/* start of routine */
p_inst_desc = &inst_desc ;
datatype = MCC_K_DT_UNSIGNED32 ; /* all instances used below are of this datatype */
status = decq_am_util_init_desc_s( p_inst_desc, 0, 0 , &datatype ) ;
if ( status != MCC_S_NORMAL )
return( status ) ;
p_inst_desc->mcc_w_curlen = sizeof(instance) ;
p_inst_desc->mcc_b_dtype = DSC_K_DTYPE_LU ;
p_inst_desc->mcc_a_pointer = (unsigned char *) &instance ;
switch(argument_or_attribute)
{
case MCC_K_DICT_ARGUMENT :
/*
** Directive request argument: Append the following CI pairs to the dictionary entity Specs.
*/
do {
switch(step++)
{
case 1:
class = MCC_K_DICT_DIRECTIVE ;
instance = *p_verb ;
break ;
case 2:
class = MCC_K_DICT_REQUEST ;
instance = *p_verb ;
break ;
case 3:
class = MCC_K_DICT_ARGUMENT ;
instance = idcode ;
break ;
} /*-switch-*/
/*
** Append CI pair to the end of the p_dict_entity structure.
*/
status = mcc_aes_create( &p_dict_entity, &class, p_inst_desc, ¬_wild ) ;
} while ( (status == MCC_S_NORMAL) && (step <= 3) ) ;
break ;
case MCC_K_DICT_ATTRIBUTE :
/*
** Append CI pair to the end of the p_dict_entity structure.
*/
class = MCC_K_DICT_ATTRIBUTE ;
instance = idcode ;
status = mcc_aes_create( &p_dict_entity, &class, p_inst_desc, ¬_wild ) ;
break ;
default:
status = MCC_S_INVARG;
break ;
} /*---switch(argument_or_attribute)---*/
if ( status == MCC_S_NORMAL )
if (DECQ_AM_GM_LOGICAL & DECQ_AM_M_LOG_ENTRY_PT_PRINTFS)
stat = mcc_aes_dump ( p_dict_entity ) ; /* dump the dict entity Specs. if we are in the debugger */
return (status) ;
}
/*
* Function Name:
*
* append_member_to_dict_spec
*
* Routine Description:
*
* This routine appends a CI pair of member class and member_id instance
* to a dict entity specs. Before calling this routine, the caller must have
* appended the required CI pairs of either the request argument or the attribute.
*
* This routine is called in order to get the datatype of constructed datatype. For
* example if the datatype of an argument is found to be SETOF (by a call to get_dict_datatype,
* perhaps), then to find out what the datatype of the elements are (SETOF of what ?), we append
* a CI pair to the dict entity specs with class of MCC_K_DICT_MEMBER and instance of 1 and
* subsequently a call to mcc_dict_get_def will fetch the element's datatype.
*
* Note: For nested construction, append as many CI (class= MCC_K_DICT_MEMBER, instance= member_id)
* pairs as there are nested levels.
*
* Arguments:
*
* p_dict_entity Abstract Entity Specs used to access the MCC dictionary.
* member_id for a SETOF/SEQUENCEOF datatype, this must be a 1. For a RECORD datatype,
* this is the field number (MSL code).
*
* Return Value:
*
* MCC_S_NORMAL
* error status returned by mcc_aes_*** routines.
*
* Error Handling:
*
* Side Effects:
*
* p_dict_entity is modified with the appended CI pairs.
*
* Comments:
*
*/
static unsigned long int append_member_to_dict_spec
(
MCC_A_AES p_dict_entity,
unsigned long int member_id
)
{
unsigned long int status = MCC_S_NORMAL,
step = 1 ;
unsigned long int datatype, class, instance ;
unsigned long int wild_type = MCC_K_AES_NOT_WILD ;
MCC_T_Descriptor temp_desc;
/* start of routine */
do {
switch(step++)
{
case 1:
/* Initialize a temporary (local) descriptor. Note that no memory is allocated. */
datatype = MCC_K_DT_UNSIGNED32 ;
status = decq_am_util_init_desc_s( &temp_desc, 0, 0 , &datatype ) ;
break ;
case 2:
temp_desc.mcc_w_maxstrlen = temp_desc.mcc_w_curlen = sizeof(instance) ;
temp_desc.mcc_b_dtype = DSC_K_DTYPE_LU ;
temp_desc.mcc_a_pointer = (unsigned char *) &instance ;
/* Append the MEMBER CI pair */
class = MCC_K_DICT_MEMBER;
instance = member_id ;
status = mcc_aes_create( &p_dict_entity, &class, &temp_desc, &wild_type );
break ;
} /*-switch-*/
} while ( (status == MCC_S_NORMAL) && (step <= 2) ) ;
return (status) ;
}
/*
* Function Name:
*
* update_mslcode_in_dict_spec
*
* Routine Description:
*
* This routine updates the instance of the lowest level CI in the p_dict_entity entity specs.
* It is used to update the attribute or argument MSL idcode in the dict specifications
* or to update the member id of the MCC_K_DICT_MEMBER class.
*
* Arguments:
*
* p_dict_entity Abstract Entity Specs used to access the MCC dictionary.
* dict_class The dictionary class to update. Valid values are MCC_K_DICT_ARGUMENT,
* MCC_K_DICT_ATTRIBUTE, MCC_K_DICT_MEMBER.
* msl_code MSL idcode of either the request argument or attribute or the idcode of the constructor:
* 1 for the SETOF/SEQUENCEOF datatypes, field # of the RECORD datatype.
*
* Return Value:
*
* MCC_S_NORMAL
* error status returned by mcc_aes_*** routines.
*
* Error Handling:
*
* Side Effects:
*
* Comments:
*
*/
static unsigned long int update_mslcode_in_dict_spec
(
MCC_A_AES p_dict_entity,
unsigned long int dict_class,
unsigned long int msl_code
)
{
unsigned long int status = MCC_S_NORMAL,
step = 1 ;
unsigned long int datatype ;
unsigned long int level, depth ;
unsigned long int wild_type = MCC_K_AES_NOT_WILD ;
MCC_T_Descriptor temp_desc;
/* start of routine */
do {
switch(step++)
{
case 1:
/* Initialize a temporary (local) descriptor. Note that no memory is allocated. */
datatype = MCC_K_DT_UNSIGNED32 ;
status = decq_am_util_init_desc_s( &temp_desc, 0, 0 , &datatype ) ;
break ;
case 2:
/* get depth to determine the lowest level (depth-1) */
status = mcc_aes_depth( &p_dict_entity, &depth );
break ;
case 3:
temp_desc.mcc_w_maxstrlen = temp_desc.mcc_w_curlen = sizeof(msl_code) ;
temp_desc.mcc_b_dtype = DSC_K_DTYPE_LU ;
temp_desc.mcc_a_pointer = (unsigned char *) &msl_code ;
level = depth - 1 ; /* lowest level */
status = mcc_aes_set( &p_dict_entity, &level, &dict_class, &temp_desc, &wild_type ) ;
break ;
} /*-switch-*/
} while ( (status == MCC_S_NORMAL) && (step <= 3) ) ;
return (status) ;
}
/*
* Function Name:
*
* get_dict_datatype
*
* Routine Description:
*
* This routine calls the get_dict_definition routine to fetch the request argument or attribute
* datatype from the MCC dictionary given a completed dictionary entity sepcifications.
* It returns the datatype in the routine argument p_datatype.
*
* Arguments:
*
* p_dict_entity Abstract Entity Specs used to access the MCC dictionary.
* p_mcc_desc ptr to the MCC scratch MCC descriptor needed to call MCC routines.
* p_datatype ptr to the argument/attribute datatype to be fetched from the dictionary and returned
* by this routine.
*
* Return Value:
*
* MCC_S_NORMAL
* error status returned by get_dict_definition
*
* Error Handling:
*
* Side Effects:
*
* Comments:
*
*/
static unsigned long int get_dict_datatype
(
MCC_A_AES p_dict_entity,
MCC_T_Descriptor * p_mcc_desc,
unsigned long int * p_datatype
)
{
unsigned long int status = MCC_S_NORMAL ;
/* start of routine */
status = get_dict_definition
(
p_dict_entity,
MCC_K_DD_VALUE_DATA_TYPE, /* dict definition instance */
p_mcc_desc
) ;
if ( status == MCC_S_NORMAL )
{
*p_datatype = *( (unsigned long int *)p_mcc_desc->mcc_a_pointer ) ;
}
return (status) ;
}
/*
* Function Name:
*
* get_dict_definition
*
* Routine Description:
*
* This routine fetches the definition from the MCC dictionary given a dictionary entity sepcifications.
*
* Arguments:
*
* p_dict_entity Abstract Entity Specs used to access the MCC dictionary.
* dict_def The instance corresponding to the dictionary definition to retrieve from the MCC dictionary.
* p_mcc_desc ptr to the MCC descriptor to return the retrieved definition in. Pre-allocated by caller.
*
* Return Value:
*
* MCC_S_NORMAL
* error status returned by mcc_aes_depth,
* mcc_aes_create,
* mcc_aes_prune,
* decq_am_util_init_desc_s,
* mcc_dict_get_def_info.
*
* Error Handling:
*
* Side Effects:
*
* Comments:
*
*/
static unsigned long int get_dict_definition
(
MCC_A_AES p_dict_entity,
unsigned long int dict_def_instance,
MCC_T_Descriptor * p_mcc_desc
)
{
unsigned long int status = MCC_S_NORMAL,
step = 1 ;
struct MCC_R_DICT_DEF dict_desc ;
unsigned long int level, class, datatype ;
unsigned long int depth ;
unsigned long int wild_type = MCC_K_AES_NOT_WILD ;
MCC_T_Descriptor temp_desc ;
/* start of routine */
do
{
switch(step++)
{
case 1:
/*
** Get the depth of the entity so that we can prune
** back (as to not alter original dict specs.) when done
*/
status = mcc_aes_depth ( &p_dict_entity, &depth ) ;
break ;
case 2:
/* Initialize a temporary (local) descriptor. Note that no memory is allocated. */
datatype = MCC_K_DT_UNSIGNED32 ;
status = decq_am_util_init_desc_s( &temp_desc, 0, 0 , &datatype ) ;
break ;
case 3:
temp_desc.mcc_w_maxstrlen = temp_desc.mcc_w_curlen = sizeof(dict_def_instance) ;
temp_desc.mcc_b_dtype = DSC_K_DTYPE_LU ;
temp_desc.mcc_a_pointer = (unsigned char *) &dict_def_instance ;
/* Append the DEFINITION CI pair */
class = MCC_K_DICT_DEFINITION ;
status = mcc_aes_create( &p_dict_entity, &class, &temp_desc, &wild_type );
break ;
case 4:
/*
** Initialize the dictionary data structure and its MCC descriptor (no memory allocation).
*/
dict_desc.def_w_count = 0 ;
dict_desc.def_b_defined = dict_desc.def_b_usage = 0 ;
datatype = MCC_K_DT_UNSIGNED32 ;
status = decq_am_util_init_desc_s(&(dict_desc.def_r_value_desc), 0, MCC_K_NULL_PTR, &datatype) ;
break ;
case 5:
/*
** Get the definition specified at the lowest level CI pair from the dictionary. It will copied to
** p_mcc_desc->mcc_a_pointer buffer, which is already allocated by the caller.
*/
dict_desc.def_r_value_desc.mcc_a_pointer = p_mcc_desc->mcc_a_pointer ;
dict_desc.def_r_value_desc.mcc_w_maxstrlen = p_mcc_desc->mcc_w_maxstrlen ;
status = mcc_dict_get_def_info( p_dict_entity, &dict_desc ) ;
break ;
case 6:
/* prune the definition CI pair */
status = mcc_aes_prune( &p_dict_entity, &depth ) ;
break ;
} /*-switch-*/
}
while ( (status == MCC_S_NORMAL) && (step <= 6) ) ;
if ( status == MCC_S_NORMAL )
{
p_mcc_desc->mcc_w_curlen = dict_desc.def_r_value_desc.mcc_w_curlen ; /* update buffer's length */
}
return (status) ;
}
|