ISO/TS 10303-26:2011(E)

Annex C
(informative)

Examples

C.1 General

This annex contains some examples of how to apply the mapping rules specified in this part of ISO 10303. The examples were produced using the HDF5 API developed by the HDF5 Group.

The examples make use of the functions and types declared in the following code excerpt.

#ifndef EXAMPLES
#define EXAMPLES
 
#include "hdf5.h"
 
#define NUMBER_OF_ENTITIES 4
#define NO_OF_PPOINTS      4
#define NO_OF_MANY_POINTS 25
 
hid_t file_id;
hid_t instance_reference_tid;
long  instance_reference_tid_size;
char *defined_entity_names[NUMBER_OF_ENTITIES];
char *entity_names[NUMBER_OF_ENTITIES];
 
herr_t define_instance_reference(hid_t group_id);
herr_t define_compound_point(hid_t group_id, hid_t  *pp_tid);
herr_t define_compound_line(hid_t group_id, hid_t col_tid, hid_t *ll_tid);
herr_t define_colour_enumeration(hid_t group_id, hid_t *eenum_col_tid);
herr_t define_compound_colour(hid_t group_id, hid_t eenum_col_tid, hid_t  *cc_tid);
herr_t define_aggr_reference(hid_t group_id, hid_t aggr_tid, char *aggr_id, hid_t *aggr_ref_tid);
herr_t create_schema_group(hid_t file_id, char *group_name, char *schema_name, hid_t *ggroup_id);
herr_t create_pop_group(hid_t file_id, char *group_name, char *schema_name, hid_t *ggroup_id);
herr_t create_ppoints(hid_t group_id, hid_t p_tid);
herr_t create_llines(hid_t group_id, hid_t l_tid);
hid_t define_nested_real_aggr(void);
herr_t create_nested_real_aggr(hid_t group_id,  hid_t  vlen_of_vlen_double_tid, char **buffer);
hid_t define_nested_point_aggr(hid_t p_tid);
herr_t create_nested_point_aggr(hid_t group_id,  hid_t  vlen_of_vlen_p_tid);
hid_t define_nested_ref_aggr(void);
herr_t create_many_points(hid_t group_id, hid_t p_tid);
herr_t define_compound_land_survey(hid_t group_id, hid_t *lls_tid);
herr_t create_survey(hid_t pop_id, hid_t ls_tid,hid_t p_tid);
herr_t create_nested_real_array(hid_t group_id);
long get_dataset_index(char *entity_name);
 
   enum colors_t {vvoid,red, green, blue, white, black};
 
   typedef struct inst_ref_t {
     long dataset_index;
     long instance_index;
   } inst_ref_t;
 
   typedef struct point_t {
     long   set_unset_bitmap;
     long   id;
     double x;
     double y;
   } point_t;
 
   typedef struct colour_t {
     long          set_unset_bitmap;
     char          *s_colour;
     enum colors_t e_colour;
   } colour_t;
 
   typedef struct lline_t {
     long              set_unset_bitmap;
     long              id;
     struct inst_ref_t startp;
     struct inst_ref_t endp;
     colour_t          colour;
   } lline_t;
 
#endif /* EXAMPLES */

C.2 Mappings for EXPRESS schema declarations

The following EXPRESS schema is used as context schema for all examples provided in Annex C:

SCHEMA geometry;
  TYPE Colour = ENUMERATION OF
    (
      VVOID,
      RED,
      GREEN,
      BLUE,
      WHITE,
      BLACK
    );
  END_TYPE;
   
  TYPE SSTRING = STRING;
  END_TYPE;
 
  TYPE CColour = SELECT(Colour,SSTRING);
  END_TYPE;
    
  ENTITY Line;
    colour : CColour;
    startp : POINT;
    endp   : POINT;
  END_ENTITY;
  
  ENTITY Point;
    x : REAL;
    y : REAL;
  END_ENTITY;
  
  ENTITY Land_survey;
    country    : STRING;
    properties : LIST OF LIST OF POLYGON;
    altitudes  : LIST OF LIST OF LIST OF ALTITUDE;
  END_ENTITY;
 
END_SCHEMA;

The following function exemplifies how to map an EXPRESS schema to an HDF5 Group. The input parameters are: HDF5 file identifier; name of the HDF5 Group that will be created; the name of EXPRESS schema. The last parameter, "ggroup_id", is an output parameter that will hold the identifier of the new HDF5 Group that will be created. The rules applied to perform the mapping are described in 6.5.

#include <string.h>
#include "hdf5.h"
#include "examples.h"
 
 
herr_t create_schema_group(hid_t file_id, char *group_name, char *schema_name, hid_t *ggroup_id)
{
  herr_t rstat;
  hid_t  group_id;
  hid_t  attr_id;
  hid_t  string_tid;
  hid_t  scalar_tid;
 
  rstat = -1;
 
  *ggroup_id = -1;
  group_id = H5Gcreate(file_id, group_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  if(group_id > 0) {
    *ggroup_id = group_id;
    string_tid   = H5Tcopy(H5T_C_S1);
    H5Tset_size(string_tid, strlen(schema_name)+1);
    scalar_tid   = H5Screate(H5S_SCALAR);
    attr_id = H5Acreate (group_id, "iso_10303_26_schema", string_tid, scalar_tid, H5P_DEFAULT, H5P_DEFAULT);
    rstat = H5Awrite(attr_id,string_tid,schema_name);
  }
 
  return(rstat);
}

The following text fragment represents a dump of an HDF5 file resultant from the execution of the function shown above. The resultant text file is created by the HDF5 dump utility (H5dump) and it is structured according to the HDF5 Data Definition Language (DDL) syntax.

HDF5 "example.h5" {
GROUP "/" {
   GROUP "Geometry_encoding" {
      ATTRIBUTE "iso_10303_26_schema" {
         DATATYPE  H5T_STRING {
               STRSIZE 16;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            }
         DATASPACE  SCALAR
         DATA {
         (0): "Geometry_schema"
         }
      }
    }
}
}

C.3 EXPRESS-driven data populations as HDF5

The following function shows how to create an HDF5 Group to hold an EXPRESS-driven data population of a given schema. The rules applied to perform the mapping are described in 6.3.3.

Please observe that the global "defined_entity_names" variable is initalized in the main program (see Annex C.10)

#include <string.h>
#include "hdf5.h"
#include "examples.h"
 
herr_t create_pop_group(hid_t file_id, char *group_name, char *schema_name, hid_t *ggroup_id)
{
  herr_t  rstat;
  hid_t   group_id;
  hid_t   attr_id;
  hid_t   string_tid;
  hid_t   scalar_tid;
  hid_t   string_array_tid;
  hsize_t array_dim[1];
 
  rstat = -1;
 
  *ggroup_id = -1;
  group_id = H5Gcreate(file_id, group_name, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
  if(group_id > 0) {
    *ggroup_id = group_id;
    string_tid   = H5Tcopy(H5T_C_S1);
    H5Tset_size(string_tid, strlen(schema_name)+1);
    scalar_tid   = H5Screate(H5S_SCALAR);
    attr_id = H5Acreate (group_id, "iso_10303_26_data", string_tid, scalar_tid, H5P_DEFAULT, H5P_DEFAULT);
    rstat = H5Awrite(attr_id,string_tid,schema_name);
 
    array_dim[0] = 4;
    rstat = H5Tset_size(string_tid, H5T_VARIABLE);
    string_array_tid = H5Tarray_create2(string_tid, 1, array_dim);
    attr_id = H5Acreate(group_id, "_10303_26_data_set_names", string_array_tid, scalar_tid, H5P_DEFAULT, H5P_DEFAULT);
    rstat = H5Awrite(attr_id,string_array_tid,defined_entity_names);
  }
 
  return(rstat);
}

The following text fragment represents a dump of an HDF5 file resultant from the execution of the function above.

HDF5 "example.h5" {
GROUP "/" {
   GROUP "Geometry_population" {
      ATTRIBUTE "_10303_26_data_set_names" {
         DATATYPE  H5T_ARRAY { [4] H5T_STRING {
               STRSIZE H5T_VARIABLE;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            } }
         DATASPACE  SCALAR
         DATA {
         (0): [ "Point", "Many_Point", "Line", "Land_survey" ]
         }
      }
      ATTRIBUTE "iso_10303_26_data" {
         DATATYPE  H5T_STRING {
               STRSIZE 16;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            }
         DATASPACE  SCALAR
         DATA {
         (0): "Geometry_schema"
         }
      }
   }
}
}

C.4 Mapping of EXPRESS entity data types

The following function exemplifies how to map an EXPRESS entity type to an HDF5 Compound Type using the HDF5 API. It shows how the EXPRESS entity Point defined in the context schema is mapped to HDF5. The rules applied to perform the mapping are described in 6.6.

//------------------------------------------------------------------
//  Define Point:
//
//  Only simple types are encoded is this case
//------------------------------------------------------------------
herr_t define_compound_point(hid_t group_id, hid_t  *pp_tid)
{
   herr_t rstat;
   hid_t  p_tid;
 
   *pp_tid = -1;
//
// Create named compound type for POINT
//
   p_tid = H5Tcreate (H5T_COMPOUND, sizeof(point_t));
   if(rstat = H5Tinsert(p_tid, "set_unset_bitmap", HOFFSET(point_t, set_unset_bitmap), H5T_NATIVE_LONG)) goto err;
   if(rstat = H5Tinsert(p_tid, "Entity-Instance-Identifier", HOFFSET(point_t, id), H5T_NATIVE_LONG)) goto err;
   if(rstat = H5Tinsert(p_tid, "x", HOFFSET(point_t, x), H5T_NATIVE_DOUBLE)) goto err;
   if(rstat = H5Tinsert(p_tid, "y", HOFFSET(point_t, y), H5T_NATIVE_DOUBLE)) goto err;
   if(rstat = H5Tcommit2(group_id, "Point", p_tid,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT)) goto err;
   *pp_tid = p_tid;
 
err:
   return(rstat);
}

The following code excerpt is used to populate the HDF5 file by creating instances of the HDF5 Compound Type that represents the Point entity as defined by the function "define_compound_point".

#include "hdf5.h"
#include "examples.h"
 
#define NO_OF_PPOINTS 4
 
//------------------------------------------------------------------
//  Create Points:
//
//  Exemplifies how the Point Compound type, defined by means of the define_compound_point function, is used to populate Points on an HDF5 dataset.
//  Geometrically the Points make up corners of a square(0,0),(100,0),(100,100),(0,100)
//------------------------------------------------------------------
herr_t create_ppoints(hid_t group_id, hid_t p_tid)
{
  herr_t   rstat;
  hid_t    point_dataset;
  hid_t    myspace;
  hid_t    obj_group;
  hsize_t  mydim[1];
  point_t  ppoints[NO_OF_PPOINTS];
//
// Populate the points in a memory buffer
//
    ppoints[0].set_unset_bitmap = 7;
    ppoints[0].id = 0;
    ppoints[0].x = 0.;
    ppoints[0].y = 0.;
 
    ppoints[1].set_unset_bitmap = 7;
    ppoints[1].id = 1;
    ppoints[1].x = 100.;
    ppoints[1].y = 0.;
 
    ppoints[2].set_unset_bitmap = 7;
    ppoints[2].id = 2;
    ppoints[2].x = 100.;
    ppoints[2].y = 100.;
 
    ppoints[3].set_unset_bitmap = 7;
    ppoints[3].id = 3;
    ppoints[3].x = 0.;
    ppoints[3].y = 100.;
 
//
//  Create the group that shall contain the dataset
//
   obj_group = H5Gcreate(group_id, "Point_objects", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
//
//  Create the dataset that shall contain the Points
//
   mydim[0] = NO_OF_PPOINTS;
   myspace = H5Screate_simple(1, mydim, NULL);
   point_dataset = H5Dcreate1(obj_group, "Point_instances", p_tid, myspace, H5P_DEFAULT);
   
//
// Write the Points to the dataset
//
   rstat = H5Dwrite(point_dataset, p_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, ppoints);
 
   return(rstat);
}

The following text fragment represents a dump of an HDF5 file resultant from the execution of the two functions shown above. The HDF5 definition of the EXPRESS entity Point, created with the function "define_compound_point" is represented by the Point Compound type. The "Point_instances" dataset contains the instance population created using the function "create_ppoints".

HDF5 "example.h5" { GROUP "/" {    GROUP "Geometry_encoding" {
      ATTRIBUTE "iso_10303_26_schema" {
         DATATYPE  H5T_STRING {
               STRSIZE 16;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            }
         DATASPACE  SCALAR
         DATA {
         (0): "Geometry_schema"
         }
      }
      DATATYPE "Point" H5T_COMPOUND {
         H5T_STD_I32LE "set_unset_bitmap";
         H5T_STD_I32LE "Entity-Instance-Identifier";
         H5T_IEEE_F64LE "x";
         H5T_IEEE_F64LE "y";
      }
   }
   GROUP "Geometry_population" {
      ATTRIBUTE "_10303_26_data_set_names" {
         DATATYPE  H5T_ARRAY { [4] H5T_STRING {
               STRSIZE H5T_VARIABLE;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            } }
         DATASPACE  SCALAR
         DATA {
         (0): [ "Point", "Many_Point", "Line", "Land_survey" ]
         }
      }
      ATTRIBUTE "iso_10303_26_data" {
         DATATYPE  H5T_STRING {
               STRSIZE 16;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            }
         DATASPACE  SCALAR
         DATA {
         (0): "Geometry_schema"
         }
      }
      GROUP "Point_objects" {
         DATASET "Point_instances" {
            DATATYPE  "/Geometry_encoding/Point"
            DATASPACE  SIMPLE { ( 4 ) / ( 4 ) }
            DATA {
            (0): {
                  7,
                  0,
                  0,
                  0
               },
            (1): {
                  7,
                  1,
                  100,
                  0
               },
            (2): {
                  7,
                  2,
                  100,
                  100
               },
            (3): {
                  7,
                  3,
                  0,
                  100
               }
            }
         }
      }
   }
}
}

C.5 Mappings for EXPRESS enumeration data types as HDF5

The following function exemplifies how to map an EXPRESS enumeration type to an HDF5 enumeration type using the HDF5 API. It shows how the EXPRESS enumeration Colour, defined in the context schema, is mapped to HDF5. The rules applied to perform the mapping are described in section 5.8.1.

//------------------------------------------------------------------
//  Define enumeration:
//
//  Exemplifies how enumeration types are encoded
//------------------------------------------------------------------
herr_t define_colour_enumeration(hid_t group_id, hid_t *eenum_col_tid)
{
   herr_t rstat;
   short  enum_val;
   hid_t  enum_col_tid;
 
   *eenum_col_tid = -1;
   enum_col_tid = H5Tcreate (H5T_ENUM, sizeof(short));
   if(rstat = H5Tenum_insert(enum_col_tid, "VVOID",(enum_val=0,&enum_val))) goto err;
   if(rstat = H5Tenum_insert(enum_col_tid, "RED"  ,(enum_val=1,&enum_val))) goto err;
   if(rstat = H5Tenum_insert(enum_col_tid, "GREEN",(enum_val=2,&enum_val))) goto err;
   if(rstat = H5Tenum_insert(enum_col_tid, "BLUE" ,(enum_val=3,&enum_val))) goto err;
   if(rstat = H5Tenum_insert(enum_col_tid, "WHITE",(enum_val=4,&enum_val))) goto err;
   if(rstat = H5Tenum_insert(enum_col_tid, "BLACK",(enum_val=5,&enum_val))) goto err;
   if(rstat = H5Tcommit2(group_id, "Colour", enum_col_tid,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT)) goto err;
   *eenum_col_tid = enum_col_tid;
err:
   return(rstat);
}

The following text fragment represents a dump of an HDF5 file resultant from the execution of the function "define_colour_enumeration". The HDF5 definition of the EXPRESS enumeration Colour is represented by the Colour HDF5 Enumeration Type. In this example it was not created any instance population, hence the corresponding HDF5 construct that represents the population is empty.

HDF5 "example.h5" {
GROUP "/" {
   GROUP "Geometry_encoding" {
      ATTRIBUTE "iso_10303_26_schema" {
         DATATYPE  H5T_STRING {
               STRSIZE 16;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            }
         DATASPACE  SCALAR
         DATA {
         (0): "Geometry_schema"
         }
      }
      DATATYPE "Colour" H5T_ENUM {
            H5T_STD_I16LE;
            "VVOID"            0;
            "RED"              1;
            "GREEN"            2;
            "BLUE"             3;
            "WHITE"            4;
            "BLACK"            5;
         };
 
   }
   GROUP "Geometry_population" {
      ATTRIBUTE "_10303_26_data_set_names" {
         DATATYPE  H5T_ARRAY { [4] H5T_STRING {
               STRSIZE H5T_VARIABLE;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            } }
         DATASPACE  SCALAR
         DATA {
         (0): [ "Point", "Many_Point", "Line", "Land_survey" ]
         }
      }
      ATTRIBUTE "iso_10303_26_data" {
         DATATYPE  H5T_STRING {
               STRSIZE 16;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            }
         DATASPACE  SCALAR
         DATA {
         (0): "Geometry_schema"
         }
      }
   }
}
}
 

C.6 EXPRESS select of mixed types as HDF5

The following function exemplifies how to map an EXPRESS select type to an HDF5 Compound Type using the HDF5 API. It shows how the EXPRESS select type "CColour" defined in the context schema is mapped to HDF5. The rules applied to perform the mapping are described in section 5.8.2.3.

//------------------------------------------------------------------
//  Define Colour:
//
//  Exemplifies how select types are encoded
//------------------------------------------------------------------
herr_t define_compound_colour(hid_t group_id, hid_t eenum_col_tid, hid_t  *cc_tid)
{
   herr_t rstat;
   hid_t  c_tid;
   hid_t  string_tid;
 
   *cc_tid = -1;
   string_tid   = H5Tcopy(H5T_C_S1);
   if(rstat = H5Tset_size(string_tid, H5T_VARIABLE)) goto err;
//
// Create named compound type for COLOUR
//
   c_tid = H5Tcreate (H5T_COMPOUND, sizeof(colour_t));
   if(rstat = H5Tinsert(c_tid, "select_bitmap", HOFFSET(colour_t, select_bitmap), H5T_NATIVE_LONG)) goto err;
   if(rstat = H5Tinsert(c_tid, "s_colour", HOFFSET(colour_t, s_colour), string_tid)) goto err;
   if(rstat = H5Tinsert(c_tid, "e_colour", HOFFSET(colour_t, e_colour), eenum_col_tid)) goto err;
   if(rstat = H5Tcommit2(group_id, "CColour", c_tid,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT)) goto err;
   *cc_tid = c_tid;
 
err:
   return(rstat);
}

The following text fragment represents a dump of an HDF5 file showing how the EXPRESS select type "CColour" is actually encoded in HDF5.

HDF5 "example.h5" {
GROUP "/" {
   GROUP "Geometry_encoding" {
      ATTRIBUTE "iso_10303_26_schema" {
         DATATYPE  H5T_STRING {
               STRSIZE 16;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            }
         DATASPACE  SCALAR
         DATA {
         (0): "Geometry_schema"
         }
      }
      DATATYPE "CColour" H5T_COMPOUND {
         H5T_STD_I32LE "select_bitmap";
         H5T_STRING {
            STRSIZE H5T_VARIABLE;
            STRPAD H5T_STR_NULLTERM;
            CSET H5T_CSET_ASCII;
            CTYPE H5T_C_S1;
         } "s_colour";
         H5T_ENUM {
            H5T_STD_I16LE;
            "VVOID"            0;
            "RED"              1;
            "GREEN"            2;
            "BLUE"             3;
            "WHITE"            4;
            "BLACK"            5;
         } "e_colour";
      }
      DATATYPE "Colour" H5T_ENUM {
            H5T_STD_I16LE;
            "VVOID"            0;
            "RED"              1;
            "GREEN"            2;
            "BLUE"             3;
            "WHITE"            4;
            "BLACK"            5;
         };
 
   }
   GROUP "Geometry_population" {
      ATTRIBUTE "_10303_26_data_set_names" {
         DATATYPE  H5T_ARRAY { [4] H5T_STRING {
               STRSIZE H5T_VARIABLE;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            } }
         DATASPACE  SCALAR
         DATA {
         (0): [ "Point", "Many_Point", "Line", "Land_survey" ]
         }
      }
      ATTRIBUTE "iso_10303_26_data" {
         DATATYPE  H5T_STRING {
               STRSIZE 16;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            }
         DATASPACE  SCALAR
         DATA {
         (0): "Geometry_schema"
         }
      }
   }
}
}

C.7 EXPRESS entity instance references

The following function exemplifies how the EXPRESS entity "Line" defined in the context schema is mapped to the corresponding HDF5 Compound Type using the HDF5 API. In addition, this example shows how instance references and attributes of mixed SELECT types are mapped applying the rules described in section 5.9.3. The EXPRESS entity "Line" referrers to two instances of the entity "Point", namely "startp" and "endp", and contains an attribute of type "CColour", which is the EXPRESS select type defined in the context schema.

//__________________________________________________________________
//  Define Line:
//
//  In addition to simple type encoding, this functions exemplifies how to encode references to entity instances.
//  Moreover it is exemplified how select types , also being defined as Compound types, are embedded.
//__________________________________________________________________
herr_t define_compound_line(hid_t group_id, hid_t col_tid, hid_t *ll_tid)
{
   herr_t rstat;
   hid_t  l_tid;
 
  *ll_tid = _1;
//
// Create named compound type for LINE
//
   l_tid = H5Tcreate (H5T_COMPOUND, sizeof(lline_t));
   if(rstat = H5Tinsert(l_tid, "set_unset_bitmap", HOFFSET(lline_t, set_unset_bitmap), H5T_NATIVE_LONG)) goto err;
   if(rstat = H5Tinsert(l_tid, "Entity_Instance_Identifier", HOFFSET(lline_t, id), H5T_NATIVE_LONG)) goto err;
   if(rstat = H5Tinsert(l_tid, "startp", HOFFSET(lline_t, startp), instance_reference_tid )) goto err;
   if(rstat = H5Tinsert(l_tid, "endp", HOFFSET(lline_t, endp), instance_reference_tid )) goto err;
   if(rstat = H5Tinsert(l_tid, "colour", HOFFSET(lline_t, colour), col_tid )) goto err;
   if(rstat = H5Tcommit2(group_id, "Line", l_tid,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT)) goto err;
   *ll_tid = l_tid;
 
err:
   return(rstat);
}

The following code excerpt is used to populate an HDF5 file according to the complete context schema.

#include <stdlib.h>
#include <string.h>
 
#include "hdf5.h"
#include "examples.h"
 
#define NO_OF_LLINES 4
 
//------------------------------------------------------------------
//  Create Lines:
//
//  Lines are created by letting the startp and endp
//  attributes (fields) refer to Points in the dataset
//  /Geometry_population/Point_objects/Point_instances
// 
//  (000,100)------------------(100,100)
//           .                 . 
//           .                 . 
//           .                 . 
//           .                 . 
//  (000,000)-------------------(000,100)
//
//------------------------------------------------------------------
herr_t create_llines(hid_t group_id, hid_t l_tid)
{
   herr_t          rstat;
   hid_t           line_dataset;
   hid_t           myspace;
   hid_t           obj_group;
   hsize_t         mydim[1];
   inst_ref_t      inst_ref;
   enum colors_t   line_colour;
   lline_t         lines[NO_OF_LLINES];
 
//
// Populate the four Lines in a memory buffer
//
   mydim[0] = NO_OF_LLINES;
   myspace = H5Screate_simple(1, mydim, NULL);
//
// Lower Line (0,0) to (100,0)
//
   lines[0].set_unset_bitmap = 7;
   lines[0].id = 4;
   inst_ref.dataset_index = get_dataset_index("Point");
   inst_ref.instance_index = 0;
   memcpy(&lines[0].startp,&inst_ref,sizeof(inst_ref_t));
   inst_ref.instance_index = 1;   
   memcpy(&lines[0].endp,&inst_ref,sizeof(inst_ref_t));
   lines[0].colour.select_bitmap = 2;
   line_colour = red;
   lines[0].colour.e_colour = line_colour;
   lines[0].colour.s_colour = "";
//
// Rightmost Line (100,0) to (100,100)
//
   lines[1].set_unset_bitmap = 7;
   lines[1].id = 5;
   inst_ref.instance_index = 1;
   memcpy(&lines[1].startp,&inst_ref,sizeof(inst_ref_t));
   inst_ref.instance_index = 2;   
   memcpy(&lines[1].endp,&inst_ref,sizeof(inst_ref_t));
   lines[1].colour.select_bitmap = 2;
   line_colour = blue;
   lines[1].colour.e_colour = line_colour;
   lines[1].colour.s_colour = "";
//
// Upper Line (100,100) to (0,100)
//
   lines[2].set_unset_bitmap = 7;
   lines[2].id = 6;
   inst_ref.instance_index = 2;
   memcpy(&lines[2].startp,&inst_ref,sizeof(inst_ref_t));
   inst_ref.instance_index = 3;   
   memcpy(&lines[2].endp,&inst_ref,sizeof(inst_ref_t));
   lines[2].colour.select_bitmap = 1;
   line_colour = vvoid;
   lines[2].colour.e_colour = line_colour;
   lines[2].colour.s_colour = "Red line";
//
// Leftmost Line (0,100) to (0,0)
//
   lines[3].set_unset_bitmap = 7;
   lines[3].id = 7;
   inst_ref.instance_index = 3;
   memcpy(&lines[3].startp,&inst_ref,sizeof(inst_ref_t));
   inst_ref.instance_index = 0;   
   memcpy(&lines[3].endp,&inst_ref,sizeof(inst_ref_t));
   lines[3].colour.select_bitmap = 1;
   line_colour = vvoid;
   lines[3].colour.e_colour = line_colour;
   lines[3].colour.s_colour = "Blue line";
//
// Create the group that shall containg the Line dataset
//
   obj_group = H5Gcreate(group_id, "Line_objects", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
//
// Create the dataset that shall contain the Lines
//
   line_dataset = H5Dcreate1(obj_group, "Line_instances", l_tid, myspace, H5P_DEFAULT);
//
// Write the Lines to the dataset
//
   if(rstat = H5Dwrite(line_dataset, l_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, lines)) goto err;
 
err:
   return(rstat);
}

See a dump of the resultant HDF5 file in section C.9.

C.8 EXPRESS aggregate datatype values as HDF5

The "Land_survey" EXPRESS entity defined in the context schema contains two nested aggregates.

//---------------------------------------------------------------------
//  Define Land Survey:
//
//  Exemplifies how references to aggregates are encoded encoded.
//  One aggregate is stored on a separate dataset. The other one is embedded.
//---------------------------------------------------------------------
herr_t define_compound_land_survey(hid_t group_id, hid_t *lls_tid)
{
   herr_t rstat;
   long   mysize,offset;
   long   string_tid_size;
   long   aggr_ref_tid_size;
   hid_t  ls_tid;
   hid_t  string_tid;
   hid_t  aggr1_ref_tid;
   hid_t  aggr2_ref_tid;
   hid_t  vlen_of_vlen_double_tid;
   hid_t  vlen_of_vlen_ref_tid;
 
  *lls_tid = -1;
  string_tid   = H5Tcopy(H5T_C_S1);
  if(rstat = H5Tset_size(string_tid, H5T_VARIABLE)) goto err;
  string_tid_size = H5Tget_size(string_tid);
 
  vlen_of_vlen_ref_tid = define_nested_ref_aggr();
  if(rstat = define_aggr_reference(group_id, vlen_of_vlen_ref_tid, "1", &aggr1_ref_tid)) goto err;
  vlen_of_vlen_double_tid = define_nested_real_aggr();
  if(rstat = define_aggr_reference(group_id, vlen_of_vlen_double_tid, "2", &aggr2_ref_tid)) goto err;
  aggr_ref_tid_size = H5Tget_size(aggr1_ref_tid);
//
// Create named compound type for LAND_SURVEY
//
   mysize = 2*sizeof(long) + string_tid_size + 2*aggr_ref_tid_size;
   offset = 0;
   ls_tid = H5Tcreate (H5T_COMPOUND, mysize);
   if(rstat = H5Tinsert(ls_tid, "set_unset_bitmap", offset, H5T_NATIVE_LONG)) goto err;
   offset += sizeof(long);
   if(rstat = H5Tinsert(ls_tid, "Entity-Instance-Identifier", offset, H5T_NATIVE_LONG)) goto err;
   offset += sizeof(long);
   if(rstat = H5Tinsert(ls_tid, "country", offset, string_tid)) goto err;
   offset += string_tid_size;
   if(rstat = H5Tinsert(ls_tid, "properties", offset, aggr1_ref_tid)) goto err;
   offset += aggr_ref_tid_size;
   if(rstat = H5Tinsert(ls_tid, "altitudes", offset, aggr2_ref_tid )) goto err;
   if(rstat = H5Tcommit2(group_id, "Land_survey",ls_tid,H5P_DEFAULT,H5P_DEFAULT,H5P_DEFAULT)) goto err;
   *lls_tid = ls_tid;
 
err:
   return(rstat);
}

The following code excerpt exemplifies how to create and populate the HDF5 Compund Type corresponding to the "Land_survey" EXPRESS entity, using the HDF5 API.

#include <stdlib.h>
#include <string.h>
 
#include "hdf5.h"
#include "examples.h"
 
 
//------------------------------------------------------------------
//  Create Survey
//------------------------------------------------------------------
herr_t create_survey(hid_t group_id, hid_t ls_tid,hid_t p_tid)
{
   herr_t          rstat;
   hid_t           ls_dataset;
   hid_t           myspace;
   hid_t           obj_group;
   hobj_ref_t      objref;
   hid_t           vlen_of_vlen_double_tid;
   hid_t           vlen_of_vlen_ref_tid;
   long            mysize;
   long            myinteger;
   char            mychar;
   hsize_t         mydim[1];
   char            *norway = "Norway";
   char            *vlen_data;
   char            *buffer;
   char            *mybuffer;
 
   mysize = H5Tget_size(ls_tid);
   mybuffer = (char*) malloc(mysize);
   buffer = mybuffer; 
 
   if(rstat = create_many_points(group_id, p_tid)) goto err;
 
   obj_group = H5Gcreate(group_id, "Land_survey_objects", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
 
   vlen_of_vlen_double_tid = define_nested_real_aggr();
   vlen_of_vlen_ref_tid = define_nested_ref_aggr();
 
   if(rstat =  create_nested_real_aggr(obj_group,vlen_of_vlen_double_tid,&vlen_data)) goto err;
   if(rstat = create_nested_point_aggr(obj_group,vlen_of_vlen_ref_tid)) goto err;
 
   memset(mybuffer,0,mysize);
   myinteger = 15;
   memcpy(mybuffer,&myinteger,sizeof(long));
   mybuffer += sizeof(long);
   myinteger = 25;
   memcpy(mybuffer,&myinteger,sizeof(long));
   mybuffer += sizeof(long);
   memcpy(mybuffer,&norway,sizeof(char*));
   mybuffer += sizeof(char*);
 
   mychar = (char)1;
   memcpy(mybuffer,&mychar,sizeof(char));
   mybuffer += sizeof(char);   
   if(rstat = H5Rcreate(&objref, obj_group, "/Geometry_population/Land_survey_objects/Aggr-properties-1", H5R_OBJECT, -1)) goto err;
   memcpy(mybuffer,&objref,sizeof(hobj_ref_t));
   mybuffer += sizeof(hobj_ref_t);
   mybuffer += sizeof(hvl_t);
 
   mychar = (char)0;
   memcpy(mybuffer,&mychar,sizeof(char));
   mybuffer += sizeof(char);   
   mybuffer += sizeof(hobj_ref_t);
   memcpy(mybuffer,vlen_data,sizeof(hvl_t));
 
//
// Create the LAND SURVEY dataset
//
   mydim[0] = 1;
   myspace = H5Screate_simple(1, mydim, NULL);
 
   ls_dataset = H5Dcreate1(obj_group, "Land_survey_instances", ls_tid, myspace, H5P_DEFAULT);
//
// Write lines to file
//
   if(rstat = H5Dwrite(ls_dataset, ls_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, buffer)) goto err;
 
err:
   free(mybuffer);
   return(rstat);
}

Auxiliary functions are used to define and create the multi-dimensional aggregates that are part of the "Land_survey" Compound type. These functions are called from the "create_survey" function above and they are presented next.

hid_t define_nested_real_aggr(void)
{
  hid_t  vlen_double_tid;
  hid_t  vlen_of_vlen_double_tid;
 
 //
 // Create variable-length datatype in two levels, double beeing the base type
 //
   vlen_double_tid = H5Tvlen_create(H5T_NATIVE_DOUBLE);
   vlen_of_vlen_double_tid = H5Tvlen_create (vlen_double_tid);
   vlen_of_vlen_double_tid = H5Tvlen_create (vlen_of_vlen_double_tid);
 
   return(vlen_of_vlen_double_tid);
}
 
hid_t define_nested_ref_aggr(void)
{
  hid_t  vlen_ref_tid;
  hid_t  vlen_of_vlen_ref_tid;
 
 //
 // Create variable-length datatype in two levels, reference type beeing the base type
 //
   vlen_ref_tid = H5Tvlen_create(instance_reference_tid);
   vlen_of_vlen_ref_tid = H5Tvlen_create (vlen_ref_tid);
 
   return(vlen_of_vlen_ref_tid);
}

#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <string.h>
#include "hdf5.h"
#include "examples.h"
 
#define LEN0            3 
#define LEN1            2
 
//
// NOTE:
// Memory fragments that are allocated in the following two functions are not released.
//
// In a real application a memory management system, where VLEN memory is
// grabbed from a pool of large reausable chunks should be developed.
// (The pool is released upon application exit)
//
// Did not take the time to develop a memory management system for this rather small example,
// so be aware of this small memory leak.
//
//------------------------------------------------------------------
//  Create nested REAL aggregate
//
//  Exemplifies how a nested aggregate of REAL is encoded in HDF5
//  The number of elements on each level are:
//  2-3-6
//     -3
//     -4
//    2-3
//     -6
//------------------------------------------------------------------
herr_t create_nested_real_aggr(hid_t group_id,  hid_t  vlen_of_vlen_double_tid, char **buffer)
{
    hvl_t *wdata;
    hvl_t *mybuf;
    hvl_t   *tA, *tB;
    herr_t  rstat;
    hsize_t dims[1] = {2};
 
    rstat = 0;
    /*
     * Initialize variable-length data.  
     */
    wdata = (hvl_t*) malloc(2*sizeof(hvl_t));
    mybuf = (hvl_t*) malloc(sizeof(hvl_t));
    *buffer = (char*)mybuf;
    mybuf->len = 2;
    mybuf->p = wdata;
    /* Initializing vector C */
 
    wdata[0].len = LEN0;
    wdata[0].p = (hvl_t *) malloc ( LEN0 * sizeof (hvl_t));
    wdata[1].len = LEN1;
    wdata[1].p = (hvl_t *) malloc ( LEN1 * sizeof (hvl_t));
 
    /* Initialize vector A */
    tA = wdata[0].p;
    tA->len = 5;
    tA->p = (double *) malloc (tA->len * sizeof (double));
    ((double *) tA->p)[0] = 100.0;
    ((double *) tA->p)[1] = 101.1;
    ((double *) tA->p)[2] = 102.2;
    ((double *) tA->p)[3] = 103.3;
    ((double *) tA->p)[4] = 104.4;
    tA++;
    tA->len = 3;
    tA->p = (double *) malloc (tA->len * sizeof (double));
    ((double *) tA->p)[0] = 200.0;
    ((double *) tA->p)[1] = 201.1;
    ((double *) tA->p)[2] = 202.2;
    tA++;
    tA->len = 4;
    tA->p = (double *) malloc (tA->len * sizeof (double));
    ((double *)tA->p)[0] = 300.0;
    ((double *)tA->p)[1] = 301.1;
    ((double *)tA->p)[2] = 302.2;
    ((double *)tA->p)[3] = 303.3;
    /* Done with A */ 
 
    /* Initialize vector B */
    tB = wdata[1].p;
    tB->len =3;
    tB->p = (double *) malloc (tB->len * sizeof (double));
    ((double *)tB->p)[0] = 400.0;
    ((double *)tB->p)[1] = 401.1;
    ((double *)tB->p)[2] = 401.2;
    tB++;
    tB->len = 6;
    tB->p = (double *) malloc (tB->len * sizeof (double));
    ((double *) tB->p)[0] = 500.0;
    ((double *) tB->p)[1] = 501.1;
    ((double *) tB->p)[2] = 502.2;
    ((double *) tB->p)[3] = 503.3;
    ((double *) tB->p)[4] = 504.4;
    ((double *) tB->p)[5] = 505.5;
    /* Done with B */ 
 
    return(rstat);
}
 
 
 
//------------------------------------------------------------------
//  Create nested aggregate of references to Point instances
//
//  The number of elements on each level are:
//  2-3-6
//     -3
//     -4
//    2-3
//     -6
//------------------------------------------------------------------
herr_t create_nested_point_aggr(hid_t group_id,  hid_t  vlen_of_vlen_ref_tid)
{
    long rstat;
 
    hid_t      space;
    hid_t      dset;
    inst_ref_t inst_ref;
    inst_ref_t *s_p_ref;
    inst_ref_t *t_p_ref;
 
    hvl_t  wdata[2];           /* Array of vlen structures to write */
    hvl_t  *tA, *tB;
    hsize_t dims[1] = {2};
 
    rstat = -1;
    /*
     * Initialize variable-length data.  
     */
 
    /* Initializing vector C */
 
    wdata[0].len = 3;
    wdata[0].p = (hvl_t *) malloc ( 3 * sizeof (hvl_t));
    wdata[1].len = 2;
    wdata[1].p = (hvl_t *) malloc ( 1 * sizeof (hvl_t));
 
    s_p_ref = &inst_ref;
 
    /* Initialize vector A */
    tA = wdata[0].p;
    tA->len = 5;
    tA->p = (hdset_reg_ref_t *) malloc (tA->len * sizeof (inst_ref_t));
    t_p_ref = (inst_ref_t*)tA->p;
    inst_ref.dataset_index = get_dataset_index("Many_Point");
    inst_ref.instance_index = 0;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 1;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 7;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 11;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 5;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
 
    tA++;
    tA->len = 3;
    tA->p = (inst_ref_t *) malloc (tA->len * sizeof (inst_ref_t));
    t_p_ref = (inst_ref_t*)tA->p;
    inst_ref.instance_index = 1;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 2;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 7;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
 
    tA++;
    tA->len = 4;
    tA->p = (inst_ref_t *) malloc (tA->len * sizeof (inst_ref_t));
    t_p_ref = (inst_ref_t*)tA->p;
    inst_ref.instance_index = 2;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 9;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 13;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 7;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
 
    /* Initialize vector B */
    tB = wdata[1].p;
    tB->len = 3;
    tB->p = (inst_ref_t *) malloc (tB->len * sizeof (inst_ref_t));
    t_p_ref = (inst_ref_t*)tB->p;
    inst_ref.instance_index = 2;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 4;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 9;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
 
    tB++;
    tB->len = 6;
    tB->p = (inst_ref_t *) malloc (tB->len * sizeof (inst_ref_t));
    t_p_ref = (inst_ref_t*)tB->p;
    inst_ref.instance_index = 5;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 11;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 7;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 13;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 16;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
    ++t_p_ref;
    inst_ref.instance_index = 10;
    memcpy(t_p_ref,s_p_ref,sizeof(inst_ref_t));
 
    /* Done with B */ 
 
    /*
     * Create dataspace.  Setting maximum size to NULL sets the maximum
     * size to be the current size.
     */
    space = H5Screate_simple (1, dims, NULL);
 
    /*
     * Create the dataset and write the variable-length data to it.
     */
    dset = H5Dcreate (group_id, "Aggr-properties-1", vlen_of_vlen_ref_tid, space, H5P_DEFAULT, H5P_DEFAULT,H5P_DEFAULT);
 
    rstat = H5Dwrite (dset, vlen_of_vlen_ref_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);
 
 
    return(rstat);
}
 
 
 
//------------------------------------------------------------------
//  Create many Points:
//
//  This function is similar to the create_points function.
//  The only difference is that more points are created 
//  for the purpose of refering to them from an aggregate defined in Land_survey Compound type.
//  Geometrically the Points make up 25 squares in a mesh.
//  (0000,4000),(1000,4000),(2000,4000),(3000,4000),(4000,4000)
//  (0000,3000),(1000,3000),(2000,3000),(3000,3000),(4000,3000)
//  (0000,2000),(1000,2000),(2000,2000),(3000,2000),(4000,2000)
//  (0000,1000),(1000,1000),(2000,1000),(3000,1000),(4000,1000)
//  (0000,0000),(1000,0000),(2000,0000),(3000,0000),(4000,0000)
//------------------------------------------------------------------
herr_t create_many_points(hid_t group_id, hid_t p_tid)
{
  int      i,j,k;
  herr_t   rstat;
  hid_t    point_dataset;
  hid_t    myspace;
  hid_t    obj_group;
  hsize_t  mydim[1];
 
  point_t  many_points[NO_OF_MANY_POINTS];
 
//
// Populate the Points in a memory buffer
//
    k = 0;
    for(i = 0; i<5; ++i){
      for(j = 0; j<5; ++j){
        many_points[k].set_unset_bitmap = 7;
        many_points[k].id = k;
        many_points[k].x = j*1000.;
        many_points[k].y = i*1000.;
        ++k;<s
      }
    }
//
//  Create the group that shall contain the dataset
//
   obj_group = H5Gcreate(group_id, "Many_Point_objects", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
//
//  Create the dataset that shall contain the Points
//
   mydim[0] = NO_OF_MANY_POINTS;
   myspace = H5Screate_simple(1, mydim, NULL);
   point_dataset = H5Dcreate1(obj_group, "Many_Point_instances", p_tid, myspace, H5P_DEFAULT);
   
//
// Write the Points to the dataset
//
   rstat = H5Dwrite(point_dataset, p_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, many_points);
 
   return(rstat);
}

C.9 Complete HDF5 file resultant from examples

The following text fragment represents a dump of an HDF5 file resultant from encoding the complete context schema into an HDF5 file applying the mapping rules described in this part of ISO 10303. It combines the results of all the examples described in this annex.

HDF5 "example.h5" {
GROUP "/" {
   GROUP "Geometry_encoding" {
      ATTRIBUTE "iso_10303_26_schema" {
         DATATYPE  H5T_STRING {
               STRSIZE 16;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            }
         DATASPACE  SCALAR
         DATA {
         (0): "Geometry_schema"
         }
      }
      DATATYPE "AGGREGATE_REFERENCE_1" H5T_COMPOUND {
         H5T_STD_B8LE "obj_ref_or_vlen";
         H5T_REFERENCE "object_reference";
         H5T_VLEN { H5T_VLEN { H5T_COMPOUND {
         H5T_STD_I32LE "_HDF5_dataset_index_";
         H5T_STD_I32LE "_HDF5_instance_index_";
      }}} "vlen_array";
      }
      DATATYPE "AGGREGATE_REFERENCE_2" H5T_COMPOUND {
         H5T_STD_B8LE "obj_ref_or_vlen";
         H5T_REFERENCE "object_reference";
         H5T_VLEN { H5T_VLEN { H5T_VLEN { H5T_IEEE_F64LE}}} "vlen_array";
      }
      DATATYPE "CColour" H5T_COMPOUND {
         H5T_STD_I32LE "select_bitmap";
         H5T_STRING {
            STRSIZE H5T_VARIABLE;
            STRPAD H5T_STR_NULLTERM;
            CSET H5T_CSET_ASCII;
            CTYPE H5T_C_S1;
         } "s_colour";
         H5T_ENUM {
            H5T_STD_I16LE;
            "VVOID"            0;
            "RED"              1;
            "GREEN"            2;
            "BLUE"             3;
            "WHITE"            4;
            "BLACK"            5;
         } "e_colour";
      }
      DATATYPE "Colour" H5T_ENUM {
            H5T_STD_I16LE;
            "VVOID"            0;
            "RED"              1;
            "GREEN"            2;
            "BLUE"             3;
            "WHITE"            4;
            "BLACK"            5;
         };
 
      DATATYPE "Land_survey" H5T_COMPOUND {
         H5T_STD_I32LE "set_unset_bitmap";
         H5T_STD_I32LE "Entity-Instance-Identifier";
         H5T_STRING {
            STRSIZE H5T_VARIABLE;
            STRPAD H5T_STR_NULLTERM;
            CSET H5T_CSET_ASCII;
            CTYPE H5T_C_S1;
         } "country";
         H5T_COMPOUND {
            H5T_STD_B8LE "obj_ref_or_vlen";
            H5T_REFERENCE "object_reference";
            H5T_VLEN { H5T_VLEN { H5T_COMPOUND {
            H5T_STD_I32LE "_HDF5_dataset_index_";
            H5T_STD_I32LE "_HDF5_instance_index_";
         }}} "vlen_array";
         } "properties";
         H5T_COMPOUND {
            H5T_STD_B8LE "obj_ref_or_vlen";
            H5T_REFERENCE "object_reference";
            H5T_VLEN { H5T_VLEN { H5T_VLEN { H5T_IEEE_F64LE}}} "vlen_array";
         } "altitudes";
      }
      DATATYPE "Line" H5T_COMPOUND {
         H5T_STD_I32LE "set_unset_bitmap";
         H5T_STD_I32LE "Entity-Instance-Identifier";
         H5T_COMPOUND {
            H5T_STD_I32LE "_HDF5_dataset_index_";
            H5T_STD_I32LE "_HDF5_instance_index_";
         } "startp";
         H5T_COMPOUND {
            H5T_STD_I32LE "_HDF5_dataset_index_";
            H5T_STD_I32LE "_HDF5_instance_index_";
         } "endp";
         H5T_COMPOUND {
            H5T_STD_I32LE "select_bitmap";
            H5T_STRING {
               STRSIZE H5T_VARIABLE;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            } "s_colour";
            H5T_ENUM {
               H5T_STD_I16LE;
               "VVOID"            0;
               "RED"              1;
               "GREEN"            2;
               "BLUE"             3;
               "WHITE"            4;
               "BLACK"            5;
            } "e_colour";
         } "colour";
      }
      DATATYPE "Point" H5T_COMPOUND {
         H5T_STD_I32LE "set_unset_bitmap";
         H5T_STD_I32LE "Entity-Instance-Identifier";
         H5T_IEEE_F64LE "x";
         H5T_IEEE_F64LE "y";
      }
      DATATYPE "_HDF_INSTANCE_REFERENCE_HANDLE_" H5T_COMPOUND {
         H5T_STD_I32LE "_HDF5_dataset_index_";
         H5T_STD_I32LE "_HDF5_instance_index_";
      }
   }
   GROUP "Geometry_population" {
      ATTRIBUTE "_10303_26_data_set_names" {
         DATATYPE  H5T_ARRAY { [4] H5T_STRING {
               STRSIZE H5T_VARIABLE;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            } }
         DATASPACE  SCALAR
         DATA {
         (0): [ "Point", "Many_Point", "Line", "Land_survey" ]
         }
      }
      ATTRIBUTE "iso_10303_26_data" {
         DATATYPE  H5T_STRING {
               STRSIZE 16;
               STRPAD H5T_STR_NULLTERM;
               CSET H5T_CSET_ASCII;
               CTYPE H5T_C_S1;
            }
         DATASPACE  SCALAR
         DATA {
         (0): "Geometry_schema"
         }
      }
      GROUP "Land_survey_objects" {
         DATASET "Aggr-properties-1" {
            DATATYPE  H5T_VLEN { H5T_VLEN { H5T_COMPOUND {
               H5T_STD_I32LE "_HDF5_dataset_index_";
               H5T_STD_I32LE "_HDF5_instance_index_";
            }}}
            DATASPACE  SIMPLE { ( 2 ) / ( 2 ) }
            DATA {
            (0): (({
                        1,
                        0
                     }, {
                        1,
                        1
                     }, {
                        1,
                        7
                     }, {
                        1,
                        11
                     }, {
                        1,
                        5
                     }), ({
                        1,
                        1
                     }, {
                        1,
                        2
                     }, {
                        1,
                        7
                     }), ({
                        1,
                        2
                     }, {
                        1,
                        9
                     }, {
                        1,
                        13
                     }, {
                        1,
                        7
                     })),
            (1): (({
                        1,
                        2
                     }, {
                        1,
                        4
                     }, {
                        1,
                        9
                     }), ({
                        1,
                        5
                     }, {
                        1,
                        11
                     }, {
                        1,
                        7
                     }, {
                        1,
                        13
                     }, {
                        1,
                        16
                     }, {
                        1,
                        10
                     }))
            }
         }
         DATASET "Land_survey_instances" {
            DATATYPE  "/Geometry_encoding/Land_survey"
            DATASPACE  SIMPLE { ( 1 ) / ( 1 ) }
            DATA {
            (0): {
                  15,
                  25,
                  "Norway",
                  {
                     0x01,
                     DATASET 17632 /Geometry_population/Land_survey_objects/Aggr-properties-1 ,
                     ()
                  },
                  {
                     0x00,
                     NULL,
                     (((100, 101.1, 102.2, 103.3, 104.4), (200, 201.1, 202.2), (300, 301.1, 302.2, 303.3)), ((400, 401.1, 401.2), (500, 501.1, 502.2, 503.3, 504.4, 505.5)))
                  }
               }
            }
         }
      }
      GROUP "Line_objects" {
         DATASET "Line_instances" {
            DATATYPE  "/Geometry_encoding/Line"
            DATASPACE  SIMPLE { ( 4 ) / ( 4 ) }
            DATA {
            (0): {
                  7,
                  4,
                  {
                     0,
                     0
                  },
                  {
                     0,
                     1
                  },
                  {
                     2,
                     "",
                     RED
                  }
               },
            (1): {
                  7,
                  5,
                  {
                     0,
                     1
                  },
                  {
                     0,
                     2
                  },
                  {
                     2,
                     "",
                     BLUE
                  }
               },
            (2): {
                  7,
                  6,
                  {
                     0,
                     2
                  },
                  {
                     0,
                     3
                  },
                  {
                     1,
                     "Red line",
                     VVOID
                  }
               },
            (3): {
                  7,
                  7,
                  {
                     0,
                     3
                  },
                  {
                     0,
                     0
                  },
                  {
                     1,
                     "Blue line",
                     VVOID
                  }
               }
            }
         }
      }
      GROUP "Many_Point_objects" {
         DATASET "Many_Point_instances" {
            DATATYPE  "/Geometry_encoding/Point"
            DATASPACE  SIMPLE { ( 25 ) / ( 25 ) }
            DATA {
            (0): {
                  7,
                  0,
                  0,
                  0
               },
            (1): {
                  7,
                  1,
                  1000,
                  0
               },
            (2): {
                  7,
                  2,
                  2000,
                  0
               },
            (3): {
                  7,
                  3,
                  3000,
                  0
               },
            (4): {
                  7,
                  4,
                  4000,
                  0
               },
            (5): {
                  7,
                  5,
                  0,
                  1000
               },
            (6): {
                  7,
                  6,
                  1000,
                  1000
               },
            (7): {
                  7,
                  7,
                  2000,
                  1000
               },
            (8): {
                  7,
                  8,
                  3000,
                  1000
               },
            (9): {
                  7,
                  9,
                  4000,
                  1000
               },
            (10): {
                  7,
                  10,
                  0,
                  2000
               },
            (11): {
                  7,
                  11,
                  1000,
                  2000
               },
            (12): {
                  7,
                  12,
                  2000,
                  2000
               },
            (13): {
                  7,
                  13,
                  3000,
                  2000
               },
            (14): {
                  7,
                  14,
                  4000,
                  2000
               },
            (15): {
                  7,
                  15,
                  0,
                  3000
               },
            (16): {
                  7,
                  16,
                  1000,
                  3000
               },
            (17): {
                  7,
                  17,
                  2000,
                  3000
               },
            (18): {
                  7,
                  18,
                  3000,
                  3000
               },
            (19): {
                  7,
                  19,
                  4000,
                  3000
               },
            (20): {
                  7,
                  20,
                  0,
                  4000
               },
            (21): {
                  7,
                  21,
                  1000,
                  4000
               },
            (22): {
                  7,
                  22,
                  2000,
                  4000
               },
            (23): {
                  7,
                  23,
                  3000,
                  4000
               },
            (24): {
                  7,
                  24,
                  4000,
                  4000
               }
            }
         }
      }
      GROUP "Point_objects" {
         DATASET "Point_instances" {
            DATATYPE  "/Geometry_encoding/Point"
            DATASPACE  SIMPLE { ( 4 ) / ( 4 ) }
            DATA {
            (0): {
                  7,
                  0,
                  0,
                  0
               },
            (1): {
                  7,
                  1,
                  100,
                  0
               },
            (2): {
                  7,
                  2,
                  100,
                  100
               },
            (3): {
                  7,
                  3,
                  0,
                  100
               }
            }
         }
      }
   }
}
}

C.10 Complete program that executes the examples in this part of ISO 10303

// ------------------------------------------------------------------------------------------------------------------- 
// Main program that executes the examples found in the ISO-10303-P26 specification.
//
// In addition some dump functions are supplied, but these are not complete in the sense
// that all aspects of HDF5 are covered. Please consult the HDF5 documentation for those aspects that are missing.
// Please make use of the h5dump utility offered by the HDF group for a complete dump.
//
// Note:
// An application should close a datatype, dataspace, or dataset object once it is no longer needed.
// H5Tclose(datatype)
// H5Dclose(dataset)
// H5Sclose(dataspace)
// In this small prototype the closing of such objects has been omitted.
// Reclaim of memory has also been omitted.
// Such a practice is certainly not recommended for a real application
// Please consult the HDF5 documentation for the details.
//----------------------------------------------------------------------------------------------------------------------
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#include "hdf5.h"
#include "examples.h"
 
long dump_dataset(hid_t mydataset);
long dump_compound(hid_t mycompound_type, hsize_t curr_offset, char *mybuffer);
long dump_instance_by_reference(hid_t dataset_tid, long dataset_index, long instance_index);
long dump_aggr_by_reference(hid_t obj_tid, hobj_ref_t myref);
long dump_vlen_data(hid_t datatype, long members, char *vlen_data);
 
void error_trap(char *file_name, long lineno);
 
//------------------------------------------------------------------
#define HDF5_FILE "O:/projects/SimDM/HDF5/data/HDF5_files/example.h5"
#define REPORT_FILE "O:/projects/SimDM/HDF5/data/HDF5_files/rep_file.txt"
 
FILE        *rep_file;
extern      hid_t file_id;
extern char *defined_entity_names[NUMBER_OF_ENTITIES] = {"Point","Many_Point","Line","Land_survey"};
extern char *entity_names[NUMBER_OF_ENTITIES];
 
hid_t obj_ref_tid;
long  level = 0;
long  current_line;
char  *current_file;
long  dump_in_aggr_mode = 0;
 
#define GOTO_ERR\
   {\
      current_file = __FILE__;\
      current_line = __LINE__;\
      error_trap(current_file,current_line);\
      goto err;\
   }
 
//
//------------------------------------------------------------------
//
void error_trap(char *file_name, long lineno)
{
      fprintf(rep_file,"\nERROR trapped in '%s' at line: %lu",file_name,lineno);
}
void indent(void)
{
  long ix;
 
  fprintf(rep_file,"\n");
  for(ix = 0; ix< level; ix++) {
    fprintf(rep_file," ");
  }
}
 
void indent_nlf(void)
{
  long ix;
 
  for(ix = 0; ix< level; ix++) {
    fprintf(rep_file," ");
  }
}
 
//------------------------------------------------------------------
//  MAIN program
//------------------------------------------------------------------
int main(int argc, char* argv[])
{
   herr_t  mystatus;
   hid_t   dataset;
   hid_t   group_id;
   hid_t   p_tid; 
   hid_t   l_tid; 
   hid_t   lls_tid;
   hid_t   eenum_col_tid;
   hid_t   cc_tid;
   hid_t   pop_id;
   hid_t   attr_tid;
   hid_t   attr_type_tid;
   hid_t   native_type_tid;
 
   obj_ref_tid   = H5Tcopy(H5T_STD_REF_OBJ);
 
   rep_file = fopen(REPORT_FILE,"w");
   fprintf(rep_file,"\nWriting %s",REPORT_FILE);
 
//
// Create HDF5 file 
//
   file_id = H5Fcreate(HDF5_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
//
// Create group for schemata
//
   if(mystatus = create_schema_group(file_id, "Geometry_encoding", "Geometry_schema", &group_id)) GOTO_ERR;
//
// Create group for the population
//
   if(mystatus = create_pop_group(file_id, "Geometry_population", "Geometry_schema", &pop_id)) GOTO_ERR;
   //
// HDF5 definitions
//
   if(mystatus = define_instance_reference(group_id)) GOTO_ERR;
   if(mystatus = define_compound_point(group_id,&p_tid)) GOTO_ERR;
   if(mystatus = define_colour_enumeration(group_id, &eenum_col_tid)) GOTO_ERR ;
   if(mystatus = define_compound_colour(group_id, eenum_col_tid, &cc_tid)) GOTO_ERR;
   if(mystatus = define_compound_line(group_id,cc_tid,&l_tid)) GOTO_ERR;
   if(mystatus = define_compound_land_survey(group_id, &lls_tid)) GOTO_ERR;
//
// HDF5 population
//
   if(mystatus = create_ppoints(pop_id, p_tid)) GOTO_ERR;
   if(mystatus = create_llines(pop_id, l_tid)) GOTO_ERR;
   if(mystatus = create_survey(pop_id, lls_tid, p_tid)) GOTO_ERR;
//
// Dump HDF5 population
//
   attr_tid = H5Aopen_name(pop_id, "_10303_26_data_set_names");
   if(attr_tid > 0){ 
   attr_type_tid = H5Aget_type(attr_tid);
   native_type_tid = H5Tget_native_type(attr_type_tid,H5T_DIR_ASCEND);
 
   if(mystatus = H5Aread(attr_tid, native_type_tid, entity_names)) goto err;
   if(mystatus = H5Aclose(attr_tid)) goto err;
   if(mystatus = H5Tclose(attr_type_tid)) goto err;
   if(mystatus = H5Tclose(native_type_tid)) goto err;
   } else {
     mystatus = -1;
     goto err;
   }
 
   fprintf(rep_file,"\n\n=====================================================================================");   
   dataset = H5Dopen(file_id, "/Geometry_population/Line_objects/Line_instances", H5P_DEFAULT);
   if( mystatus = dump_dataset(dataset)) GOTO_ERR;
   if(mystatus = H5Dclose(dataset)) GOTO_ERR;
   fprintf(rep_file,"\n\n=====================================================================================");   
   dataset = H5Dopen(file_id, "/Geometry_population/Land_survey_objects/Land_survey_instances", H5P_DEFAULT);
   if(mystatus = dump_dataset(dataset)) GOTO_ERR;
   if(mystatus = H5Dclose(dataset)) GOTO_ERR;
 
   if(mystatus = H5Fclose(file_id)) GOTO_ERR;
   goto ret;
 
err:
   fprintf(rep_file,"\n\nERROR caught");
   mystatus = H5Eprint2(H5E_DEFAULT, rep_file);
 
ret:
   fprintf(rep_file,"\n\nClosing report file");
   fclose(rep_file);
   return(mystatus);
}
 
//------------------------------------------------------------------
// Dump dataset
//------------------------------------------------------------------
 
long dump_dataset(hid_t mydataset)
{
   herr_t      rstat;
   hid_t       mydataset_datatype;
   H5T_class_t mydataset_datatype_class;
   hsize_t     mydataset_datatype_size;
   hid_t       mydataset_filespace;
   hssize_t    mydataset_noel;
   hvl_t       myvlen;
   long        ix;
   char       *mybuffer;
   long        myinteger;
   double      myreal;
 
//
// Get the datasets datatype, class, space and size
//
   mydataset_datatype         = H5Dget_type(mydataset);
   mydataset_datatype_class   = H5Tget_class(mydataset_datatype);
   mydataset_datatype_size    = H5Tget_size(mydataset_datatype);
   mydataset_filespace        = H5Dget_space(mydataset);
//
// Read the dataset
//
   mydataset_noel = H5Sget_simple_extent_npoints(mydataset_filespace);
   mybuffer = (char*) malloc((size_t)(mydataset_datatype_size*mydataset_noel));
   if(mydataset_datatype_class == H5T_STRING){
     if(rstat  = H5Dread(mydataset, mydataset_datatype, mydataset_filespace, mydataset_filespace, H5P_DEFAULT, &mybuffer)) GOTO_ERR;
   } else {
     if(rstat  = H5Dread(mydataset, mydataset_datatype, mydataset_filespace, mydataset_filespace, H5P_DEFAULT, mybuffer)) GOTO_ERR;
   }
//
// Handle each element according to its datatype
//
   for(ix = 0; ix< mydataset_noel; ix++) {
     if(!dump_in_aggr_mode){     
       fprintf(rep_file,"\n--(%d)",ix);
     }
 
     switch(mydataset_datatype_class){
       case H5T_INTEGER:
         memcpy(&myinteger,mybuffer,sizeof(long));
         mybuffer += sizeof(long);
         indent();
         fprintf(rep_file,"%lu",myinteger);
       break;
       case H5T_FLOAT:
         memcpy(&myreal,mybuffer,sizeof(double));
         mybuffer += sizeof(double);
         indent();
         fprintf(rep_file,"%f",myreal);
       break;
       case H5T_STRING:
         indent();
         fprintf(rep_file,"%s",mybuffer);
         mybuffer += sizeof(char*);
       break;
       case H5T_COMPOUND:
         ++level;
         indent();
         if(rstat = dump_compound(mydataset_datatype,0,mybuffer)) GOTO_ERR;
         mybuffer += mydataset_datatype_size;
         --level;
         break;
       case H5T_VLEN:
         memcpy(&myvlen,mybuffer,sizeof(hvl_t));
         mybuffer += sizeof(hvl_t);
         if(rstat = dump_vlen_data(mydataset_datatype,myvlen.len, myvlen.p)) GOTO_ERR;
       break;
       default:
         indent();
         fprintf(rep_file,"OOPS! Unhandled datatype");
     }
   }
err:
   return(rstat);
}  
 
 
//------------------------------------------------------------------
// Dump Compound type instance
//------------------------------------------------------------------
 
long dump_compound(hid_t mycompound_type, hsize_t curr_offset, char *mybuffer)
{
   hsize_t        mycompound_type_size;
   int            mycompound_type_members;
   long           dataset_index;
   long           instance_index;
   long           obj_ref_or_vlen;
   long           jx;
   long           len;
   herr_t         rstat;
   char           *mymember_name;
   hvl_t           myvlen;
   hsize_t         mymember_offset;
   hsize_t         myoffset;
   hsize_t         mymember_type_size;
   hid_t           mymember_type;
   hid_t           dataset_tid;
   H5T_class_t     mymember_class;
   long            myinteger;
   double          myreal;
   short           myenumval;
   char            *mystring;
   char            enum_name[10];
   hobj_ref_t      obj_ref;
   enum colors_t   mycolor;
   char            dataset_name[100];
 
   rstat = 0;
 
   mymember_name      = H5Tget_member_name(mycompound_type,0);
   if(!strcmp(mymember_name,"_HDF5_dataset_index_")){
     memcpy(&dataset_index,mybuffer+curr_offset,sizeof(long));
     memcpy(&instance_index,mybuffer+curr_offset+(sizeof(long)),sizeof(long));
     strcpy(dataset_name,"/Geometry_population/");
     strcat(dataset_name,entity_names[dataset_index]);
     strcat(dataset_name,"_objects/");
     strcat(dataset_name,entity_names[dataset_index]);
     strcat(dataset_name,"_instances");
     dataset_tid = H5Dopen(file_id, dataset_name, H5P_DEFAULT);
     if(rstat = dump_instance_by_reference(dataset_tid,dataset_index,instance_index)) GOTO_ERR;
     if(rstat = H5Dclose(dataset_tid)) GOTO_ERR;
     return(rstat);
   }
 
   if(!strcmp(mymember_name,"obj_ref_or_vlen")){
     obj_ref_or_vlen = (long)*(mybuffer +curr_offset);
     if(obj_ref_or_vlen == 1){
       curr_offset += sizeof(char);
       memcpy(&obj_ref,mybuffer + curr_offset,sizeof(hobj_ref_t));
       if(rstat = dump_aggr_by_reference(mycompound_type,obj_ref)) GOTO_ERR;
       return(rstat);
     }
     if(obj_ref_or_vlen == 0){
       curr_offset += sizeof(char) + sizeof(hobj_ref_t);
       memcpy(&myvlen,mybuffer + curr_offset,sizeof(hvl_t));
       mymember_type = H5Tget_member_type(mycompound_type,2);
       if(rstat = dump_vlen_data(mymember_type,myvlen.len,myvlen.p)) GOTO_ERR;
       return(rstat);
     }
   }
 
   ++level;
 
   len = H5Iget_name(mycompound_type, NULL,0);
   len = H5Iget_name(mycompound_type, dataset_name,len+1);
   fprintf(rep_file,"%s:" ,dataset_name);
 
   mycompound_type_size    = H5Tget_size(mycompound_type);
   mycompound_type_members = H5Tget_nmembers(mycompound_type);
//
// Handle membmer by member
//
   for(jx = 0; jx< mycompound_type_members; jx++) {
     indent();indent_nlf();
//
// Get the characteristics of the member
//
     mymember_name      = H5Tget_member_name(mycompound_type,jx);
     mymember_type      = H5Tget_member_type(mycompound_type,jx);
     mymember_class     = H5Tget_member_class(mycompound_type,jx);
     mymember_offset    = H5Tget_member_offset(mycompound_type,jx);
     mymember_type_size = H5Tget_size(mymember_type);
     myoffset = curr_offset + mymember_offset;
//
// Branch on datatype.
// 
     switch(mymember_class){
     case H5T_INTEGER:
       memcpy(&myinteger,mybuffer + myoffset,sizeof(long));
       fprintf(rep_file,"%s: %lu",mymember_name,myinteger);
     break;
     case H5T_FLOAT:
       memcpy(&myreal,mybuffer + myoffset,sizeof(double));
       fprintf(rep_file,"%s: %f",mymember_name,myreal);
     break;
     case H5T_REFERENCE:
       if(H5Tequal(obj_ref_tid,mymember_type)){
         fprintf(rep_file,"%s: ",mymember_name);
          memcpy(&obj_ref,mybuffer + myoffset,sizeof(hobj_ref_t));
          if(rstat = dump_aggr_by_reference(mycompound_type,obj_ref)) GOTO_ERR;
       }
     break;
     case H5T_STRING:
       memcpy(&mystring,mybuffer + myoffset,sizeof(char*));
       fprintf(rep_file,"%s: %s",mymember_name,mystring);
     break;
     case H5T_COMPOUND:
       fprintf(rep_file,"%s: ",mymember_name);
       if(rstat = dump_compound(mymember_type,myoffset,mybuffer)) GOTO_ERR;
     break;
     case H5T_ENUM:
       fprintf(rep_file,"%s: ",mymember_name);
       memcpy(&mycolor,mybuffer + myoffset,sizeof(enum colors_t));
       if(rstat = H5Tenum_nameof(mymember_type,&mycolor,enum_name,10)) GOTO_ERR;
       if(rstat = H5Tenum_valueof(mymember_type,enum_name,&myenumval)) GOTO_ERR;
       fprintf(rep_file,"%d : %s",myenumval,enum_name);
     break;
     case H5T_VLEN: 
       memcpy(&myvlen,mybuffer + myoffset,sizeof(hvl_t));
       if(rstat = dump_vlen_data(mymember_type,myvlen.len,myvlen.p)) GOTO_ERR;
       break;
     default:
       fprintf(rep_file,"\nOOPS! Unhandeled datatype");
   }
 }
 --level;
err:
   return(rstat);
}
//------------------------------------------------------------------
// Dump referenced aggregate  
//------------------------------------------------------------------
long dump_aggr_by_reference(hid_t obj_tid, hobj_ref_t myref)
{
   long        mystatus;
   hid_t       dataset_reg;
 
   mystatus = 0;
   dump_in_aggr_mode = 1;
   ++level;
//
// Get the reference 
//
   dataset_reg = H5Rdereference(obj_tid, H5R_OBJECT,&myref);
   if(dataset_reg < 0){
     mystatus = -1;
     GOTO_ERR;
   }
//
// Dump the refered aggregate 
//
   mystatus = dump_dataset(dataset_reg);
   --level;
 
err:
   dump_in_aggr_mode = 0;
   return(mystatus);
}
//------------------------------------------------------------------
// Dump referenced instance
//------------------------------------------------------------------
long dump_instance_by_reference(hid_t dataset_tid, long dataset_index, long instance_index)
{
   long        rstat;
   hid_t       mydataset_filespace;
   hid_t       dataset_datatype;
   size_t      dataset_datatype_size;
   hsize_t     mydim[1];
   hid_t       mymem_space;
   hsize_t     mycoord[1][1];
   char       *dataset_buffer;
//
// Read the selected instance 
//
   mydim[0] = 1;
   mymem_space = H5Screate_simple(1, mydim, NULL);
   dataset_datatype = H5Dget_type(dataset_tid);
   dataset_datatype_size = H5Tget_size(dataset_datatype);
   dataset_buffer = (char*) malloc(dataset_datatype_size);
 
   mydataset_filespace =  H5Dget_space(dataset_tid);
 
   mycoord[0][0] = instance_index;
   if(rstat = H5Sselect_elements(mydataset_filespace, H5S_SELECT_SET, 1, (const hsize_t *)&mycoord)) GOTO_ERR;
   if(rstat  = H5Dread(dataset_tid, dataset_datatype, mymem_space, mydataset_filespace, H5P_DEFAULT, dataset_buffer)) GOTO_ERR;
//
// Dump the instance from buffer
//
   if(rstat = dump_compound(dataset_datatype,0,dataset_buffer)) GOTO_ERR;
 
   free(dataset_buffer);
 
err: 
   return(rstat);
}
 
//------------------------------------------------------------------
// Dump VLEN data
//------------------------------------------------------------------
long dump_vlen_data(hid_t datatype, long members, char *vlen_data)
{
   long          rstat,i;
   long          super_size;
   hid_t         super_tid;
   H5T_class_t   super_class;
   double        myreal;
   long          myinteger;
   short         myenumval;
   enum colors_t mycolor;
   hobj_ref_t    obj_ref;
   char          enum_name[10];
   hvl_t         myvlen;
   char          *p_myvlen;
 
   rstat = 0;
   p_myvlen = vlen_data;
//
// Get type of VLEN data
//
   super_tid   = H5Tget_super(datatype);
   super_class = H5Tget_class(super_tid);
   super_size  = H5Tget_size(super_tid);
   ++level;++level;
   indent();
   fprintf(rep_file,"(");
//
// Branch on type for each element
//
   for(i=0; i<members; ++i){
     switch(super_class){
       case H5T_INTEGER:
         memcpy(&myinteger,p_myvlen,sizeof(long));
         p_myvlen += sizeof(long);
         fprintf(rep_file," %lu ",myinteger);
       break;
       case H5T_FLOAT:
         memcpy(&myreal,p_myvlen,sizeof(double));
         p_myvlen += sizeof(double);
         fprintf(rep_file," %f ",myreal);
       break;
       case H5T_VLEN:
         memcpy(&myvlen,p_myvlen,sizeof(hvl_t));
         if(rstat = dump_vlen_data(super_tid,myvlen.len,myvlen.p)) GOTO_ERR;
         p_myvlen += sizeof(hvl_t);
       break;
       case H5T_COMPOUND:
         indent();
         if(rstat = dump_compound(super_tid,0,p_myvlen)) GOTO_ERR;
         p_myvlen += super_size;
       break;
       case H5T_REFERENCE:
         if(H5Tequal(obj_ref_tid,super_tid)){
           indent();
           memcpy(&obj_ref,p_myvlen,sizeof(hobj_ref_t));
           if(rstat = dump_aggr_by_reference(super_tid,obj_ref)) GOTO_ERR;
           p_myvlen += super_size;
         }
       break;
       case H5T_ENUM:
         memcpy(&mycolor,p_myvlen,sizeof(enum colors_t));
         p_myvlen += sizeof(enum colors_t);
         if(rstat = H5Tenum_nameof(super_tid,&mycolor,enum_name,10)) GOTO_ERR;
         if(rstat = H5Tenum_valueof(super_tid,enum_name,&myenumval)) GOTO_ERR;
         fprintf(rep_file,"%d : %s",myenumval,enum_name);
       break;
       default:
         fprintf(rep_file,"\nOOPS! Unhandeled datatype");
     }
  }
  indent();
  fprintf(rep_file,")");
  --level;--level;
 
err:
   return(rstat);
}
//
// Get dataset index
//
long get_dataset_index(char *entity_name)
{
  long dataset_index,i;
 
  dataset_index = -1;
  for(i=0; i<NUMBER_OF_ENTITIES; ++i){
    if(!strcmp(defined_entity_names[i],entity_name)){
      return(i);
    }
  }
 
  return(dataset_index);
}


C.10 Contents of report file after running the example

=====================================================================================
--(0)
 /Geometry_encoding/Line:
    set_unset_bitmap: 7
    Entity-Instance-Identifier: 4
    startp: /Geometry_encoding/Point:
      set_unset_bitmap: 7
      Entity-Instance-Identifier: 0
      x: 0.000000
      y: 0.000000
    endp: /Geometry_encoding/Point:
      set_unset_bitmap: 7
      Entity-Instance-Identifier: 1
      x: 100.000000
      y: 0.000000
    colour: /Geometry_encoding/CColour:
      select_bitmap: 2
      s_colour: 
      e_colour: 1 : RED
--(1)
 /Geometry_encoding/Line:
    set_unset_bitmap: 7
    Entity-Instance-Identifier: 5
    startp: /Geometry_encoding/Point:
      set_unset_bitmap: 7
      Entity-Instance-Identifier: 1
      x: 100.000000
      y: 0.000000
    endp: /Geometry_encoding/Point:
      set_unset_bitmap: 7
      Entity-Instance-Identifier: 2
      x: 100.000000
      y: 100.000000
    colour: /Geometry_encoding/CColour:
      select_bitmap: 2
      s_colour: 
      e_colour: 3 : BLUE
--(2)
 /Geometry_encoding/Line:
    set_unset_bitmap: 7
    Entity-Instance-Identifier: 6
    startp: /Geometry_encoding/Point:
      set_unset_bitmap: 7
      Entity-Instance-Identifier: 2
      x: 100.000000
      y: 100.000000
    endp: /Geometry_encoding/Point:
      set_unset_bitmap: 7
      Entity-Instance-Identifier: 3
      x: 0.000000
      y: 100.000000
    colour: /Geometry_encoding/CColour:
      select_bitmap: 1
      s_colour: Red line
      e_colour: 0 : VVOID
--(3)
 /Geometry_encoding/Line:
    set_unset_bitmap: 7
    Entity-Instance-Identifier: 7
    startp: /Geometry_encoding/Point:
      set_unset_bitmap: 7
      Entity-Instance-Identifier: 3
      x: 0.000000
      y: 100.000000
    endp: /Geometry_encoding/Point:
      set_unset_bitmap: 7
      Entity-Instance-Identifier: 0
      x: 0.000000
      y: 0.000000
    colour: /Geometry_encoding/CColour:
      select_bitmap: 1
      s_colour: Blue line
      e_colour: 0 : VVOID

=====================================================================================
--(0)
 /Geometry_encoding/Land_survey:
    set_unset_bitmap: 15
    Entity-Instance-Identifier: 25
    country: Norway
    properties: 
     (
       (
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 0
                x: 0.000000
                y: 0.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 1
                x: 1000.000000
                y: 0.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 7
                x: 2000.000000
                y: 1000.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 11
                x: 1000.000000
                y: 2000.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 5
                x: 0.000000
                y: 1000.000000
       )
       (
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 1
                x: 1000.000000
                y: 0.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 2
                x: 2000.000000
                y: 0.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 7
                x: 2000.000000
                y: 1000.000000
       )
       (
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 2
                x: 2000.000000
                y: 0.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 9
                x: 4000.000000
                y: 1000.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 13
                x: 3000.000000
                y: 2000.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 7
                x: 2000.000000
                y: 1000.000000
       )
     )
     (
       (
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 2
                x: 2000.000000
                y: 0.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 4
                x: 4000.000000
                y: 0.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 9
                x: 4000.000000
                y: 1000.000000
       )
       (
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 5
                x: 0.000000
                y: 1000.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 11
                x: 1000.000000
                y: 2000.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 7
                x: 2000.000000
                y: 1000.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 13
                x: 3000.000000
                y: 2000.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 16
                x: 1000.000000
                y: 3000.000000
       /Geometry_encoding/Point:
                set_unset_bitmap: 7
                Entity-Instance-Identifier: 10
                x: 0.000000
                y: 2000.000000
       )
     )
    altitudes: 
    (
      (
        ( 100.000000  101.100000  102.200000  103.300000  104.400000 
        )
        ( 200.000000  201.100000  202.200000 
        )
        ( 300.000000  301.100000  302.200000  303.300000 
        )
      )
      (
        ( 400.000000  401.100000  401.200000 
        )
        ( 500.000000  501.100000  502.200000  503.300000  504.400000  505.500000 
        )
      )
    )
© ISO 2011 — All rights reserved