next up previous contents index
Next: Problems Up: More Examples Previous: TimeStep "xdr"

Triang2d "xdr"

This is a rather long example, but it shouldn't be too difficult to understand. It shows how arrays and memory management can be handled:

TRIANG2D *triang2d_xdr(XDR *xdrp)
{
  TRIANG2D *self;
  int number_of_points;
  int max_number_of_points;
  int number_of_elements;
  int max_number_of_elements;
  int ver = 1;

  self = (TRIANG2D *)START_METHOD(G_INSTANCE);
  ASSURE(self, "", END_METHOD(NULL));

  /* for reading -> */
  number_of_points = self->number_of_points;
  max_number_of_points = self->max_number_of_points;
  number_of_elements = self->number_of_elements;
  max_number_of_elements = self->max_number_of_elements;
  /* <- for reading */

  if(!g_xdr_version(xdrp, &ver) ||
     !  xdr_int(xdrp, &number_of_points) ||
     !  xdr_int(xdrp, &max_number_of_points) ||
     !  xdr_int(xdrp, &number_of_elements) ||
     !  xdr_int(xdrp, &max_number_of_elements))
    END_METHOD(NULL);

  /* for reading -> */
  if(max_number_of_points != self->max_number_of_points ||
     max_number_of_elements != self->max_number_of_elements) {
    GRAPE(self, "list-free")();
    self->max_number_of_points = max_number_of_points;
    self->max_number_of_elements = max_number_of_elements;
  }
  self->number_of_points = number_of_points;
  self->number_of_elements = number_of_elements;
  /* <- for reading */

  if(!g_xdr_array(xdrp, (void **)&self->x, self->number_of_points,
                  self->max_number_of_points, "double") ||
     !g_xdr_array(xdrp, (void **)&self->y, self->number_of_points,
                  self->max_number_of_points, "double") ||
     !g_xdr_array(xdrp, (void **)&self->z, self->number_of_points,
                  self->max_number_of_points, "double") ||
     !g_xdr_array(xdrp, (void **)&self->vertex, self->number_of_elements,
                  self->max_number_of_elements, "INT3") ||
     !g_xdr_array(xdrp, (void **)&self->neighbour, self->number_of_elements,
                  self->max_number_of_elements, "INT3"))
    END_METHOD(NULL);

  END_METHOD(self);
}
The Triang1d and Triang3d "xdr" methods are very similar to this one, for Triang3d INT3 has to be replaced by INT4 and for Triang1d all lines referring to element information have to be removed.

The two parts marked with the ``for reading'' comments are not needed for writing, in this case the number_of_ variables are just copied to local variables and back again, the if part with the "list-free" is not executed. The arrays might be NULL (if max_number_of_points/elements is zero), they might also be used somewhere else, e.g. in some other Triang2d instance, this is all handled by g_xdr_array.

If the method is called for reading, first the (maximum) number of points and elements are read into local variables. Reading them directly into the corresponding Triang2d variables would cause lots of trouble because the max_number_of_ variables probably wouldn't be consistent with the array lengths. If the existing arrays don't have the correct size we delete them by calling "list-free", then the local variables can be copied to the Triang2d variables. We could call "list-alloc" to allocate new arrays, but we don't have to since g_xdr_array will allocate new memory if necessary.

With some minor changes the method would work even without calling "list-free" at all, in this case the array lengths would be corrected by g_xdr_array if necessary. But this could also lead to inconsistencies if the method was called on a subclass instance: arrays in the subclass which contain point or element data would still have the old lengths but these old lengths are lost when the method returns. Calling "list-free" also deletes subclass arrays, new arrays with the correct lengths are then allocated by the g_xdr_array calls in the subclass "xdr" method.


next up previous contents index
Next: Problems Up: More Examples Previous: TimeStep "xdr"

SFB 256 Universität Bonn and IAM Universität Freiburg

Copyright © by the Sonderforschungsbereich 256 at the Institut für Angewandte Mathematik, Universität Bonn.