Listing 10

/* CIRCLE PACKAGE - contains CIRCLE typedef,
     private data and action package
     definitions */
#include <stdlib.h>


/* CIRCLE type has only two elements */
typedef struct circle
   {
   /* void * pointer to private data */
   void *pprivate;

   /* pcact is used as a pointer to an
        array of action functions */
   int (**pcact)();
   } CIRCLE;


/* private data struct is static */
static struct circle_pri_data
   {
   int color;
   };

/* get and setcolor member functions */
static int cir_get_color(CIRCLE *pc)
   {
   return
      ((struct circle_pri_data *)
        (pc->pprivate))->color;
   }

static int cir_set_color(CIRCLE *pc, int col)
   {
   ((struct circle_pri_data *)
        (pc->pprivate))->color = col;
   }


/* now define and initialize action package */
static (*cact[])() =
   { circle_getcolor, circle_setcolor };


/* the constructor is public, callable from
     another file the constructor creates
     space for the private data, and inits
     the new circle's action pointer to the
     action package */
constructor(CIRCLE *pc, int color)
   {
   /* first make space for the private data */
   if (!(pc->pprivate =
     malloc(sizeof(struct circle_pri_data))))
        exit(-1);

   /* cast pprivate to point to private data
      to set color */
   ((struct circle_pri_data *)
     (pc->pprivate))->color = color;

   /* finally, hook up the new circle to the
     action package */
   pc->pact = cact;
   }

/* the public destructor frees the allocated
     private storage */
destructor(CIRCLE *pc) {
   free(pc->pprivate);
   }

/* End of File */