1/* This is part of the netCDF package.
2   Copyright 2005 University Corporation for Atmospheric Research/Unidata
3   See COPYRIGHT file for conditions of use.
4
5   Test HDF5 file code. These are not intended to be exhaustive tests,
6   but they use HDF5 the same way that netCDF-4 does, so if these
7   tests don't work, than netCDF-4 won't work either.
8
9   This program deals with HDF5 compound types.
10
11   $Id: tst_h_compounds.c,v 1.25 2010/06/01 15:34:51 ed Exp $
12*/
13#include "h5_err_macros.h"
14#include <hdf5.h>
15
16#define FILE_NAME "tst_h_compounds.h5"
17#define DIM1_LEN 3
18#define OSMONDS "TheOsmonds"
19#define WHO "TheWho"
20#define BOOZE_VAR "Alcohol_Consumed"
21#define BEER_OR_WINE "Beer_or_Wine"
22#define LIQUOR "The_Hard_Stuff"
23#define COMPOUND_NAME "Booze_Index"
24#define ARRAY_LEN 5
25#define STR_LEN 255
26
27int
28main()
29{
30   hid_t fileidosmonds_grpidwho_grpidspaceidtypeid;
31   hid_t datasetiddatasetid1typeid1;
32   hsize_t dims[1];
33   struct s1 {
34         int i1i2;
35   } data[DIM1_LEN];
36   struct s2 {
37         int i1[ARRAY_LEN], i2;
38   } data2[DIM1_LEN];
39   char *dummy;
40   int ij;
41
42   /* REALLY initialize the data (even the gaps in the structs). This
43    * is only needed to pass valgrind. */
44   if (!(dummy = calloc(sizeof(struct s2), DIM1_LEN))) ERR;
45   memcpy((void *)data2, (void *)dummy, sizeof(struct s2) * DIM1_LEN);
46   free(dummy);
47   if (!(dummy = calloc(sizeof(struct s1), DIM1_LEN))) ERR;
48   memcpy((void *)data2, (void *)dummy, sizeof(struct s1) * DIM1_LEN);
49   free(dummy);
50
51   for (i=0; i<DIM1_LENi++)
52   {
53      data[i].i1 = 99;
54      data[i].i2 = -99;
55      data2[i].i2 = -99;
56      for (j=0; j<ARRAY_LENj++)
57         data2[i].i1[j] = 99;
58  }
59
60   printf("\n*** Checking HDF5 compound types.\n");
61   printf("*** Checking simple HDF5 compound types...");
62   {
63
64      /* Open file and create group. */
65      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULT,
66                              H5P_DEFAULT)) < 0) ERR;
67      if ((osmonds_grpid = H5Gcreate(fileidOSMONDS, 0)) < 0) ERR;
68
69      /* Create a simple compound type. */
70      if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
71      if (H5Tinsert(typeidBEER_OR_WINEHOFFSET(struct s1i1), H5T_NATIVE_INT) < 0) ERR;
72      if (H5Tinsert(typeidLIQUORHOFFSET(struct s1i2), H5T_NATIVE_INT) < 0) ERR;
73      if (H5Tcommit(osmonds_grpidCOMPOUND_NAMEtypeid) < 0) ERR;
74
75      /* Create a space. */
76      dims[0] = DIM1_LEN;
77      if ((spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
78
79      /* Create a dataset of this compound type. */
80      if ((datasetid = H5Dcreate(osmonds_grpidBOOZE_VARtypeid,
81                                 spaceidH5P_DEFAULT)) < 0) ERR;
82
83      /* Write some data. */
84      if (H5Dwrite(datasetidtypeidH5S_ALLH5S_ALL,
85                   H5P_DEFAULTdata) < 0) ERR;
86
87      /* Release all resources. */
88      if (H5Dclose(datasetid) < 0 ||
89          H5Tclose(typeid) < 0 ||
90          H5Sclose(spaceid) < 0 ||
91          H5Gclose(osmonds_grpid) < 0 ||
92          H5Fclose(fileid) < 0) ERR;
93
94      /* Now open the file and read it. */
95      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
96      if ((osmonds_grpid = H5Gopen(fileidOSMONDS)) < 0) ERR;
97      if ((datasetid = H5Dopen1(osmonds_grpidBOOZE_VAR)) < 0) ERR;
98      if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
99      if (H5Tget_class(typeid) != H5T_COMPOUNDERR;
100      if (H5Tget_nmembers(typeid) != 2) ERR;
101      /* This doesn't work because all I have is a reference to the type!
102         if (H5Iget_name(typeid, type_name, STR_LEN) < 0) ERR;
103         if (strcmp(type_name, COMPOUND_NAME)) ERR;*/
104
105      /* Release all resources. */
106      if (H5Dclose(datasetid) < 0 ||
107          H5Tclose(typeid) < 0 ||
108          H5Gclose(osmonds_grpid) < 0 ||
109          H5Fclose(fileid) < 0) ERR;
110   }
111
112   SUMMARIZE_ERR;
113   printf("*** Checking HDF5 compound types and groups...");
114
115   {
116      /* Open file and create two group. */
117      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULT,
118                              H5P_DEFAULT)) < 0) ERR;
119      if ((osmonds_grpid = H5Gcreate(fileidOSMONDS, 0)) < 0) ERR;
120      if ((who_grpid = H5Gcreate(fileidWHO, 0)) < 0) ERR;
121
122      /* Create a simple compound type. */
123      if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
124      if (H5Tinsert(typeidBEER_OR_WINEHOFFSET(struct s1i1), H5T_NATIVE_INT) < 0) ERR;
125      if (H5Tinsert(typeidLIQUORHOFFSET(struct s1i2), H5T_NATIVE_INT) < 0) ERR;
126      if (H5Tcommit(osmonds_grpidCOMPOUND_NAMEtypeid) < 0) ERR;
127
128      /* Create a space. */
129      dims[0] = DIM1_LEN;
130      if ((spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
131
132      /* Create a dataset of this compound type in the same group. */
133      if ((datasetid = H5Dcreate(osmonds_grpidBOOZE_VARtypeid,
134                                 spaceidH5P_DEFAULT)) < 0) ERR;
135
136      /* Write some data. */
137      if (H5Dwrite(datasetidtypeidH5S_ALLH5S_ALL,
138                   H5P_DEFAULTdata) < 0) ERR;
139
140      /* Create a dataset of this compound type in a different group. */
141      if ((datasetid1 = H5Dcreate(who_grpidBOOZE_VARtypeid,
142                                  spaceidH5P_DEFAULT)) < 0) ERR;
143
144      /* Write some data. */
145      if (H5Dwrite(datasetid1typeidH5S_ALLH5S_ALL,
146                   H5P_DEFAULTdata) < 0) ERR;
147
148      /* Release all resources. */
149      if (H5Dclose(datasetid) < 0 ||
150          H5Dclose(datasetid1) < 0 ||
151          H5Tclose(typeid) < 0 ||
152          H5Sclose(spaceid) < 0 ||
153          H5Gclose(osmonds_grpid) < 0 ||
154          H5Gclose(who_grpid) < 0 ||
155          H5Fclose(fileid) < 0) ERR;
156
157      {
158         hsize_t num_obj;
159         int iobj_type;
160         char name[STR_LEN + 1];
161         htri_t equal;
162
163
164         /* Now open the file and read it. */
165         if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
166         if ((osmonds_grpid = H5Gopen(fileidOSMONDS)) < 0) ERR;
167         if (H5Gget_num_objs(osmonds_grpid, &num_obj) < 0) ERR;
168         for (i=0; i<num_obji++)
169         {
170            if (H5Gget_objname_by_idx(osmonds_grpidinameSTR_LEN+1) < 0) ERR;
171            if ((obj_type = H5Gget_objtype_by_idx(osmonds_grpidi)) < 0) ERR;
172            switch(obj_type)
173            {
174               case H5G_DATASET:
175                  if ((datasetid = H5Dopen1(osmonds_grpidname)) < 0) ERR;
176                  break;
177               case H5G_TYPE:
178                  if ((typeid = H5Topen(osmonds_grpidname)) < 0) ERR;
179                  if (H5Tget_class(typeid) != H5T_COMPOUNDERR;
180                  if (H5Tget_nmembers(typeid) != 2) ERR;
181                  if (strcmp(nameCOMPOUND_NAME)) ERR;
182                  break;
183               default:
184                  ERR;
185            }
186         }
187
188         /* Open the other dataset, and learn about its type. */
189         if ((who_grpid = H5Gopen(fileidWHO)) < 0) ERR;
190         if ((datasetid1 = H5Dopen1(who_grpidBOOZE_VAR)) < 0) ERR;
191         if ((typeid1 = H5Dget_type(datasetid1)) < 0) ERR;
192         if ((equal = H5Tequal(typeidtypeid1)) < 0) ERR;
193         if (!equalERR;
194      }
195
196      /* Release all resources. */
197      if (H5Dclose(datasetid) < 0 ||
198          H5Dclose(datasetid1) < 0 ||
199          H5Tclose(typeid) < 0 ||
200          H5Tclose(typeid1) < 0 ||
201          H5Gclose(osmonds_grpid) < 0 ||
202          H5Gclose(who_grpid) < 0 ||
203          H5Fclose(fileid) < 0) ERR;
204
205   }
206
207   SUMMARIZE_ERR;
208   printf("*** Checking HDF5 compound type which contains an array...");
209
210   {
211      hsize_t array_dims[] = {ARRAY_LEN};
212      hid_t array_typeid;
213
214      /* Open file and create group. */
215      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULT,
216                              H5P_DEFAULT)) < 0) ERR;
217      if ((osmonds_grpid = H5Gcreate(fileidOSMONDS, 0)) < 0) ERR;
218
219      /* Create an array type. */
220      if ((array_typeid = H5Tarray_create(H5T_NATIVE_INT, 1, array_dimsNULL)) < 0) ERR;
221
222      /* Create a compound type containing an array. */
223      if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct s2))) < 0) ERR;
224      if (H5Tinsert(typeidBEER_OR_WINEHOFFSET(struct s2i1), array_typeid) < 0) ERR;
225      if (H5Tinsert(typeidLIQUORHOFFSET(struct s2i2), H5T_NATIVE_INT) < 0) ERR;
226      if (H5Tcommit(osmonds_grpidCOMPOUND_NAMEtypeid) < 0) ERR;
227
228      /* Create a space. */
229      dims[0] = DIM1_LEN;
230      if ((spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
231
232      /* Create a dataset of this compound type. */
233      if ((datasetid = H5Dcreate(osmonds_grpidBOOZE_VARtypeid,
234                                 spaceidH5P_DEFAULT)) < 0) ERR;
235
236      /* Write some data. */
237      if (H5Dwrite(datasetidtypeidH5S_ALLH5S_ALL,
238                   H5P_DEFAULTdata2) < 0) ERR;
239
240      /* Release all resources. */
241      if (H5Dclose(datasetid) < 0 ||
242          H5Tclose(typeid) < 0 ||
243          H5Tclose(array_typeid) < 0 ||
244          H5Sclose(spaceid) < 0 ||
245          H5Gclose(osmonds_grpid) < 0 ||
246          H5Fclose(fileid) < 0) ERR;
247
248      /* Now open the file and read it. */
249      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
250      if ((osmonds_grpid = H5Gopen(fileidOSMONDS)) < 0) ERR;
251      if ((datasetid = H5Dopen1(osmonds_grpidBOOZE_VAR)) < 0) ERR;
252      if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
253      if (H5Tget_class(typeid) != H5T_COMPOUNDERR;
254      if (H5Tget_nmembers(typeid) != 2) ERR;
255      /* This doesn't work because all I have is a reference to the type!
256         if (H5Iget_name(typeid, type_name, STR_LEN) < 0) ERR;
257         if (strcmp(type_name, COMPOUND_NAME)) ERR;*/
258
259      /* Release all resources. */
260      if (H5Dclose(datasetid) < 0 ||
261          H5Tclose(typeid) < 0 ||
262          H5Gclose(osmonds_grpid) < 0 ||
263          H5Fclose(fileid) < 0) ERR;
264   }
265
266   SUMMARIZE_ERR;
267   printf("*** Checking HDF5 compound type 6 different types...");
268
269   {
270#define DAY "day"
271#define ELEV "elev"
272#define COUNT "count"
273#define RELHUM "relhum"
274#define TIME "time"
275#define OBS_T "obs_t"
276#define OBS_VAR "obs_var"
277#define DIM6_LEN 3
278
279      hid_t fileidgrpidspaceidtypeidnative_typeid;
280      hid_t datasetidmem_type;
281      hsize_t dims[1];
282      typedef struct obs_t {
283            char day ;
284            short elev;
285            int count;
286            float relhum;
287            double time;
288      } obs_t ;
289      obs_t obsdata[DIM6_LEN];
290      obs_t obsdata_in[DIM6_LEN], obsdata2_in[DIM6_LEN];
291      char file_in[STR_LEN * 2];
292      char *dummy;
293      size_t size_in;
294
295      /* REALLY initialize the data (even the gaps in the structs). This
296       * is only needed to pass valgrind. */
297      if (!(dummy = calloc(sizeof(struct obs_t), DIM6_LEN))) ERR;
298      memcpy((void *)obsdata, (void *)dummy, sizeof(struct obs_t) * DIM6_LEN);
299      free(dummy);
300
301      /* Initialize data. */
302      for (i = 0; i < DIM6_LENi++)
303      {
304  obsdata[i].day = 15 * i + 1;
305  obsdata[i].elev = 2 * i + 1;
306  obsdata[i].count = 2 * i + 1;
307  obsdata[i].relhum = 2.0 * i + 1;
308  obsdata[i].time = 2.0 * i + 1;
309      }
310
311      /* Open file and create group. */
312      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
313      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
314
315      /* Create a compound type containing some different types. */
316      if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct obs_t))) < 0) ERR;
317      if (H5Tinsert(typeidDAYHOFFSET(struct obs_tday), H5T_NATIVE_CHAR) < 0) ERR;
318      if (H5Tinsert(typeidELEVHOFFSET(struct obs_telev), H5T_NATIVE_SHORT) < 0) ERR;
319      if (H5Tinsert(typeidCOUNTHOFFSET(struct obs_tcount), H5T_NATIVE_INT) < 0) ERR;
320      if (H5Tinsert(typeidRELHUMHOFFSET(struct obs_trelhum), H5T_NATIVE_FLOAT) < 0) ERR;
321      if (H5Tinsert(typeid, TIME, HOFFSET(struct obs_t, time), H5T_NATIVE_DOUBLE) < 0) ERR;
322      if (H5Tcommit(grpidOBS_Ttypeid) < 0) ERR;
323
324      /* Create a space. */
325      dims[0] = DIM6_LEN;
326      if ((spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
327
328      /* Create a dataset of this compound type. */
329      if ((datasetid = H5Dcreate(grpidOBS_VARtypeidspaceidH5P_DEFAULT)) < 0) ERR;
330
331      /* Write some data. */
332      if (H5Dwrite(datasetidtypeidH5S_ALLH5S_ALLH5P_DEFAULTobsdata) < 0) ERR;
333
334      /* Release all resources. */
335      if (H5Dclose(datasetid) < 0 ||
336          H5Tclose(typeid) < 0 ||
337          H5Sclose(spaceid) < 0 ||
338          H5Gclose(grpid) < 0 ||
339          H5Fclose(fileid) < 0) ERR;
340
341      /* Now open the file and read it. */
342      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
343      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
344      if ((datasetid = H5Dopen1(grpidOBS_VAR)) < 0) ERR;
345      if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
346      if ((size_in = H5Tget_size(typeid)) == 0) ERR;
347      if (size_in != sizeof(struct obs_t)) ERR;
348      if ((native_typeid = H5Tget_native_type(typeidH5T_DIR_DEFAULT)) < 0) ERR;
349      if ((size_in = H5Tget_size(native_typeid)) == 0) ERR;
350      if (size_in != sizeof(struct obs_t)) ERR;
351      if (H5Tget_class(typeid) != H5T_COMPOUNDERR;
352      if (H5Tget_nmembers(typeid) != 5) ERR;
353
354      /* Read all data. */
355      if (H5Dread(datasetidtypeidH5S_ALLH5S_ALLH5P_DEFAULTobsdata_in) < 0) ERR;
356
357      /* Check the data. */
358      for (i = 0; i < DIM6_LENi++)
359      {
360         if (obsdata[i].day != obsdata_in[i].day || obsdata[i].elev != obsdata_in[i].elev ||
361             obsdata[i].count != obsdata_in[i].count || obsdata[i].relhum != obsdata_in[i].relhum ||
362             obsdata[i].time != obsdata_in[i].time)
363         {
364            ERR;
365            return 1;
366         }
367      }
368
369      /* Release all resources. */
370      if (H5Dclose(datasetid) < 0 ||
371          H5Tclose(typeid) < 0 ||
372          H5Gclose(grpid) < 0 ||
373          H5Fclose(fileid) < 0) ERR;
374
375      /* Now open the reference copy of this file and read it. */
376#define REF_FILE_NAME "ref_tst_h_compounds.h5"
377      if (getenv("srcdir"))
378      {
379         strcpy(file_in, getenv("srcdir"));
380         strcat(file_in, "/");
381         strcat(file_inREF_FILE_NAME);
382      }
383      else
384         strcpy(file_inREF_FILE_NAME);
385
386      if ((fileid = H5Fopen(file_inH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
387      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
388      if ((datasetid = H5Dopen1(grpidOBS_VAR)) < 0) ERR;
389      if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
390      if ((mem_type = H5Tget_native_type(typeidH5T_DIR_DEFAULT)) < 0) ERR;
391      if (H5Tget_class(typeid) != H5T_COMPOUNDERR;
392      if (H5Tget_nmembers(typeid) != 5) ERR;
393
394      /* Read all data. */
395      if (H5Dread(datasetidmem_typeH5S_ALLH5S_ALLH5P_DEFAULTobsdata2_in) < 0) ERR;
396
397      /* Check the data. */
398      for (i = 0; i < DIM6_LENi++)
399      {
400         if (obsdata[i].day != obsdata2_in[i].day || obsdata[i].elev != obsdata2_in[i].elev ||
401             obsdata[i].count != obsdata2_in[i].count || obsdata[i].relhum != obsdata2_in[i].relhum ||
402             obsdata[i].time != obsdata2_in[i].time)
403         {
404            ERR;
405            return 1;
406         }
407      }
408
409      /* Release all resources. */
410      if (H5Dclose(datasetid) < 0 ||
411          H5Tclose(typeid) < 0 ||
412          H5Gclose(grpid) < 0 ||
413          H5Fclose(fileid) < 0) ERR;
414   }
415
416   SUMMARIZE_ERR;
417   printf("*** Checking HDF5 compound variable which contains a compound type...");
418   {
419#define DATASET_NAME "Enterprise"
420      /* This struct will be embeddeded in another. */
421      struct s1
422      {
423            int i1;
424            int i2;
425      };
426      /* StarFleet Human Resources Department has data records for all
427       * employees. */
428      struct hr_rec
429      {
430            int starfleet_id;
431            struct s1 svc_rec;
432            char name[STR_LEN + 1];
433            float max_tempmin_temp; /* temperature range */
434            double percent_transporter_errosion;
435      };
436      struct hr_rec hr_data_out[DIM1_LEN], hr_data_in[DIM1_LEN];
437
438      hid_t fileidgrpidtypeid_innertypeidspaceidarray1_tiddatasetid;
439      hsize_t dims[1];
440      char *dummy;
441      int i;
442
443      /* REALLY initialize the data (even the gaps in the structs). This
444       * is only needed to pass valgrind. */
445      if (!(dummy = calloc(sizeof(struct hr_rec), DIM1_LEN))) ERR;
446      memcpy((void *)hr_data_out, (void *)dummy, sizeof(struct hr_rec) * DIM1_LEN);
447      free(dummy);
448
449      /* Create some phony data. */
450      for (i = 0; i < DIM1_LENi++)
451      {
452         hr_data_out[i].starfleet_id = i;
453         hr_data_out[i].svc_rec.i1 = 95;
454         hr_data_out[i].svc_rec.i2 = 90;
455         if (sprintf(hr_data_out[i].name, "alien_%d", i) < 0) ERR;
456         hr_data_out[i].max_temp = 99.99;
457         hr_data_out[i].min_temp = -9.99;
458         hr_data_out[i].percent_transporter_errosion = .1;
459      }
460
461      /* Open file and get root group. */
462      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
463      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
464
465      /* Create a compound type. */
466      if ((typeid_inner = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
467      if (H5Tinsert(typeid_inner, "i1", HOFFSET(struct s1i1), H5T_NATIVE_INT) < 0) ERR;
468      if (H5Tinsert(typeid_inner, "i2", HOFFSET(struct s1i2), H5T_NATIVE_INT) < 0) ERR;
469
470      /* Create a compound type containing a compound type. */
471      if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct hr_rec))) < 0) ERR;
472      if (H5Tinsert(typeid, "starfleet_id", HOFFSET(struct hr_recstarfleet_id), H5T_NATIVE_INT) < 0) ERR;
473      if (H5Tinsert(typeid, "svc_rec", HOFFSET(struct hr_recsvc_rec), typeid_inner) < 0) ERR;
474      if ((array1_tid = H5Tcopy(H5T_C_S1)) < 0) ERR;
475      if (H5Tset_size(array1_tidSTR_LEN + 1) < 0) ERR;
476      if (H5Tinsert(typeid, "name", HOFFSET(struct hr_recname), array1_tid) < 0) ERR;
477      if (H5Tinsert(typeid, "max_temp", HOFFSET(struct hr_recmax_temp), H5T_NATIVE_FLOAT) < 0) ERR;
478      if (H5Tinsert(typeid, "min_temp", HOFFSET(struct hr_recmin_temp), H5T_NATIVE_FLOAT) < 0) ERR;
479      if (H5Tinsert(typeid, "percent_transporter_errosion", HOFFSET(struct hr_recpercent_transporter_errosion),
480                    H5T_NATIVE_DOUBLE) < 0) ERR;
481      if (H5Tcommit(grpid, "hr_rec", typeid) < 0) ERR;
482
483      /* Create a space. */
484      dims[0] = DIM1_LEN;
485      if ((spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
486
487      /* Create a dataset of this compound type. */
488      if ((datasetid = H5Dcreate(grpidDATASET_NAMEtypeidspaceidH5P_DEFAULT)) < 0) ERR;
489
490      /* Write some data. */
491      if (H5Dwrite(datasetidtypeidH5S_ALLH5S_ALLH5P_DEFAULThr_data_out) < 0) ERR;
492
493      /* Release all resources. */
494      if (H5Dclose(datasetid) < 0 ||
495          H5Tclose(array1_tid) < 0 ||
496          H5Tclose(typeid) < 0 ||
497          H5Tclose(typeid_inner) < 0 ||
498          H5Sclose(spaceid) < 0 ||
499          H5Gclose(grpid) < 0 ||
500          H5Fclose(fileid) < 0) ERR;
501
502      /* Now open the file and read it. */
503      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
504      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
505      if ((datasetid = H5Dopen1(grpidDATASET_NAME)) < 0) ERR;
506      if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
507      if (H5Tget_class(typeid) != H5T_COMPOUNDERR;
508      if (H5Dread(datasetidtypeidH5S_ALLH5S_ALLH5P_DEFAULThr_data_in) < 0) ERR;
509
510      /* Check the data. */
511      for (i = 0; i < DIM1_LENi++)
512         if (hr_data_out[i].starfleet_id != hr_data_in[i].starfleet_id ||
513             hr_data_out[i].svc_rec.i1 != hr_data_in[i].svc_rec.i1 ||
514             hr_data_out[i].svc_rec.i2 != hr_data_in[i].svc_rec.i2 ||
515             strcmp(hr_data_out[i].namehr_data_in[i].name) ||
516             hr_data_out[i].max_temp != hr_data_in[i].max_temp ||
517             hr_data_out[i].min_temp != hr_data_in[i].min_temp ||
518             hr_data_out[i].percent_transporter_errosion != hr_data_in[i].percent_transporter_errosion)
519            ERR;
520
521      /* Release all resources. */
522      if (H5Dclose(datasetid) < 0 ||
523          H5Tclose(typeid) < 0 ||
524          H5Gclose(grpid) < 0 ||
525          H5Fclose(fileid) < 0) ERR;
526   }
527
528   SUMMARIZE_ERR;
529   printf("*** Checking HDF5 variable which contains a compound type with different string handling...");
530   {
531#define DATASET_NAME "Enterprise"
532      /* This struct will be embeddeded in another. */
533      struct s1
534      {
535            int i1;
536            int i2;
537      };
538      /* StarFleet Human Resources Department has data records for all
539       * employees. */
540      struct hr_rec
541      {
542            int starfleet_id;
543            struct s1 svc_rec;
544            char name[STR_LEN + 1];
545            float max_tempmin_temp; /* temperature range */
546            double percent_transporter_errosion;
547      };
548      struct hr_rec hr_data_out[DIM1_LEN], hr_data_in[DIM1_LEN];
549
550      hid_t fileidgrpidtypeid_innertypeidspaceidarray1_tiddatasetidstr_tid;
551      hsize_t dims[1];
552      int i;
553
554      /* Create some phony data. */
555      for (i = 0; i < DIM1_LENi++)
556      {
557         hr_data_out[i].starfleet_id = i;
558         hr_data_out[i].svc_rec.i1 = 95;
559         hr_data_out[i].svc_rec.i2 = 90;
560         if (sprintf(hr_data_out[i].name, "alien_%d", i) < 0) ERR;
561         hr_data_out[i].max_temp = 99.99;
562         hr_data_out[i].min_temp = -9.99;
563         hr_data_out[i].percent_transporter_errosion = .1;
564      }
565
566      /* Open file and get root group. */
567      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
568      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
569
570      /* Create a compound type. */
571      if ((typeid_inner = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
572      if (H5Tinsert(typeid_inner, "i1", HOFFSET(struct s1i1), H5T_NATIVE_INT) < 0) ERR;
573      if (H5Tinsert(typeid_inner, "i2", HOFFSET(struct s1i2), H5T_NATIVE_INT) < 0) ERR;
574
575      /* Create a compound type containing a compound type. */
576      if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct hr_rec))) < 0) ERR;
577      if (H5Tinsert(typeid, "starfleet_id", HOFFSET(struct hr_recstarfleet_id), H5T_NATIVE_INT) < 0) ERR;
578      if (H5Tinsert(typeid, "svc_rec", HOFFSET(struct hr_recsvc_rec), typeid_inner) < 0) ERR;
579      dims[0] = STR_LEN + 1;
580      if ((str_tid = H5Tcopy(H5T_C_S1)) < 0) ERR;
581      if (H5Tset_strpad(str_tidH5T_STR_NULLTERM) < 0) ERR;
582      if ((array1_tid = H5Tarray_create2(str_tid, 1, dims)) < 0) ERR;
583      if (H5Tinsert(typeid, "name", HOFFSET(struct hr_recname), array1_tid) < 0) ERR;
584      if (H5Tinsert(typeid, "max_temp", HOFFSET(struct hr_recmax_temp), H5T_NATIVE_FLOAT) < 0) ERR;
585      if (H5Tinsert(typeid, "min_temp", HOFFSET(struct hr_recmin_temp), H5T_NATIVE_FLOAT) < 0) ERR;
586      if (H5Tinsert(typeid, "percent_transporter_errosion", HOFFSET(struct hr_recpercent_transporter_errosion),
587                    H5T_NATIVE_DOUBLE) < 0) ERR;
588      if (H5Tcommit(grpid, "hr_rec", typeid) < 0) ERR;
589
590      /* Create a space. */
591      dims[0] = DIM1_LEN;
592      if ((spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
593
594      /* Create a dataset of this compound type. */
595      if ((datasetid = H5Dcreate(grpidDATASET_NAMEtypeidspaceidH5P_DEFAULT)) < 0) ERR;
596
597      /* Write some data. */
598      if (H5Dwrite(datasetidtypeidH5S_ALLH5S_ALLH5P_DEFAULThr_data_out) < 0) ERR;
599
600      /* Release all resources. */
601      if (H5Dclose(datasetid) < 0 ||
602          H5Tclose(array1_tid) < 0 ||
603          H5Tclose(typeid) < 0 ||
604          H5Tclose(typeid_inner) < 0 ||
605          H5Tclose(str_tid) < 0 ||
606          H5Sclose(spaceid) < 0 ||
607          H5Gclose(grpid) < 0 ||
608          H5Fclose(fileid) < 0) ERR;
609
610      /* Now open the file and read it. */
611      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
612      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
613      if ((datasetid = H5Dopen1(grpidDATASET_NAME)) < 0) ERR;
614      if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
615      if (H5Tget_class(typeid) != H5T_COMPOUNDERR;
616      if (H5Dread(datasetidtypeidH5S_ALLH5S_ALLH5P_DEFAULThr_data_in) < 0) ERR;
617
618      /* Check the data. */
619      for (i = 0; i < DIM1_LENi++)
620         if (hr_data_out[i].starfleet_id != hr_data_in[i].starfleet_id ||
621             hr_data_out[i].svc_rec.i1 != hr_data_in[i].svc_rec.i1 ||
622             hr_data_out[i].svc_rec.i2 != hr_data_in[i].svc_rec.i2 ||
623             strcmp(hr_data_out[i].namehr_data_in[i].name) ||
624             hr_data_out[i].max_temp != hr_data_in[i].max_temp ||
625             hr_data_out[i].min_temp != hr_data_in[i].min_temp ||
626             hr_data_out[i].percent_transporter_errosion != hr_data_in[i].percent_transporter_errosion)
627            ERR;
628
629      /* Release all resources. */
630      if (H5Dclose(datasetid) < 0 ||
631          H5Tclose(typeid) < 0 ||
632          H5Gclose(grpid) < 0 ||
633          H5Fclose(fileid) < 0) ERR;
634   }
635
636   SUMMARIZE_ERR;
637   printf("*** Checking HDF5 compound attribute which contains a compound type...");
638   {
639#define ATT_NAME1 "Space_Station_Regula_One"
640      /* This struct will be embeddeded in another. */
641      struct s1
642      {
643            int i1;
644            int i2;
645      };
646      /* StarFleet Human Resources Department has data records for all
647       * employees. */
648      struct hr_rec
649      {
650            int starfleet_id;
651            struct s1 svc_rec;
652            char name[STR_LEN + 1];
653            float max_tempmin_temp; /* temperature range */
654            double percent_transporter_errosion;
655      };
656      struct hr_rec hr_data_out[DIM1_LEN], hr_data_in[DIM1_LEN];
657
658      hid_t fileidgrpidtypeid_innertypeidspaceidarray1_tidattidnative_typeid;
659      hsize_t dims[1];
660      int i;
661
662      /* Create some phony data. */
663      for (i = 0; i < DIM1_LENi++)
664      {
665         hr_data_out[i].starfleet_id = i;
666         hr_data_out[i].svc_rec.i1 = 95;
667         hr_data_out[i].svc_rec.i2 = 90;
668         if (sprintf(hr_data_out[i].name, "alien_%d", i) < 0) ERR;
669         hr_data_out[i].max_temp = 99.99;
670         hr_data_out[i].min_temp = -9.99;
671         hr_data_out[i].percent_transporter_errosion = .1;
672      }
673
674      /* Open file and get root group. */
675      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
676      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
677
678      /* Create a compound type. */
679      if ((typeid_inner = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
680      if (H5Tinsert(typeid_inner, "i1", HOFFSET(struct s1i1), H5T_NATIVE_INT) < 0) ERR;
681      if (H5Tinsert(typeid_inner, "i2", HOFFSET(struct s1i2), H5T_NATIVE_INT) < 0) ERR;
682
683      /* Create a compound type containing a compound type. */
684      if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct hr_rec))) < 0) ERR;
685      if (H5Tinsert(typeid, "starfleet_id", HOFFSET(struct hr_recstarfleet_id), H5T_NATIVE_INT) < 0) ERR;
686      if (H5Tinsert(typeid, "svc_rec", HOFFSET(struct hr_recsvc_rec), typeid_inner) < 0) ERR;
687      if ((array1_tid = H5Tcopy(H5T_C_S1)) < 0) ERR;
688      if (H5Tset_size(array1_tidSTR_LEN + 1) < 0) ERR;
689      if (H5Tinsert(typeid, "name", HOFFSET(struct hr_recname), array1_tid) < 0) ERR;
690      if (H5Tinsert(typeid, "max_temp", HOFFSET(struct hr_recmax_temp), H5T_NATIVE_FLOAT) < 0) ERR;
691      if (H5Tinsert(typeid, "min_temp", HOFFSET(struct hr_recmin_temp), H5T_NATIVE_FLOAT) < 0) ERR;
692      if (H5Tinsert(typeid, "percent_transporter_errosion", HOFFSET(struct hr_recpercent_transporter_errosion),
693                    H5T_NATIVE_DOUBLE) < 0) ERR;
694      if (H5Tcommit(grpid, "hr_rec", typeid) < 0) ERR;
695
696      /* Create a space. */
697      dims[0] = DIM1_LEN;
698      if ((spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
699
700      /* Create an attribute of this compound type. */
701      if ((attid = H5Acreate2(grpidATT_NAME1typeidspaceidH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
702
703      /* Write some data to the attribute. */
704      if (H5Awrite(attidtypeidhr_data_out) < 0) ERR;
705
706      /* Release all resources. */
707      if (H5Aclose(attid) < 0 ||
708          H5Tclose(typeid) < 0 ||
709          H5Tclose(typeid_inner) < 0 ||
710          H5Sclose(spaceid) < 0 ||
711          H5Gclose(grpid) < 0 ||
712          H5Fclose(fileid) < 0) ERR;
713
714      /* Now open the file and read it. */
715      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
716      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
717      if ((attid = H5Aopen_by_name(grpid, ".", ATT_NAME1H5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
718      if ((typeid = H5Aget_type(attid)) < 0) ERR;
719      if ((native_typeid = H5Tget_native_type(typeidH5T_DIR_DEFAULT)) < 0) ERR;
720      if (H5Aread(attidnative_typeidhr_data_in) < 0) ERR;
721
722      /* Check the data. */
723      for (i = 0; i < DIM1_LENi++)
724         if (hr_data_out[i].starfleet_id != hr_data_in[i].starfleet_id ||
725             hr_data_out[i].svc_rec.i1 != hr_data_in[i].svc_rec.i1 ||
726             hr_data_out[i].svc_rec.i2 != hr_data_in[i].svc_rec.i2 ||
727             strcmp(hr_data_out[i].namehr_data_in[i].name) ||
728             hr_data_out[i].max_temp != hr_data_in[i].max_temp ||
729             hr_data_out[i].min_temp != hr_data_in[i].min_temp ||
730             hr_data_out[i].percent_transporter_errosion != hr_data_in[i].percent_transporter_errosion)
731            ERR;
732
733      /* Release all resources. */
734      if (H5Aclose(attid) < 0 ||
735          H5Tclose(typeid) < 0 ||
736          H5Gclose(grpid) < 0 ||
737          H5Fclose(fileid) < 0) ERR;
738
739   }
740
741   SUMMARIZE_ERR;
742   printf("*** Checking HDF5 variable of compound type which contains a string...");
743   {
744#define DATASET_NAME "Enterprise"
745      struct hr_rec
746      {
747            char name[STR_LEN + 1];
748            float max_temp;
749      };
750      struct hr_rec hr_data_out[DIM1_LEN], hr_data_in[DIM1_LEN];
751
752      hid_t fileidgrpidtypeidspaceidarray1_tiddatasetidstr_tid;
753      hsize_t dims[1] = {STR_LEN + 1};
754      int i;
755
756      /* Create some phony data. */
757      for (i = 0; i < DIM1_LENi++)
758      {
759         if (sprintf(hr_data_out[i].name, "alien_%d", i) < 0) ERR;
760         hr_data_out[i].max_temp = 99.99;
761      }
762
763      /* Open file and get root group. */
764      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
765      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
766
767      /* Create a compound type. */
768      if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct hr_rec))) < 0) ERR;
769/*      printf("sizeof(struct hr_rec)=%d dims[0]=%d\n", sizeof(struct hr_rec), dims[0]);*/
770      if ((str_tid = H5Tcopy(H5T_C_S1)) < 0) ERR;
771      if (H5Tset_strpad(str_tidH5T_STR_NULLTERM) < 0) ERR;
772      if ((array1_tid = H5Tarray_create2(str_tid, 1, dims)) < 0) ERR;
773/*      printf("sizeof(struct hr_rec)=%d HOFFSET(struct hr_rec, name) = %d HOFFSET(struct hr_rec, max_temp) = %d\n",
774        sizeof(struct hr_rec), HOFFSET(struct hr_rec, name), HOFFSET(struct hr_rec, max_temp));*/
775      if (H5Tinsert(typeid, "name", HOFFSET(struct hr_recname), array1_tid) < 0) ERR;
776      if (H5Tinsert(typeid, "max_temp", HOFFSET(struct hr_recmax_temp), H5T_NATIVE_FLOAT) < 0) ERR;
777      if (H5Tcommit(grpid, "hr_rec", typeid) < 0) ERR;
778
779      /* Create a space. */
780      dims[0] = DIM1_LEN;
781      if ((spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
782
783      /* Create a dataset of this compound type. */
784      if ((datasetid = H5Dcreate(grpidDATASET_NAMEtypeidspaceidH5P_DEFAULT)) < 0) ERR;
785
786      /* Write some data. */
787      if (H5Dwrite(datasetidtypeidH5S_ALLH5S_ALLH5P_DEFAULThr_data_out) < 0) ERR;
788
789      /* Release all resources. */
790      if (H5Dclose(datasetid) < 0 ||
791          H5Tclose(array1_tid) < 0 ||
792          H5Tclose(typeid) < 0 ||
793          H5Tclose(str_tid) < 0 ||
794          H5Sclose(spaceid) < 0 ||
795          H5Gclose(grpid) < 0 ||
796          H5Fclose(fileid) < 0) ERR;
797
798      /* Now open the file and read it. */
799      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
800      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
801      if ((datasetid = H5Dopen1(grpidDATASET_NAME)) < 0) ERR;
802      if ((typeid = H5Dget_type(datasetid)) < 0) ERR;
803      if (H5Tget_class(typeid) != H5T_COMPOUNDERR;
804      if (H5Dread(datasetidtypeidH5S_ALLH5S_ALLH5P_DEFAULThr_data_in) < 0) ERR;
805
806      /* Check the data. */
807      for (i = 0; i < DIM1_LENi++)
808         if (strcmp(hr_data_out[i].namehr_data_in[i].name) ||
809             hr_data_out[i].max_temp != hr_data_in[i].max_tempERR;
810
811      /* Release all resources. */
812      if (H5Dclose(datasetid) < 0 ||
813          H5Tclose(typeid) < 0 ||
814          H5Gclose(grpid) < 0 ||
815          H5Fclose(fileid) < 0) ERR;
816   }
817
818   SUMMARIZE_ERR;
819   printf("*** Checking HDF5 compound attribute which contains an array of char...");
820   {
821#define DIM2_LEN 1
822#define ATT_NAME "HR_Records"
823      struct hr_rec
824      {
825            char name[STR_LEN + 1];
826            float max_temp;
827      };
828      struct hr_rec hr_data_out[DIM2_LEN], hr_data_in[DIM2_LEN];
829
830      hid_t fileidgrpidtypeidspaceidarray1_tidattidstr_tid;
831      hsize_t dims[1] = {STR_LEN + 1};
832      char *dummy;
833      int i;
834
835      /* REALLY initialize the data (even the gaps in the structs). This
836       * is only needed to pass valgrind. */
837      if (!(dummy = calloc(sizeof(struct hr_rec), DIM2_LEN))) ERR;
838      memcpy((void *)hr_data_out, (void *)dummy, sizeof(struct hr_rec) * DIM2_LEN);
839      free(dummy);
840
841      /* Create some phony data. */
842      for (i = 0; i < DIM2_LENi++)
843      {
844         if (sprintf(hr_data_out[i].name, "alien_%d", i) < 0) ERR;
845         hr_data_out[i].max_temp = 99.99;
846      }
847
848      /* Open file and get root group. */
849      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
850      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
851
852      /* Create a compound type. */
853      if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct hr_rec))) < 0) ERR;
854      if ((str_tid = H5Tcopy(H5T_C_S1)) < 0) ERR;
855      if (H5Tset_strpad(str_tidH5T_STR_NULLTERM) < 0) ERR;
856      if ((array1_tid = H5Tarray_create2(str_tid, 1, dims)) < 0) ERR;
857/*      printf("sizeof(struct hr_rec)=%d HOFFSET(struct hr_rec, name) = %d HOFFSET(struct hr_rec, max_temp) = %d\n",
858        sizeof(struct hr_rec), HOFFSET(struct hr_rec, name), HOFFSET(struct hr_rec, max_temp));*/
859      if (H5Tinsert(typeid, "Name", HOFFSET(struct hr_recname), array1_tid) < 0) ERR;
860      if (H5Tinsert(typeid, "Max_Temp", HOFFSET(struct hr_recmax_temp), H5T_NATIVE_FLOAT) < 0) ERR;
861      if (H5Tcommit(grpid, "SF_HR_Record", typeid) < 0) ERR;
862
863      /* Create a space. */
864      dims[0] = DIM2_LEN;
865      if ((spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
866
867      /* Create an attribute of this compound type. */
868      if ((attid = H5Acreate2(grpidATT_NAMEtypeidspaceidH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
869
870      /* Write some data. */
871      if (H5Awrite(attidtypeidhr_data_out) < 0) ERR;
872
873      /* Release all resources. */
874      if (H5Aclose(attid) < 0 ||
875          H5Tclose(array1_tid) < 0 ||
876          H5Tclose(typeid) < 0 ||
877          H5Tclose(str_tid) < 0 ||
878          H5Sclose(spaceid) < 0 ||
879          H5Gclose(grpid) < 0 ||
880          H5Fclose(fileid) < 0) ERR;
881
882      /* Now open the file and read it. */
883      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
884      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
885      if ((attid = H5Aopen_by_name(grpid, ".", ATT_NAMEH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
886      if ((typeid = H5Aget_type(attid)) < 0) ERR;
887      if (H5Tget_class(typeid) != H5T_COMPOUNDERR;
888      if (H5Aread(attidtypeidhr_data_in) < 0) ERR;
889
890      /* Check the data. */
891      for (i = 0; i < DIM2_LENi++)
892         if (strcmp(hr_data_out[i].namehr_data_in[i].name) ||
893             hr_data_out[i].max_temp != hr_data_in[i].max_tempERR;
894
895      /* Release all resources. */
896      if (H5Aclose(attid) < 0 ||
897          H5Tclose(typeid) < 0 ||
898          H5Gclose(grpid) < 0 ||
899          H5Fclose(fileid) < 0) ERR;
900   }
901
902   SUMMARIZE_ERR;
903   printf("*** Checking HDF5 compound attribute which contains an array of unsigned byte...");
904   {
905#define DISC_DIM1_LEN 2
906#define DISC_ATT_NAME "Discovery"
907      struct s1
908      {
909     unsigned char x[STR_LEN + 1];
910     float y;
911      };
912      struct s1 data_out[DISC_DIM1_LEN], data_in[DISC_DIM1_LEN];
913
914      hid_t fileidgrpidtypeidspaceidarray1_tidattid;
915      hid_t fcpl_idfapl_id;
916      hsize_t dims[1] = {STR_LEN + 1};
917      int ij;
918
919      /* Create some data. */
920      for (i = 0; i < DISC_DIM1_LENi++)
921      {
922  for (j = 0; j < STR_LEN + 1; j++)
923     data_out[i].x[j] = 4;
924  data_out[i].y = 99.99;
925      }
926
927      /* Set latest_format in access propertly list and
928       * H5P_CRT_ORDER_TRACKED in the creation property list. This
929       * turns on HDF5 creation ordering. */
930      if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
931      if (H5Pset_fclose_degree(fapl_idH5F_CLOSE_STRONG)) ERR;
932      if (H5Pset_libver_bounds(fapl_idH5F_LIBVER_LATESTH5F_LIBVER_LATEST) < 0) ERR;
933      if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
934      if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
935        H5P_CRT_ORDER_INDEXED)) < 0) ERR;
936      if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
937        H5P_CRT_ORDER_INDEXED)) < 0) ERR;
938
939      /* Open file and get root group. */
940      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCfcpl_idfapl_id)) < 0) ERR;
941      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
942
943      /* Create a compound type. */
944      if ((typeid = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
945      if ((array1_tid = H5Tarray_create2(H5T_NATIVE_UCHAR, 1, dims)) < 0) ERR;
946      if (H5Tinsert(typeid, "x", HOFFSET(struct s1x), array1_tid) < 0) ERR;
947      if (H5Tinsert(typeid, "y", HOFFSET(struct s1y), H5T_NATIVE_FLOAT) < 0) ERR;
948      if (H5Tcommit(grpid, "c", typeid) < 0) ERR;
949
950      /* Create a space. */
951      dims[0] = DISC_DIM1_LEN;
952      if ((spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
953
954      /* Create an attribute of this compound type. */
955      if ((attid = H5Acreate2(grpidDISC_ATT_NAMEtypeidspaceidH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
956
957      /* Write some data. */
958      if (H5Awrite(attidtypeiddata_out) < 0) ERR;
959
960      /* Release all resources. */
961      if (H5Aclose(attid) < 0 ||
962   H5Tclose(array1_tid) < 0 ||
963   H5Tclose(typeid) < 0 ||
964   H5Sclose(spaceid) < 0 ||
965   H5Gclose(grpid) < 0 ||
966   H5Fclose(fileid) < 0) ERR;
967
968      /* Now open the file and read it. */
969      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
970      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
971      if ((attid = H5Aopen_by_name(grpid, ".", DISC_ATT_NAMEH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
972      if ((typeid = H5Aget_type(attid)) < 0) ERR;
973      if (H5Tget_class(typeid) != H5T_COMPOUNDERR;
974      if (H5Aread(attidtypeiddata_in) < 0) ERR;
975
976      /* Check the data. */
977      for (i = 0; i < DISC_DIM1_LENi++)
978      {
979  for (j = 0; j < STR_LEN + 1; j++)
980     if (data_in[i].x[j] != data_out[i].x[j]) ERR_RET;
981  if (data_in[i].y != data_out[i].yERR;
982      }
983
984      /* Release all resources. */
985      if (H5Aclose(attid) < 0 ||
986   H5Tclose(typeid) < 0 ||
987   H5Gclose(grpid) < 0 ||
988   H5Fclose(fileid) < 0) ERR;
989   }
990
991   SUMMARIZE_ERR;
992   printf("*** Checking simple read of HDF5 compound attribute which contains a simple compound type...");
993   {
994#define DIM_CMP_LEN 1
995#define ATT_CMP_NAME1 "The_Nutmeg_of_Consolation"
996#define NUM_TYPES 2
997#define INNER_TYPE_NAME "s1"
998#define OUTER_TYPE_NAME "d"
999
1000      /* This struct will be embeddeded in another. */
1001      struct s1
1002      {
1003            float x;
1004            double y;
1005      };
1006      struct s2
1007      {
1008            struct s1 s1;
1009      };
1010      struct s2 data_out[DIM_CMP_LEN], data_in[DIM_CMP_LEN];
1011      hid_t fileidgrpidtypeid_innertypeid_outerspaceidattid;
1012      hid_t att_typeidatt_native_typeid;
1013      hsize_t dims[1];
1014      hid_t fapl_idfcpl_id;
1015      char *dummy;
1016      int i;
1017
1018      /* REALLY initialize the data (even the gaps in the structs). This
1019       * is only needed to pass valgrind. */
1020      if (!(dummy = calloc(sizeof(struct s2), DIM_CMP_LEN))) ERR;
1021      memcpy((void *)data_out, (void *)dummy, sizeof(struct s2) * DIM_CMP_LEN);
1022      free(dummy);
1023
1024      /* Create some phony data. */
1025      for (i = 0; i < DIM_CMP_LENi++)
1026      {
1027         data_out[i].s1.x = 1.0;
1028         data_out[i].s1.y = -2.0;
1029      }
1030
1031      /* Create file access and create property lists. */
1032      if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
1033      if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
1034      if (H5Pset_libver_bounds(fapl_idH5F_LIBVER_LATESTH5F_LIBVER_LATEST) < 0) ERR;
1035      if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
1036        H5P_CRT_ORDER_INDEXED)) < 0) ERR;
1037      if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
1038        H5P_CRT_ORDER_INDEXED)) < 0) ERR;
1039
1040      /* Create file and get root group. */
1041      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCfcpl_idfapl_id)) < 0) ERR;
1042      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
1043
1044      /* Create the inner compound type. */
1045      if ((typeid_inner = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
1046      if (H5Tinsert(typeid_inner, "x", HOFFSET(struct s1x), H5T_NATIVE_FLOAT) < 0) ERR;
1047      if (H5Tinsert(typeid_inner, "y", HOFFSET(struct s1y), H5T_NATIVE_DOUBLE) < 0) ERR;
1048      if (H5Tcommit(grpidINNER_TYPE_NAMEtypeid_inner) < 0) ERR;
1049
1050      /* Create a compound type containing a compound type. */
1051      if ((typeid_outer = H5Tcreate(H5T_COMPOUND, sizeof(struct s2))) < 0) ERR;
1052      if (H5Tinsert(typeid_outerINNER_TYPE_NAMEHOFFSET(struct s2s1), typeid_inner) < 0) ERR;
1053      if (H5Tcommit(grpidOUTER_TYPE_NAMEtypeid_outer) < 0) ERR;
1054
1055      /* Create a space. */
1056      dims[0] = DIM_CMP_LEN;
1057      if ((spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
1058
1059      /* Create an attribute of this compound type. */
1060      if ((attid = H5Acreate2(grpidATT_CMP_NAME1typeid_outerspaceidH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
1061
1062      /* Write some data to the attribute. */
1063      if (H5Awrite(attidtypeid_outerdata_out) < 0) ERR;
1064
1065      /* Release all resources. */
1066      if (H5Aclose(attid) < 0 ||
1067          H5Tclose(typeid_outer) < 0 ||
1068          H5Tclose(typeid_inner) < 0 ||
1069          H5Sclose(spaceid) < 0 ||
1070          H5Gclose(grpid) < 0 ||
1071          H5Fclose(fileid) < 0) ERR;
1072
1073      /* Now open the file and get the type of the attribute. */
1074      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
1075      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
1076      if ((attid = H5Aopen_by_name(grpid, ".", ATT_CMP_NAME1H5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
1077      if ((att_typeid = H5Aget_type(attid)) < 0) ERR;
1078      if ((att_native_typeid = H5Tget_native_type(att_typeidH5T_DIR_DEFAULT)) < 0) ERR;
1079
1080      /* Check the data. */
1081      if (H5Aread(attidatt_native_typeiddata_in) < 0) ERR;
1082      for (i = 0; i < DIM_CMP_LENi++)
1083         if (data_out[i].s1.x != data_in[i].s1.x ||
1084             data_out[i].s1.y != data_in[i].s1.yERR;
1085
1086      /* Release all resources. */
1087      if (H5Aclose(attid) < 0 ||
1088          H5Tclose(att_typeid) < 0 ||
1089          H5Tclose(att_native_typeid) < 0 ||
1090          H5Gclose(grpid) < 0 ||
1091          H5Fclose(fileid) < 0) ERR;
1092
1093   }
1094   SUMMARIZE_ERR;
1095   printf("*** Checking simple read of HDF5 compound attribute which contains a simple compound type...");
1096   {
1097#define DIM_CMP_LEN 1
1098#define ATT_CMP_NAME1 "The_Nutmeg_of_Consolation"
1099#define NUM_TYPES 2
1100#define INNER_TYPE_NAME "s1"
1101#define OUTER_TYPE_NAME "d"
1102
1103      /* This struct will be embeddeded in another. */
1104      struct s1
1105      {
1106            float x;
1107            double y;
1108      };
1109      struct s2
1110      {
1111            struct s1 s1;
1112      };
1113      struct s2 data_out[DIM_CMP_LEN], data_in[DIM_CMP_LEN];
1114      hid_t fileidgrpidtypeid_innertypeid_outerspaceidattid;
1115      hid_t att_typeidatt_native_typeid;
1116      hsize_t dims[1];
1117      hid_t fapl_idfcpl_id;
1118      int i;
1119
1120      /* REALLY initialize the data (even the gaps in the structs). This
1121       * is only needed to pass valgrind. */
1122      if (!(dummy = calloc(sizeof(struct s2), DIM_CMP_LEN))) ERR;
1123      memcpy((void *)data_out, (void *)dummy, sizeof(struct s2) * DIM_CMP_LEN);
1124      free(dummy);
1125
1126      /* Create some phony data. */
1127      for (i = 0; i < DIM_CMP_LENi++)
1128      {
1129         data_out[i].s1.x = 1.0;
1130         data_out[i].s1.y = -2.0;
1131      }
1132
1133      /* Create file access and create property lists. */
1134      if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0) ERR;
1135      if ((fcpl_id = H5Pcreate(H5P_FILE_CREATE)) < 0) ERR;
1136      if (H5Pset_libver_bounds(fapl_idH5F_LIBVER_LATESTH5F_LIBVER_LATEST) < 0) ERR;
1137      if (H5Pset_link_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
1138        H5P_CRT_ORDER_INDEXED)) < 0) ERR;
1139      if (H5Pset_attr_creation_order(fcpl_id, (H5P_CRT_ORDER_TRACKED |
1140        H5P_CRT_ORDER_INDEXED)) < 0) ERR;
1141
1142      /* Create file and get root group. */
1143      if ((fileid = H5Fcreate(FILE_NAMEH5F_ACC_TRUNCfcpl_idfapl_id)) < 0) ERR;
1144      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
1145
1146      /* Create the inner compound type. */
1147      if ((typeid_inner = H5Tcreate(H5T_COMPOUND, sizeof(struct s1))) < 0) ERR;
1148      if (H5Tinsert(typeid_inner, "x", HOFFSET(struct s1x), H5T_NATIVE_FLOAT) < 0) ERR;
1149      if (H5Tinsert(typeid_inner, "y", HOFFSET(struct s1y), H5T_NATIVE_DOUBLE) < 0) ERR;
1150      if (H5Tcommit(grpidINNER_TYPE_NAMEtypeid_inner) < 0) ERR;
1151
1152      /* Create a compound type containing a compound type. */
1153      if ((typeid_outer = H5Tcreate(H5T_COMPOUND, sizeof(struct s2))) < 0) ERR;
1154      if (H5Tinsert(typeid_outerINNER_TYPE_NAMEHOFFSET(struct s2s1), typeid_inner) < 0) ERR;
1155      if (H5Tcommit(grpidOUTER_TYPE_NAMEtypeid_outer) < 0) ERR;
1156
1157      /* Create a space. */
1158      dims[0] = DIM_CMP_LEN;
1159      if ((spaceid = H5Screate_simple(1, dimsdims)) < 0) ERR;
1160
1161      /* Create an attribute of this compound type. */
1162      if ((attid = H5Acreate2(grpidATT_CMP_NAME1typeid_outerspaceidH5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
1163
1164      /* Write some data to the attribute. */
1165      if (H5Awrite(attidtypeid_outerdata_out) < 0) ERR;
1166
1167      /* Release all resources. */
1168      if (H5Aclose(attid) < 0 ||
1169          H5Tclose(typeid_outer) < 0 ||
1170          H5Tclose(typeid_inner) < 0 ||
1171          H5Sclose(spaceid) < 0 ||
1172          H5Gclose(grpid) < 0 ||
1173          H5Fclose(fileid) < 0) ERR;
1174
1175      /* Now open the file and get the type of the attribute. */
1176      if ((fileid = H5Fopen(FILE_NAMEH5F_ACC_RDONLYH5P_DEFAULT)) < 0) ERR;
1177      if ((grpid = H5Gopen(fileid, "/")) < 0) ERR;
1178      if ((attid = H5Aopen_by_name(grpid, ".", ATT_CMP_NAME1H5P_DEFAULTH5P_DEFAULT)) < 0) ERR;
1179      if ((att_typeid = H5Aget_type(attid)) < 0) ERR;
1180      if ((att_native_typeid = H5Tget_native_type(att_typeidH5T_DIR_DEFAULT)) < 0) ERR;
1181
1182      /* Check the data. */
1183      if (H5Aread(attidatt_native_typeiddata_in) < 0) ERR;
1184      for (i = 0; i < DIM_CMP_LENi++)
1185         if (data_out[i].s1.x != data_in[i].s1.x ||
1186             data_out[i].s1.y != data_in[i].s1.yERR;
1187
1188      /* Release all resources. */
1189      if (H5Aclose(attid) < 0 ||
1190          H5Tclose(att_typeid) < 0 ||
1191          H5Tclose(att_native_typeid) < 0 ||
1192          H5Gclose(grpid) < 0 ||
1193          H5Fclose(fileid) < 0) ERR;
1194
1195   }
1196   SUMMARIZE_ERR;
1197   FINAL_RESULTS;
1198}


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed