ONC+ Developer's Guide

Discriminated Union Example

Suppose the type of a union may be integer, character pointer (a string), or a gnumbers structure. Also, assume the union and its current type are declared in a structure. The declaration is:

enum utype {INTEGER=1, STRING=2, GNUMBERS=3};
struct u_tag {
   enum utype utype;	/* the union's discriminant */
   union {
      int ival;
      char *pval;
      struct gnumbers gn;
   } uval;
};
  

Example A-12 constructs and XDR procedure (de)serialize the discriminated union.


Example A-12 XDR Discriminated Union

struct xdr_discrim u_tag_arms[4] = {
 	{INTEGER, xdr_int},
 	{GNUMBERS, xdr_gnumbers}
 	{STRING, xdr_wrapstring},
 	{__dontcare__, NULL}
 	/* always terminate arms with a NULL xdr_proc */
 }

bool_t
xdr_u_tag(xdrs, utp)
 	XDR *xdrs;
 	struct u_tag *utp;
{
 	return(xdr_union(xdrs, &utp->utype, &utp->uval,
	       u_tag_arms, NULL));
}

The routine xdr_gnumbers() was presented above in the XDR Library section. xdr_wrapstring() was presented in example C. The default arm parameter to xdr_union() (the last parameter) is NULL in this example. Therefore the value of the union's discriminant may legally take on only values listed in the u_tag_arms array. This example also demonstrates that the elements of the arm's array do not need to be sorted.

It is worth pointing out that the values of the discriminant may be sparse, though in this example they are not. It is always good practice to assign explicitly integer values to each element of the discriminant's type. This practice both documents the external representation of the discriminant and guarantees that different C compilers emit identical discriminant values.