|  | 	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) ;
}
 |