ONC+ Developer's Guide

Discriminated Union Example

Suppose the type of a union is 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;
};  

The following code example constructs an XDR procedure to deserialize 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 previously in XDR Library. The default arm parameter to xdr_union(), the last parameter, is NULL in this example. Therefore, the value of the union's discriminant can legally take on only values listed in the u_tag_arms array. Example A–12 also demonstrates that the elements of the arm's array do not need to be sorted.

The values of the discriminant can be sparse, though in Example A–12 they are not. Make a practice of assigning 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.