1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /***********************************************************
15 *
16 * Test program:	 th5o
17 *
18 * Test public H5O functions for accessing
19 *
20 *************************************************************/
21 
22 #include "testhdf5.h"
23 
24 #define TEST_FILENAME "th5o_file"
25 
26 #define RANK 2
27 #define DIM0 5
28 #define DIM1 10
29 
30 #define TEST6_DIM1 100
31 #define TEST6_DIM2 100
32 
33 
34 /****************************************************************
35 **
36 **  test_h5o_open(): Test H5Oopen function.
37 **
38 ****************************************************************/
39 static void
test_h5o_open(void)40 test_h5o_open(void)
41 {
42     hid_t       fid;                        /* HDF5 File ID      */
43     hid_t       grp, dset, dtype, dspace;   /* Object identifiers */
44     hsize_t     dims[RANK];
45     H5I_type_t  id_type;                    /* Type of IDs returned from H5Oopen */
46     H5G_info_t  ginfo;                      /* Group info struct */
47     H5T_class_t type_class;                 /* Class of the datatype */
48     herr_t      ret;                        /* Value returned from API calls */
49 
50     /* Create a new HDF5 file */
51     fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
52     CHECK(fid, FAIL, "H5Fcreate");
53 
54     /* Create a group, dataset, and committed datatype within the file */
55     /* Create the group */
56     grp = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
57     CHECK(grp, FAIL, "H5Gcreate2");
58     ret = H5Gclose(grp);
59     CHECK(ret, FAIL, "H5Gclose");
60 
61     /* Commit the type inside the group */
62     dtype = H5Tcopy(H5T_NATIVE_INT);
63     CHECK(dtype, FAIL, "H5Tcopy");
64     ret = H5Tcommit2(fid, "group/datatype", dtype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
65     CHECK(ret, FAIL, "H5Tcommit2");
66     ret = H5Tclose(dtype);
67     CHECK(ret, FAIL, "H5Tclose");
68 
69     /* Create the data space for the dataset. */
70     dims[0] = DIM0;
71     dims[1] = DIM1;
72     dspace = H5Screate_simple(RANK, dims, NULL);
73     CHECK(dspace, FAIL, "H5Screate_simple");
74 
75     /* Create the dataset. */
76     dset = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
77     CHECK(dset, FAIL, "H5Dcreate2");
78     ret = H5Dclose(dset);
79     CHECK(ret, FAIL, "H5Dclose");
80     ret = H5Sclose(dspace);
81     CHECK(ret, FAIL, "H5Sclose");
82 
83     /* Now make sure that H5Oopen can open all three types of objects */
84     grp = H5Oopen(fid, "group", H5P_DEFAULT);
85     CHECK(grp, FAIL, "H5Oopen");
86     dtype = H5Oopen(fid, "group/datatype", H5P_DEFAULT);
87     CHECK(dtype, FAIL, "H5Oopen");
88     /* Check that we can use the group as a valid location */
89     dset = H5Oopen(grp, "/dataset", H5P_DEFAULT);
90     CHECK(dset, FAIL, "H5Oopen");
91 
92     /* Make sure that each is the right kind of ID */
93     id_type = H5Iget_type(grp);
94     VERIFY(id_type, H5I_GROUP, "H5Iget_type for group ID");
95     id_type = H5Iget_type(dtype);
96     VERIFY(id_type, H5I_DATATYPE, "H5Iget_type for datatype ID");
97     id_type = H5Iget_type(dset);
98     VERIFY(id_type, H5I_DATASET, "H5Iget_type for dataset ID");
99 
100     /* Do something more complex with each of the IDs to make sure they "work" */
101     ret = H5Gget_info(grp, &ginfo);
102     CHECK(ret, FAIL, "H5Gget_info");
103     VERIFY(ginfo.nlinks, 1, "H5Gget_info"); /* There should be one object, the datatype */
104 
105     type_class = H5Tget_class(dtype);
106     VERIFY(type_class, H5T_INTEGER, "H5Tget_class");
107 
108     dspace = H5Dget_space(dset);
109     CHECK(dspace, FAIL, "H5Dget_space");
110 
111     /* Close the IDs */
112     ret = H5Sclose(dspace);
113     CHECK(ret, FAIL, "H5Sclose");
114     ret = H5Gclose(grp);
115     CHECK(ret, FAIL, "H5Gclose");
116     ret = H5Tclose(dtype);
117     CHECK(ret, FAIL, "H5Tclose");
118     ret = H5Dclose(dset);
119     CHECK(ret, FAIL, "H5Dclose");
120 
121     /* Trying to open objects with bogus names should fail gracefully */
122     H5E_BEGIN_TRY {
123         grp = H5Oopen(fid, "bogus_group", H5P_DEFAULT);
124         VERIFY(grp, FAIL, "H5Oopen");
125         dtype = H5Oopen(fid, "group/bogus_datatype", H5P_DEFAULT);
126         VERIFY(dtype, FAIL, "H5Oopen");
127         dset = H5Oopen(fid, "/bogus_dataset", H5P_DEFAULT);
128         VERIFY(dset, FAIL, "H5Oopen");
129     } H5E_END_TRY
130 
131     /* Close the file */
132     ret = H5Fclose(fid);
133     CHECK(ret, FAIL, "H5Fclose");
134 
135     /* Trying to open an object with a bogus file ID should fail */
136     H5E_BEGIN_TRY {
137         dset = H5Oopen(fid, "dataset", H5P_DEFAULT);
138         VERIFY(dset, FAIL, "H5Oopen");
139     } H5E_END_TRY
140 } /* test_h5o_open() */
141 
142 
143 
144 /****************************************************************
145 **
146 **  test_h5o_close(): Test H5Oclose function.
147 **
148 ****************************************************************/
149 static void
test_h5o_close(void)150 test_h5o_close(void)
151 {
152     hid_t       fid;                        /* HDF5 File ID      */
153     hid_t       grp, dset, dtype, dspace;   /* Object identifiers */
154     hsize_t     dims[RANK];
155     herr_t      ret;                        /* Value returned from API calls */
156 
157     /* Create a new HDF5 file */
158     fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
159     CHECK(fid, FAIL, "H5Fcreate");
160 
161     /* Create a group, dataset, and committed datatype within the file */
162     /* Create the group and close it with H5Oclose */
163     grp = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
164     CHECK(grp, FAIL, "H5Gcreate2");
165     VERIFY(H5Iget_type(grp), H5I_GROUP, "H5Iget_type");
166     ret = H5Oclose(grp);
167     CHECK(ret, FAIL, "H5Oclose");
168 
169     /* Commit the type inside the group */
170     dtype = H5Tcopy(H5T_NATIVE_INT);
171     CHECK(dtype, FAIL, "H5Tcopy");
172     ret = H5Tcommit2(fid, "group/datatype", dtype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
173     CHECK(ret, FAIL, "H5Tcommit2");
174     ret = H5Oclose(dtype);
175     CHECK(ret, FAIL, "H5Oclose");
176 
177     /* Create the data space for the dataset. */
178     dims[0] = DIM0;
179     dims[1] = DIM1;
180     dspace = H5Screate_simple(RANK, dims, NULL);
181     CHECK(dspace, FAIL, "H5Screate_simple");
182 
183     /* Create the dataset. */
184     dset = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
185     CHECK(dset, FAIL, "H5Dcreate2");
186     ret = H5Oclose(dset);
187     CHECK(ret, FAIL, "H5Oclose");
188 
189     /* Attempting to close the data space with H5Oclose should fail */
190     H5E_BEGIN_TRY {
191        ret = H5Oclose(dspace);
192        VERIFY(ret, FAIL, "H5Oclose");
193     } H5E_END_TRY
194     /* Close the dataspace for real */
195     ret = H5Sclose(dspace);
196     CHECK(ret, FAIL, "H5Sclose");
197 
198     /* Make sure that H5Oclose can close objects opened with H5Oopen */
199     grp = H5Oopen(fid, "group", H5P_DEFAULT);
200     CHECK(grp, FAIL, "H5Oopen");
201     dtype = H5Oopen(fid, "group/datatype", H5P_DEFAULT);
202     CHECK(dtype, FAIL, "H5Oopen");
203     dset = H5Oopen(fid, "dataset", H5P_DEFAULT);
204     CHECK(dset, FAIL, "H5Oopen");
205 
206     ret = H5Oclose(grp);
207     CHECK(ret, FAIL, "H5Oclose");
208     ret = H5Oclose(dtype);
209     CHECK(ret, FAIL, "H5Oclose");
210     ret = H5Oclose(dset);
211     CHECK(ret, FAIL, "H5Oclose");
212 
213     /* Make sure H5Oclose can close objects opened with H5*open */
214     grp = H5Gopen2(fid, "group", H5P_DEFAULT);
215     CHECK(grp, FAIL, "H5Gopen2");
216     dtype = H5Topen2(fid, "group/datatype", H5P_DEFAULT);
217     CHECK(dtype, FAIL, "H5Topen2");
218     dset = H5Dopen2(fid, "dataset", H5P_DEFAULT);
219     CHECK(dset, FAIL, "H5Dopen2");
220 
221     ret = H5Oclose(grp);
222     CHECK(ret, FAIL, "H5Oclose");
223     ret = H5Oclose(dtype);
224     CHECK(ret, FAIL, "H5Oclose");
225     ret = H5Oclose(dset);
226     CHECK(ret, FAIL, "H5Oclose");
227 
228     /* Close the file */
229     ret = H5Fclose(fid);
230     CHECK(ret, FAIL, "H5Fclose");
231 }
232 
233 
234 /****************************************************************
235 **
236 **  test_h5o_open_by_addr(): Test H5Oopen_by_addr function.
237 **
238 ****************************************************************/
239 static void
test_h5o_open_by_addr(void)240 test_h5o_open_by_addr(void)
241 {
242     hid_t       fid;                        /* HDF5 File ID      */
243     hid_t       grp, dset, dtype, dspace;   /* Object identifiers */
244     H5L_info_t li;                      /* Buffer for H5Lget_info */
245     haddr_t grp_addr;                       /* Addresses for objects */
246     haddr_t dset_addr;
247     haddr_t dtype_addr;
248     hsize_t     dims[RANK];
249     H5I_type_t  id_type;                    /* Type of IDs returned from H5Oopen */
250     H5G_info_t  ginfo;                      /* Group info struct */
251     H5T_class_t type_class;                 /* Class of the datatype */
252     herr_t      ret;                        /* Value returned from API calls */
253 
254     /* Create a new HDF5 file */
255     fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
256     CHECK(fid, FAIL, "H5Fcreate");
257 
258     /* Create a group, dataset, and committed datatype within the file */
259     /* Create the group */
260     grp = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
261     CHECK(grp, FAIL, "H5Gcreate2");
262     ret = H5Gclose(grp);
263     CHECK(ret, FAIL, "H5Gclose");
264 
265     /* Commit the type inside the group */
266     dtype = H5Tcopy(H5T_NATIVE_INT);
267     CHECK(dtype, FAIL, "H5Tcopy");
268     ret = H5Tcommit2(fid, "group/datatype", dtype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
269     CHECK(ret, FAIL, "H5Tcommit2");
270     ret = H5Tclose(dtype);
271     CHECK(ret, FAIL, "H5Tclose");
272 
273     /* Create the data space for the dataset. */
274     dims[0] = DIM0;
275     dims[1] = DIM1;
276     dspace = H5Screate_simple(RANK, dims, NULL);
277     CHECK(dspace, FAIL, "H5Screate_simple");
278 
279     /* Create the dataset. */
280     dset = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
281     CHECK(dset, FAIL, "H5Dcreate2");
282     ret = H5Dclose(dset);
283     CHECK(ret, FAIL, "H5Dclose");
284     ret = H5Sclose(dspace);
285     CHECK(ret, FAIL, "H5Sclose");
286 
287     /* Get address for each object */
288     ret = H5Lget_info(fid, "group", &li, H5P_DEFAULT);
289     CHECK(ret, FAIL, "H5Lget_info");
290     grp_addr = li.u.address;
291     ret = H5Lget_info(fid, "group/datatype", &li, H5P_DEFAULT);
292     CHECK(ret, FAIL, "H5Lget_info");
293     dtype_addr = li.u.address;
294     ret = H5Lget_info(fid, "dataset", &li, H5P_DEFAULT);
295     CHECK(ret, FAIL, "H5Lget_info");
296     dset_addr = li.u.address;
297 
298     /* Now make sure that H5Oopen_by_addr can open all three types of objects */
299     grp = H5Oopen_by_addr(fid, grp_addr);
300     CHECK(grp, FAIL, "H5Oopen_by_addr");
301     dtype = H5Oopen_by_addr(fid, dtype_addr);
302     CHECK(dtype, FAIL, "H5Oopen_by_addr");
303     /* Check that we can use the group ID as a valid location */
304     dset = H5Oopen_by_addr(grp, dset_addr);
305     CHECK(dset, FAIL, "H5Oopen_by_addr");
306 
307     /* Make sure that each is the right kind of ID */
308     id_type = H5Iget_type(grp);
309     VERIFY(id_type, H5I_GROUP, "H5Iget_type for group ID");
310     id_type = H5Iget_type(dtype);
311     VERIFY(id_type, H5I_DATATYPE, "H5Iget_type for datatype ID");
312     id_type = H5Iget_type(dset);
313     VERIFY(id_type, H5I_DATASET, "H5Iget_type for dataset ID");
314 
315     /* Do something more complex with each of the IDs to make sure they "work" */
316     ret = H5Gget_info(grp, &ginfo);
317     CHECK(ret, FAIL, "H5Gget_info");
318     VERIFY(ginfo.nlinks, 1, "H5Gget_info"); /* There should be one object, the datatype */
319 
320     type_class = H5Tget_class(dtype);
321     VERIFY(type_class, H5T_INTEGER, "H5Tget_class");
322 
323     dspace = H5Dget_space(dset);
324     CHECK(dspace, FAIL, "H5Dget_space");
325 
326     /* Close the IDs */
327     ret = H5Sclose(dspace);
328     CHECK(ret, FAIL, "H5Sclose");
329     ret = H5Gclose(grp);
330     CHECK(ret, FAIL, "H5Gclose");
331     ret = H5Tclose(dtype);
332     CHECK(ret, FAIL, "H5Tclose");
333     ret = H5Dclose(dset);
334     CHECK(ret, FAIL, "H5Dclose");
335 
336     /* Try giving some bogus values to H5O_open_by_addr. */
337     /* Try to open an object with a bad address */
338     grp_addr += 20;
339     H5E_BEGIN_TRY{
340       grp = H5Oopen_by_addr(fid, grp_addr);
341     }H5E_END_TRY
342     VERIFY(grp, FAIL, "H5Oopen_by_addr");
343 
344     /* For instance, an objectno smaller than the end of the file's superblock should
345      * trigger an error */
346     grp_addr = 10;
347     H5E_BEGIN_TRY{
348       grp = H5Oopen_by_addr(fid, grp_addr);
349     }H5E_END_TRY
350     VERIFY(grp, FAIL, "H5Oopen_by_addr");
351 
352     /* Likewise, an objectno larger than the size of the file should fail */
353     grp_addr = 0;
354     grp_addr = 1000000000;
355     H5E_BEGIN_TRY{
356       grp = H5Oopen_by_addr(fid, grp_addr);
357     }H5E_END_TRY
358     VERIFY(grp, FAIL, "H5Oopen_by_addr");
359 
360     ret = H5Fclose(fid);
361     CHECK(ret, FAIL, "H5Fclose");
362 
363     /* Also, trying to open an object without a valid location should fail */
364     H5E_BEGIN_TRY{
365       dtype = H5Oopen_by_addr(fid, dtype_addr);
366     }H5E_END_TRY
367     VERIFY(dtype, FAIL, "H5Oopen_by_addr");
368 } /* test_h5o_open_by_addr() */
369 
370 
371 /****************************************************************
372 **
373 **  test_h5o_refcount(): Test H5O refcounting functions.
374 **
375 ****************************************************************/
376 static void
test_h5o_refcount(void)377 test_h5o_refcount(void)
378 {
379     hid_t       fid;                        /* HDF5 File ID      */
380     hid_t       grp, dset, dtype, dspace;   /* Object identifiers */
381     H5O_info_t	oinfo;                      /* Object info struct */
382     hsize_t     dims[RANK];
383     herr_t      ret;                        /* Value returned from API calls */
384 
385     /* Create a new HDF5 file */
386     fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
387     CHECK(fid, FAIL, "H5Fcreate");
388 
389     /* Create a group, dataset, and committed datatype within the file */
390     /* Create the group */
391     grp = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
392     CHECK(grp, FAIL, "H5Gcreate2");
393 
394     /* Commit the type inside the group */
395     dtype = H5Tcopy(H5T_NATIVE_INT);
396     CHECK(dtype, FAIL, "H5Tcopy");
397     ret = H5Tcommit2(fid, "datatype", dtype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
398     CHECK(ret, FAIL, "H5Tcommit2");
399 
400     /* Create the data space for the dataset. */
401     dims[0] = DIM0;
402     dims[1] = DIM1;
403     dspace = H5Screate_simple(RANK, dims, NULL);
404     CHECK(dspace, FAIL, "H5Screate_simple");
405 
406     /* Create the dataset. */
407     dset = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
408     CHECK(dset, FAIL, "H5Dcreate2");
409     ret = H5Sclose(dspace);
410     CHECK(ret, FAIL, "H5Sclose");
411 
412     /* Get ref counts for each object.  They should all be 1, since each object has a hard link. */
413     ret = H5Oget_info_by_name(fid, "group", &oinfo, H5P_DEFAULT);
414     CHECK(ret, FAIL, "H5Oget_info_by_name");
415     VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name");
416     ret = H5Oget_info_by_name(fid, "datatype", &oinfo, H5P_DEFAULT);
417     CHECK(ret, FAIL, "H5Oget_info_by_name");
418     VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name");
419     ret = H5Oget_info_by_name(fid, "dataset", &oinfo, H5P_DEFAULT);
420     CHECK(ret, FAIL, "H5Oget_info_by_name");
421     VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name");
422 
423     /* Increment each object's reference count. */
424     ret = H5Oincr_refcount(grp);
425     CHECK(ret, FAIL, "H5Oincr_refcount");
426     ret = H5Oincr_refcount(dtype);
427     CHECK(ret, FAIL, "H5Oincr_refcount");
428     ret = H5Oincr_refcount(dset);
429     CHECK(ret, FAIL, "H5Oincr_refcount");
430 
431     /* Get ref counts for each object.  They should all be 2 now. */
432     ret = H5Oget_info_by_name(fid, "group", &oinfo, H5P_DEFAULT);
433     CHECK(ret, FAIL, "H5Oget_info_by_name");
434     VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name");
435     ret = H5Oget_info_by_name(fid, "datatype", &oinfo, H5P_DEFAULT);
436     CHECK(ret, FAIL, "H5Oget_info_by_name");
437     VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name");
438     ret = H5Oget_info_by_name(fid, "dataset", &oinfo, H5P_DEFAULT);
439     CHECK(ret, FAIL, "H5Oget_info_by_name");
440     VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name");
441 
442     /* Decrement the reference counts and check that they decrease back to 1. */
443     ret = H5Odecr_refcount(grp);
444     CHECK(ret, FAIL, "H5Odecr_refcount");
445     ret = H5Odecr_refcount(dtype);
446     CHECK(ret, FAIL, "H5Odecr_refcount");
447     ret = H5Odecr_refcount(dset);
448     CHECK(ret, FAIL, "H5Odecr_refcount");
449 
450     ret = H5Oget_info_by_name(fid, "group", &oinfo, H5P_DEFAULT);
451     CHECK(ret, FAIL, "H5Oget_info_by_name");
452     VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name");
453     ret = H5Oget_info_by_name(fid, "datatype", &oinfo, H5P_DEFAULT);
454     CHECK(ret, FAIL, "H5Oget_info_by_name");
455     VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name");
456     ret = H5Oget_info_by_name(fid, "dataset", &oinfo, H5P_DEFAULT);
457     CHECK(ret, FAIL, "H5Oget_info_by_name");
458     VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name");
459 
460     /* Increment the reference counts and then close the file to make sure the increment is permanant */
461     ret = H5Oincr_refcount(grp);
462     CHECK(ret, FAIL, "H5Oincr_refcount");
463     ret = H5Oincr_refcount(dtype);
464     CHECK(ret, FAIL, "H5Oincr_refcount");
465     ret = H5Oincr_refcount(dset);
466     CHECK(ret, FAIL, "H5Oincr_refcount");
467 
468     ret = H5Gclose(grp);
469     CHECK(ret, FAIL, "H5Gclose");
470     ret = H5Tclose(dtype);
471     CHECK(ret, FAIL, "H5Tclose");
472     ret = H5Dclose(dset);
473     CHECK(ret, FAIL, "H5Dclose");
474     ret = H5Fclose(fid);
475     CHECK(ret, FAIL, "H5Fclose");
476 
477     /* Re-open the file and check that the reference counts were really incremented */
478     fid = H5Fopen(TEST_FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
479     CHECK(fid, FAIL, "H5Fopen");
480 
481     grp = H5Gopen2(fid, "group", H5P_DEFAULT);
482     CHECK(grp, FAIL, "H5Gopen2");
483     dtype = H5Topen2(fid, "datatype", H5P_DEFAULT);
484     CHECK(dtype, FAIL, "H5Topen2");
485     dset = H5Dopen2(fid, "dataset", H5P_DEFAULT);
486     CHECK(dset, FAIL, "H5Dopen2");
487 
488     ret = H5Oget_info_by_name(fid, "group", &oinfo, H5P_DEFAULT);
489     CHECK(ret, FAIL, "H5Oget_info_by_name");
490     VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name");
491     ret = H5Oget_info_by_name(fid, "datatype", &oinfo, H5P_DEFAULT);
492     CHECK(ret, FAIL, "H5Oget_info_by_name");
493     VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name");
494     ret = H5Oget_info_by_name(fid, "dataset", &oinfo, H5P_DEFAULT);
495     CHECK(ret, FAIL, "H5Oget_info_by_name");
496     VERIFY(oinfo.rc, 2, "reference count in H5Oget_info_by_name");
497 
498     /* Decrement the reference counts and close the file */
499     ret = H5Odecr_refcount(grp);
500     CHECK(ret, FAIL, "H5Odecr_refcount");
501     ret = H5Odecr_refcount(dtype);
502     CHECK(ret, FAIL, "H5Odecr_refcount");
503     ret = H5Odecr_refcount(dset);
504     CHECK(ret, FAIL, "H5Odecr_refcount");
505 
506     ret = H5Gclose(grp);
507     CHECK(ret, FAIL, "H5Gclose");
508     ret = H5Tclose(dtype);
509     CHECK(ret, FAIL, "H5Tclose");
510     ret = H5Dclose(dset);
511     CHECK(ret, FAIL, "H5Dclose");
512     ret = H5Fclose(fid);
513     CHECK(ret, FAIL, "H5Fclose");
514 
515     /* Re-open the file and check that the reference counts were really decremented */
516     fid = H5Fopen(TEST_FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
517     CHECK(fid, FAIL, "H5Fopen");
518 
519     grp = H5Gopen2(fid, "group", H5P_DEFAULT);
520     CHECK(grp, FAIL, "H5Gopen2");
521     dtype = H5Topen2(fid, "datatype", H5P_DEFAULT);
522     CHECK(dtype, FAIL, "H5Topen2");
523     dset = H5Dopen2(fid, "dataset", H5P_DEFAULT);
524     CHECK(dset, FAIL, "H5Dopen2");
525 
526     ret = H5Oget_info_by_name(fid, "group", &oinfo, H5P_DEFAULT);
527     CHECK(ret, FAIL, "H5Oget_info_by_name");
528     VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name");
529     ret = H5Oget_info_by_name(fid, "datatype", &oinfo, H5P_DEFAULT);
530     CHECK(ret, FAIL, "H5Oget_info_by_name");
531     VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name");
532     ret = H5Oget_info_by_name(fid, "dataset", &oinfo, H5P_DEFAULT);
533     CHECK(ret, FAIL, "H5Oget_info_by_name");
534     VERIFY(oinfo.rc, 1, "reference count in H5Oget_info_by_name");
535 
536     /* Close the IDs */
537     ret = H5Gclose(grp);
538     CHECK(ret, FAIL, "H5Gclose");
539     ret = H5Tclose(dtype);
540     CHECK(ret, FAIL, "H5Tclose");
541     ret = H5Dclose(dset);
542     CHECK(ret, FAIL, "H5Dclose");
543 
544     /* Make sure that bogus IDs return errors properly */
545     H5E_BEGIN_TRY {
546         ret = H5Oincr_refcount(grp);
547         VERIFY(ret, FAIL, "H5Oincr_refcount");
548         ret = H5Oincr_refcount(dtype);
549         VERIFY(ret, FAIL, "H5Oincr_refcount");
550         ret = H5Oincr_refcount(dset);
551         VERIFY(ret, FAIL, "H5Oincr_refcount");
552         ret = H5Odecr_refcount(grp);
553         VERIFY(ret, FAIL, "H5Odecr_refcount");
554         ret = H5Odecr_refcount(dtype);
555         VERIFY(ret, FAIL, "H5Odecr_refcount");
556         ret = H5Odecr_refcount(dset);
557         VERIFY(ret, FAIL, "H5Odecr_refcount");
558     } H5E_END_TRY
559 
560     /* Close the file */
561     ret = H5Fclose(fid);
562     CHECK(ret, FAIL, "H5Fclose");
563 } /* test_h5o_refcount() */
564 
565 
566 /****************************************************************
567 **
568 **  test_h5o_plist(): Test object creation properties
569 **
570 ****************************************************************/
571 static void
test_h5o_plist(void)572 test_h5o_plist(void)
573 {
574     hid_t       fid;                        /* HDF5 File ID      */
575     hid_t       grp, dset, dtype, dspace;   /* Object identifiers */
576     hid_t       fapl;                       /* File access property list */
577     hid_t       gcpl, dcpl, tcpl;           /* Object creation properties */
578     unsigned    def_max_compact, def_min_dense; /* Default phase change parameters */
579     unsigned    max_compact, min_dense;         /* Actual phase change parameters */
580     herr_t      ret;                        /* Value returned from API calls */
581 
582     /* Make a FAPL that uses the "use the latest version of the format" flag */
583     fapl = H5Pcreate(H5P_FILE_ACCESS);
584     CHECK(fapl, FAIL, "H5Pcreate");
585 
586     /* Set the "use the latest version of the format" bounds for creating objects in the file */
587     ret = H5Pset_libver_bounds(fapl, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST);
588     CHECK(ret, FAIL, "H5Pset_libver_bounds");
589 
590     /* Create a new HDF5 file */
591     fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl);
592     CHECK(fid, FAIL, "H5Fcreate");
593 
594     /* Create group, dataset & named datatype creation property lists */
595     gcpl = H5Pcreate(H5P_GROUP_CREATE);
596     CHECK(gcpl, FAIL, "H5Pcreate");
597     dcpl = H5Pcreate(H5P_DATASET_CREATE);
598     CHECK(dcpl, FAIL, "H5Pcreate");
599     tcpl = H5Pcreate(H5P_DATATYPE_CREATE);
600     CHECK(tcpl, FAIL, "H5Pcreate");
601 
602     /* Retrieve default attribute phase change values */
603     ret = H5Pget_attr_phase_change(gcpl, &def_max_compact, &def_min_dense);
604     CHECK(ret, FAIL, "H5Pget_attr_phase_change");
605 
606     /* Set non-default attribute phase change values on each creation property list */
607     ret = H5Pset_attr_phase_change(gcpl, def_max_compact + 1, def_min_dense - 1);
608     CHECK(ret, FAIL, "H5Pset_attr_phase_change");
609     ret = H5Pset_attr_phase_change(dcpl, def_max_compact + 1, def_min_dense - 1);
610     CHECK(ret, FAIL, "H5Pset_attr_phase_change");
611     ret = H5Pset_attr_phase_change(tcpl, def_max_compact + 1, def_min_dense - 1);
612     CHECK(ret, FAIL, "H5Pset_attr_phase_change");
613 
614     /* Retrieve attribute phase change values on each creation property list and verify */
615     ret = H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense);
616     CHECK(ret, FAIL, "H5Pget_attr_phase_change");
617     VERIFY(max_compact, (def_max_compact + 1), "H5Pget_attr_phase_change");
618     VERIFY(min_dense, (def_min_dense - 1), "H5Pget_attr_phase_change");
619     ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
620     CHECK(ret, FAIL, "H5Pget_attr_phase_change");
621     VERIFY(max_compact, (def_max_compact + 1), "H5Pget_attr_phase_change");
622     VERIFY(min_dense, (def_min_dense - 1), "H5Pget_attr_phase_change");
623     ret = H5Pget_attr_phase_change(tcpl, &max_compact, &min_dense);
624     CHECK(ret, FAIL, "H5Pget_attr_phase_change");
625     VERIFY(max_compact, (def_max_compact + 1), "H5Pget_attr_phase_change");
626     VERIFY(min_dense, (def_min_dense - 1), "H5Pget_attr_phase_change");
627 
628     /* Create a group, dataset, and committed datatype within the file,
629      *  using the respective type of creation property lists.
630      */
631 
632     /* Create the group anonymously and link it in */
633     grp = H5Gcreate_anon(fid, gcpl, H5P_DEFAULT);
634     CHECK(grp, FAIL, "H5Gcreate_anon");
635     ret = H5Olink(grp, fid, "group", H5P_DEFAULT, H5P_DEFAULT);
636     CHECK(ret, FAIL, "H5Olink");
637 
638     /* Commit the type inside the group anonymously and link it in */
639     dtype = H5Tcopy(H5T_NATIVE_INT);
640     CHECK(dtype, FAIL, "H5Tcopy");
641     ret = H5Tcommit_anon(fid, dtype, tcpl, H5P_DEFAULT);
642     CHECK(ret, FAIL, "H5Tcommit_anon");
643     ret = H5Olink(dtype, fid, "datatype", H5P_DEFAULT, H5P_DEFAULT);
644     CHECK(ret, FAIL, "H5Olink");
645 
646     /* Create the dataspace for the dataset. */
647     dspace = H5Screate(H5S_SCALAR);
648     CHECK(dspace, FAIL, "H5Screate");
649 
650     /* Create the dataset anonymously and link it in */
651     dset = H5Dcreate_anon(fid, H5T_NATIVE_INT, dspace, dcpl, H5P_DEFAULT);
652     CHECK(dset, FAIL, "H5Dcreate_anon");
653     ret = H5Olink(dset, fid, "dataset", H5P_DEFAULT, H5P_DEFAULT);
654     CHECK(ret, FAIL, "H5Olink");
655     ret = H5Sclose(dspace);
656     CHECK(ret, FAIL, "H5Sclose");
657 
658     /* Close current creation property lists */
659     ret = H5Pclose(gcpl);
660     CHECK(ret, FAIL, "H5Pclose");
661     ret = H5Pclose(dcpl);
662     CHECK(ret, FAIL, "H5Pclose");
663     ret = H5Pclose(tcpl);
664     CHECK(ret, FAIL, "H5Pclose");
665 
666     /* Retrieve each object's creation property list */
667     gcpl = H5Gget_create_plist(grp);
668     CHECK(gcpl, FAIL, "H5Gget_create_plist");
669     tcpl = H5Tget_create_plist(dtype);
670     CHECK(tcpl, FAIL, "H5Tget_create_plist");
671     dcpl = H5Dget_create_plist(dset);
672     CHECK(dcpl, FAIL, "H5Dget_create_plist");
673 
674     /* Retrieve attribute phase change values on each creation property list and verify */
675     ret = H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense);
676     CHECK(ret, FAIL, "H5Pget_attr_phase_change");
677     VERIFY(max_compact, (def_max_compact + 1), "H5Pget_attr_phase_change");
678     VERIFY(min_dense, (def_min_dense - 1), "H5Pget_attr_phase_change");
679     ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
680     CHECK(ret, FAIL, "H5Pget_attr_phase_change");
681     VERIFY(max_compact, (def_max_compact + 1), "H5Pget_attr_phase_change");
682     VERIFY(min_dense, (def_min_dense - 1), "H5Pget_attr_phase_change");
683     ret = H5Pget_attr_phase_change(tcpl, &max_compact, &min_dense);
684     CHECK(ret, FAIL, "H5Pget_attr_phase_change");
685     VERIFY(max_compact, (def_max_compact + 1), "H5Pget_attr_phase_change");
686     VERIFY(min_dense, (def_min_dense - 1), "H5Pget_attr_phase_change");
687 
688     /* Close current objects */
689     ret = H5Pclose(gcpl);
690     CHECK(ret, FAIL, "H5Pclose");
691     ret = H5Pclose(dcpl);
692     CHECK(ret, FAIL, "H5Pclose");
693     ret = H5Pclose(tcpl);
694     CHECK(ret, FAIL, "H5Pclose");
695     ret = H5Gclose(grp);
696     CHECK(ret, FAIL, "H5Gclose");
697     ret = H5Tclose(dtype);
698     CHECK(ret, FAIL, "H5Tclose");
699     ret = H5Dclose(dset);
700     CHECK(ret, FAIL, "H5Dclose");
701     ret = H5Fclose(fid);
702     CHECK(ret, FAIL, "H5Fclose");
703 
704     /* Re-open the file and check that the object creation properties persist */
705     fid = H5Fopen(TEST_FILENAME, H5F_ACC_RDONLY, fapl);
706     CHECK(fid, FAIL, "H5Fopen");
707 
708     /* Re-open objects */
709     grp = H5Gopen2(fid, "group", H5P_DEFAULT);
710     CHECK(grp, FAIL, "H5Gopen2");
711     dtype = H5Topen2(fid, "datatype", H5P_DEFAULT);
712     CHECK(dtype, FAIL, "H5Topen2");
713     dset = H5Dopen2(fid, "dataset", H5P_DEFAULT);
714     CHECK(dset, FAIL, "H5Dopen2");
715 
716     /* Retrieve each object's creation property list */
717     gcpl = H5Gget_create_plist(grp);
718     CHECK(gcpl, FAIL, "H5Gget_create_plist");
719     tcpl = H5Tget_create_plist(dtype);
720     CHECK(tcpl, FAIL, "H5Tget_create_plist");
721     dcpl = H5Dget_create_plist(dset);
722     CHECK(dcpl, FAIL, "H5Dget_create_plist");
723 
724     /* Retrieve attribute phase change values on each creation property list and verify */
725     ret = H5Pget_attr_phase_change(gcpl, &max_compact, &min_dense);
726     CHECK(ret, FAIL, "H5Pget_attr_phase_change");
727     VERIFY(max_compact, (def_max_compact + 1), "H5Pget_attr_phase_change");
728     VERIFY(min_dense, (def_min_dense - 1), "H5Pget_attr_phase_change");
729     ret = H5Pget_attr_phase_change(dcpl, &max_compact, &min_dense);
730     CHECK(ret, FAIL, "H5Pget_attr_phase_change");
731     VERIFY(max_compact, (def_max_compact + 1), "H5Pget_attr_phase_change");
732     VERIFY(min_dense, (def_min_dense - 1), "H5Pget_attr_phase_change");
733     ret = H5Pget_attr_phase_change(tcpl, &max_compact, &min_dense);
734     CHECK(ret, FAIL, "H5Pget_attr_phase_change");
735     VERIFY(max_compact, (def_max_compact + 1), "H5Pget_attr_phase_change");
736     VERIFY(min_dense, (def_min_dense - 1), "H5Pget_attr_phase_change");
737 
738     /* Close current objects */
739     ret = H5Pclose(gcpl);
740     CHECK(ret, FAIL, "H5Pclose");
741     ret = H5Pclose(dcpl);
742     CHECK(ret, FAIL, "H5Pclose");
743     ret = H5Pclose(tcpl);
744     CHECK(ret, FAIL, "H5Pclose");
745     ret = H5Gclose(grp);
746     CHECK(ret, FAIL, "H5Gclose");
747     ret = H5Tclose(dtype);
748     CHECK(ret, FAIL, "H5Tclose");
749     ret = H5Dclose(dset);
750     CHECK(ret, FAIL, "H5Dclose");
751     ret = H5Fclose(fid);
752     CHECK(ret, FAIL, "H5Fclose");
753 
754     /* Close the FAPL */
755     ret = H5Pclose(fapl);
756     CHECK(ret, FAIL, "H5Pclose");
757 } /* test_h5o_plist() */
758 
759 
760 /****************************************************************
761 **
762 **  test_h5o_link(): Test creating link to object
763 **
764 ****************************************************************/
765 static void
test_h5o_link(void)766 test_h5o_link(void)
767 {
768     hid_t file_id=-1;
769     hid_t group_id=-1;
770     hid_t space_id=-1;
771     hid_t dset_id=-1;
772     hid_t type_id=-1;
773     hid_t fapl_id=-1;
774     hid_t lcpl_id=-1;
775     hsize_t dims[2] = {TEST6_DIM1, TEST6_DIM2};
776     htri_t committed;           /* Whether the named datatype is committed */
777     hbool_t new_format;         /* Whether to use the new format or not */
778     int wdata[TEST6_DIM1][TEST6_DIM2];
779     int rdata[TEST6_DIM1][TEST6_DIM2];
780     int i, n, j;
781     herr_t ret;                 /* Value returned from API calls */
782 
783     /* Initialize the raw data */
784     for(i = n = 0; i < TEST6_DIM1; i++)
785         for(j = 0; j < TEST6_DIM2; j++)
786           wdata[i][j] = n++;
787 
788     /* Create the dataspace */
789     space_id = H5Screate_simple(2 ,dims, NULL);
790     CHECK(space_id, FAIL, "H5Screate_simple");
791 
792     /* Create LCPL with intermediate group creation flag set */
793     lcpl_id = H5Pcreate(H5P_LINK_CREATE);
794     CHECK(lcpl_id, FAIL, "H5Pcreate");
795     ret = H5Pset_create_intermediate_group(lcpl_id, TRUE);
796     CHECK(ret, FAIL, "H5Pset_create_intermediate_group");
797 
798     /* Loop over using new group format */
799     for(new_format = FALSE; new_format <= TRUE; new_format++) {
800 
801         /* Make a FAPL that uses the "use the latest version of the format" bounds */
802         fapl_id = H5Pcreate(H5P_FILE_ACCESS);
803         CHECK(fapl_id, FAIL, "H5Pcreate");
804 
805         /* Set the "use the latest version of the format" bounds for creating objects in the file */
806         ret = H5Pset_libver_bounds(fapl_id, (new_format ? H5F_LIBVER_LATEST : H5F_LIBVER_EARLIEST), H5F_LIBVER_LATEST);
807         CHECK(ret, FAIL, "H5Pset_libver_bounds");
808 
809         /* Create a new HDF5 file */
810         file_id = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id);
811         CHECK(file_id, FAIL, "H5Fcreate");
812 
813         /* Close the FAPL */
814         ret = H5Pclose(fapl_id);
815         CHECK(ret, FAIL, "H5Pclose");
816 
817 
818         /* Create and commit a datatype with no name */
819         type_id = H5Tcopy(H5T_NATIVE_INT);
820         CHECK(type_id, FAIL, "H5Fcreate");
821         ret = H5Tcommit_anon(file_id, type_id, H5P_DEFAULT, H5P_DEFAULT);
822         CHECK(ret, FAIL, "H5Tcommit_anon");
823         committed = H5Tcommitted(type_id);
824         VERIFY(committed, TRUE, "H5Tcommitted");
825 
826         /* Create a dataset with no name using the committed datatype*/
827         dset_id = H5Dcreate_anon(file_id, type_id, space_id, H5P_DEFAULT, H5P_DEFAULT);
828         CHECK(dset_id, FAIL, "H5Dcreate_anon");
829 
830         /* Verify that we can write to and read from the dataset */
831 
832         /* Write the data to the dataset */
833         ret = H5Dwrite(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);
834         CHECK(ret, FAIL, "H5Dwrite");
835 
836         /* Read the data back */
837         ret = H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata);
838         CHECK(ret, FAIL, "H5Dread");
839 
840         /* Verify the data */
841         for(i = 0; i < TEST6_DIM1; i++)
842             for(j = 0; j < TEST6_DIM2; j++)
843                 VERIFY(wdata[i][j], rdata[i][j], "H5Dread");
844 
845         /* Create a group with no name*/
846         group_id = H5Gcreate_anon(file_id, H5P_DEFAULT, H5P_DEFAULT);
847         CHECK(group_id, FAIL, "H5Gcreate_anon");
848 
849         /* Link nameless datatype into nameless group */
850         ret = H5Olink(type_id, group_id, "datatype", H5P_DEFAULT, H5P_DEFAULT);
851         CHECK(ret, FAIL, "H5Olink");
852 
853         /* Link nameless dataset into nameless group with intermediate group */
854         ret = H5Olink(dset_id, group_id, "inter_group/dataset", lcpl_id, H5P_DEFAULT);
855         CHECK(ret, FAIL, "H5Olink");
856 
857         /* Close IDs for dataset and datatype */
858         ret = H5Dclose(dset_id);
859         CHECK(ret, FAIL, "H5Dclose");
860         ret = H5Tclose(type_id);
861         CHECK(ret, FAIL, "H5Tclose");
862 
863         /* Re-open datatype using new link */
864         type_id = H5Topen2(group_id, "datatype", H5P_DEFAULT);
865         CHECK(type_id, FAIL, "H5Topen2");
866 
867         /* Link nameless group to root group and close the group ID*/
868         ret = H5Olink(group_id, file_id, "/group", H5P_DEFAULT, H5P_DEFAULT);
869         CHECK(ret, FAIL, "H5Olink");
870         ret = H5Gclose(group_id);
871         CHECK(ret, FAIL, "H5Gclose");
872 
873         /* Open dataset through root group and verify its data */
874         dset_id = H5Dopen2(file_id, "/group/inter_group/dataset", H5P_DEFAULT);
875         CHECK(dset_id, FAIL, "H5Dopen2");
876 
877         /* Read data from dataset */
878         ret = H5Dread(dset_id, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, rdata);
879         CHECK(ret, FAIL, "H5Dread");
880         for(i = 0; i < TEST6_DIM1; i++)
881             for(j = 0; j < TEST6_DIM2; j++)
882                 VERIFY(wdata[i][j], rdata[i][j], "H5Dread");
883 
884         /* Close open IDs */
885         ret = H5Dclose(dset_id);
886         CHECK(ret, FAIL, "H5Dclose");
887         ret = H5Tclose(type_id);
888         CHECK(ret, FAIL, "H5Tclose");
889         ret = H5Fclose(file_id);
890         CHECK(ret, FAIL, "H5Fclose");
891     } /* end for */
892 
893     /* Close remaining IDs */
894     ret = H5Sclose(space_id);
895     CHECK(ret, FAIL, "H5Sclose");
896     ret = H5Pclose(lcpl_id);
897     CHECK(ret, FAIL, "H5Pclose");
898 } /* end test_h5o_link() */
899 
900 
901 /****************************************************************
902 **
903 **  test_h5o_comment(): Test H5Oset(get)_comment functions.
904 **
905 ****************************************************************/
906 static void
test_h5o_comment(void)907 test_h5o_comment(void)
908 {
909     hid_t       fid;                        /* HDF5 File ID      */
910     hid_t       grp, dset, dtype, dspace;   /* Object identifiers */
911     hid_t       attr_space, attr_id;
912     hsize_t     dims[RANK];
913     hsize_t     attr_dims = 1;
914     int         attr_value = 5;
915     const char  *file_comment = "file comment";
916     const char  *grp_comment = "group comment";
917     const char  *dset_comment = "dataset comment";
918     const char  *dtype_comment = "datatype comment";
919     char        check_comment[64];
920     ssize_t     comment_len = 0;
921     herr_t      ret;                        /* Value returned from API calls */
922     int         ret_value;
923 
924     /* Create a new HDF5 file */
925     fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
926     CHECK(fid, FAIL, "H5Fcreate");
927 
928     /* Create an attribute for the file */
929     attr_space = H5Screate_simple(1, &attr_dims, NULL);
930     CHECK(attr_space, FAIL, "H5Screate_simple");
931     attr_id = H5Acreate2(fid, "file attribute", H5T_NATIVE_INT, attr_space, H5P_DEFAULT, H5P_DEFAULT);
932     CHECK(attr_id, FAIL, "H5Acreate2");
933     ret = H5Awrite(attr_id, H5T_NATIVE_INT, &attr_value);
934     CHECK(ret, FAIL, "H5Awrite");
935 
936     /* Putting a comment on the file through its attribute */
937     ret = H5Oset_comment(attr_id, file_comment);
938     CHECK(ret, FAIL, "H5Oset_comment");
939 
940     ret = H5Sclose(attr_space);
941     CHECK(ret, FAIL, "H5Sclose");
942 
943     ret = H5Aclose(attr_id);
944     CHECK(ret, FAIL, "H5Aclose");
945 
946     /* Create a group, dataset, and committed datatype within the file */
947     /* Create the group */
948     grp = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
949     CHECK(grp, FAIL, "H5Gcreate2");
950 
951     /* Putting a comment on the group */
952     ret = H5Oset_comment(grp, grp_comment);
953     CHECK(ret, FAIL, "H5Oset_comment");
954 
955     ret = H5Gclose(grp);
956     CHECK(ret, FAIL, "H5Gclose");
957 
958     /* Commit the type inside the group */
959     dtype = H5Tcopy(H5T_NATIVE_INT);
960     CHECK(dtype, FAIL, "H5Tcopy");
961     ret = H5Tcommit2(fid, "group/datatype", dtype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
962     CHECK(ret, FAIL, "H5Tcommit2");
963 
964     /* Putting a comment on the committed data type */
965     ret = H5Oset_comment(dtype, dtype_comment);
966     CHECK(ret, FAIL, "H5Oset_comment");
967 
968     ret = H5Tclose(dtype);
969     CHECK(ret, FAIL, "H5Tclose");
970 
971     /* Create the data space for the dataset. */
972     dims[0] = DIM0;
973     dims[1] = DIM1;
974     dspace = H5Screate_simple(RANK, dims, NULL);
975     CHECK(dspace, FAIL, "H5Screate_simple");
976 
977     /* Create the dataset. */
978     dset = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
979     CHECK(dset, FAIL, "H5Dcreate2");
980 
981     /* Putting a comment on the dataset */
982     ret = H5Oset_comment(dset, dset_comment);
983     CHECK(ret, FAIL, "H5Oset_comment");
984 
985     /* Putting a comment on the dataspace.  It's supposed to fail. */
986     H5E_BEGIN_TRY {
987         ret = H5Oset_comment(dspace, "dataspace comment");
988     } H5E_END_TRY;
989     VERIFY(ret, FAIL, "H5Oset_comment");
990 
991     /* Close the file */
992     ret = H5Dclose(dset);
993     CHECK(ret, FAIL, "H5Dclose");
994     ret = H5Sclose(dspace);
995     CHECK(ret, FAIL, "H5Sclose");
996     ret = H5Fclose(fid);
997     CHECK(ret, FAIL, "H5Fclose");
998 
999 
1000     /* Now make sure that the comments are correct all 4 types of objects */
1001     /* Open file */
1002     fid = H5Fopen(TEST_FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT);
1003     CHECK(fid, FAIL, "H5Fopen");
1004 
1005     /* Getting the comment on the file and verify it */
1006     comment_len = H5Oget_comment(fid, NULL, (size_t)0);
1007     CHECK(comment_len, FAIL, "H5Oget_comment");
1008 
1009     ret = H5Oget_comment(fid, check_comment, (size_t)comment_len+1);
1010     CHECK(ret, FAIL, "H5Oget_comment");
1011 
1012     ret_value = HDstrcmp(file_comment, check_comment);
1013     VERIFY(ret_value, 0, "H5Oget_comment");
1014 
1015     /* Open the group */
1016     grp = H5Gopen2(fid, "group", H5P_DEFAULT);
1017     CHECK(grp, FAIL, "H5Gopen2");
1018 
1019     /* Getting the comment on the group and verify it */
1020     comment_len = H5Oget_comment(grp, NULL, (size_t)0);
1021     CHECK(comment_len, FAIL, "H5Oget_comment");
1022 
1023     ret = H5Oget_comment(grp, check_comment, (size_t)comment_len+1);
1024     CHECK(ret, FAIL, "H5Oget_comment");
1025 
1026     ret_value = HDstrcmp(grp_comment, check_comment);
1027     VERIFY(ret_value, 0, "H5Oget_comment");
1028 
1029     /* Open the datatype */
1030     dtype = H5Topen2(fid, "group/datatype", H5P_DEFAULT);
1031     CHECK(dtype, FAIL, "H5Topen2");
1032 
1033     /* Getting the comment on the datatype and verify it */
1034     comment_len = H5Oget_comment(dtype, NULL, (size_t)0);
1035     CHECK(comment_len, FAIL, "H5Oget_comment");
1036 
1037     ret = H5Oget_comment(dtype, check_comment, (size_t)comment_len+1);
1038     CHECK(ret, FAIL, "H5Oget_comment");
1039 
1040     ret_value = HDstrcmp(dtype_comment, check_comment);
1041     VERIFY(ret_value, 0, "H5Oget_comment");
1042 
1043     /* Open the dataset */
1044     dset = H5Dopen2(fid, "dataset", H5P_DEFAULT);
1045     CHECK(dset, FAIL, "H5Dopen2");
1046 
1047     /* Getting the comment on the dataset and verify it */
1048     comment_len = H5Oget_comment(dset, NULL, (size_t)0);
1049     CHECK(comment_len, FAIL, "H5Oget_comment");
1050 
1051     ret = H5Oget_comment(dset, check_comment, (size_t)comment_len+1);
1052     CHECK(ret, FAIL, "H5Oget_comment");
1053 
1054     ret_value = HDstrcmp(dset_comment, check_comment);
1055     VERIFY(ret_value, 0, "H5Oget_comment");
1056 
1057 
1058     /* Close the IDs */
1059     ret = H5Gclose(grp);
1060     CHECK(ret, FAIL, "H5Gclose");
1061     ret = H5Tclose(dtype);
1062     CHECK(ret, FAIL, "H5Tclose");
1063     ret = H5Dclose(dset);
1064     CHECK(ret, FAIL, "H5Dclose");
1065 
1066     /* Close the file */
1067     ret = H5Fclose(fid);
1068     CHECK(ret, FAIL, "H5Fclose");
1069 
1070 } /* test_h5o_comment() */
1071 
1072 
1073 /****************************************************************
1074 **
1075 **  test_h5o_comment_by_name(): Test H5Oset(get)_comment_by_name functions.
1076 **
1077 ****************************************************************/
1078 static void
test_h5o_comment_by_name(void)1079 test_h5o_comment_by_name(void)
1080 {
1081     hid_t       fid;                        /* HDF5 File ID      */
1082     hid_t       grp, dset, dtype, dspace;   /* Object identifiers */
1083     hid_t       attr_space, attr_id;
1084     hsize_t     dims[RANK];
1085     hsize_t     attr_dims = 1;
1086     int         attr_value = 5;
1087     const char  *file_comment = "file comment by name";
1088     const char  *grp_comment = "group comment by name";
1089     const char  *dset_comment = "dataset comment by name";
1090     const char  *dtype_comment = "datatype comment by name";
1091     char        check_comment[64];
1092     ssize_t     comment_len = 0;
1093     herr_t      ret;                        /* Value returned from API calls */
1094     int         ret_value;
1095 
1096     /* Create a new HDF5 file */
1097     fid = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1098     CHECK(fid, FAIL, "H5Fcreate");
1099 
1100     /* Create an attribute for the file */
1101     attr_space = H5Screate_simple(1, &attr_dims, NULL);
1102     CHECK(attr_space, FAIL, "H5Screate_simple");
1103     attr_id = H5Acreate2(fid, "file attribute", H5T_NATIVE_INT, attr_space, H5P_DEFAULT, H5P_DEFAULT);
1104     CHECK(attr_id, FAIL, "H5Acreate2");
1105     ret = H5Awrite(attr_id, H5T_NATIVE_INT, &attr_value);
1106     CHECK(ret, FAIL, "H5Awrite");
1107 
1108     /* Putting a comment on the file through its attribute */
1109     ret = H5Oset_comment_by_name(attr_id, ".", file_comment, H5P_DEFAULT);
1110     CHECK(ret, FAIL, "H5Oset_comment_by_name");
1111 
1112     ret = H5Sclose(attr_space);
1113     CHECK(ret, FAIL, "H5Sclose");
1114 
1115     ret = H5Aclose(attr_id);
1116     CHECK(ret, FAIL, "H5Aclose");
1117 
1118     /* Create a group, dataset, and committed datatype within the file */
1119     /* Create the group */
1120     grp = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1121     CHECK(grp, FAIL, "H5Gcreate2");
1122 
1123     /* Putting a comment on the group */
1124     ret = H5Oset_comment_by_name(fid, "group", grp_comment, H5P_DEFAULT);
1125     CHECK(ret, FAIL, "H5Oset_comment_by_name");
1126 
1127     /* Commit the type inside the group */
1128     dtype = H5Tcopy(H5T_NATIVE_INT);
1129     CHECK(dtype, FAIL, "H5Tcopy");
1130     ret = H5Tcommit2(fid, "group/datatype", dtype, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1131     CHECK(ret, FAIL, "H5Tcommit2");
1132 
1133     /* Putting a comment on the committed data type */
1134     ret = H5Oset_comment_by_name(grp, "datatype", dtype_comment, H5P_DEFAULT);
1135     CHECK(ret, FAIL, "H5Oset_comment_by_name");
1136 
1137     ret = H5Tclose(dtype);
1138     CHECK(ret, FAIL, "H5Tclose");
1139 
1140     ret = H5Gclose(grp);
1141     CHECK(ret, FAIL, "H5Gclose");
1142 
1143     /* Create the data space for the dataset. */
1144     dims[0] = DIM0;
1145     dims[1] = DIM1;
1146     dspace = H5Screate_simple(RANK, dims, NULL);
1147     CHECK(dspace, FAIL, "H5Screate_simple");
1148 
1149     /* Create the dataset. */
1150     dset = H5Dcreate2(fid, "dataset", H5T_NATIVE_INT, dspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1151     CHECK(dset, FAIL, "H5Dcreate2");
1152 
1153     /* Putting a comment on the dataset */
1154     ret = H5Oset_comment_by_name(fid, "dataset", dset_comment, H5P_DEFAULT);
1155     CHECK(ret, FAIL, "H5Oset_comment_by_name");
1156 
1157     /* Putting a comment on the dataspace.  It's supposed to fail. */
1158     H5E_BEGIN_TRY {
1159         ret = H5Oset_comment_by_name(dspace, ".", "dataspace comment", H5P_DEFAULT);
1160     } H5E_END_TRY;
1161     VERIFY(ret, FAIL, "H5Oset_comment");
1162 
1163     /* Close the file */
1164     ret = H5Dclose(dset);
1165     CHECK(ret, FAIL, "H5Dclose");
1166     ret = H5Sclose(dspace);
1167     CHECK(ret, FAIL, "H5Sclose");
1168     ret = H5Fclose(fid);
1169     CHECK(ret, FAIL, "H5Fclose");
1170 
1171     /* Now make sure that the comments are correct all 4 types of objects */
1172     /* Open file */
1173     fid = H5Fopen(TEST_FILENAME, H5F_ACC_RDONLY, H5P_DEFAULT);
1174     CHECK(fid, FAIL, "H5Fopen");
1175 
1176     /* Getting the comment on the file and verify it */
1177     comment_len = H5Oget_comment_by_name(fid, ".", NULL, (size_t)0, H5P_DEFAULT);
1178     CHECK(comment_len, FAIL, "H5Oget_comment_by_name");
1179 
1180     ret = H5Oget_comment_by_name(fid, ".", check_comment, (size_t)comment_len+1, H5P_DEFAULT);
1181     CHECK(ret, FAIL, "H5Oget_comment_by_name");
1182 
1183     ret_value = HDstrcmp(file_comment, check_comment);
1184     VERIFY(ret_value, 0, "H5Oget_comment_by_name");
1185 
1186     /* Open the group */
1187     grp = H5Gopen2(fid, "group", H5P_DEFAULT);
1188     CHECK(grp, FAIL, "H5Gopen2");
1189 
1190     /* Getting the comment on the group and verify it */
1191     comment_len = H5Oget_comment_by_name(fid, "group", NULL, (size_t)0, H5P_DEFAULT);
1192     CHECK(comment_len, FAIL, "H5Oget_comment_by_name");
1193 
1194     ret = H5Oget_comment_by_name(fid, "group", check_comment, (size_t)comment_len+1, H5P_DEFAULT);
1195     CHECK(ret, FAIL, "H5Oget_comment_by_name");
1196 
1197     ret_value = HDstrcmp(grp_comment, check_comment);
1198     VERIFY(ret_value, 0, "H5Oget_comment_by_name");
1199 
1200     /* Getting the comment on the datatype and verify it */
1201     comment_len = H5Oget_comment_by_name(grp, "datatype", NULL, (size_t)0, H5P_DEFAULT);
1202     CHECK(comment_len, FAIL, "H5Oget_comment_by_name");
1203 
1204     ret = H5Oget_comment_by_name(grp, "datatype", check_comment, (size_t)comment_len+1, H5P_DEFAULT);
1205     CHECK(ret, FAIL, "H5Oget_comment");
1206 
1207     ret_value = HDstrcmp(dtype_comment, check_comment);
1208     VERIFY(ret_value, 0, "H5Oget_comment_by_name");
1209 
1210     /* Getting the comment on the dataset and verify it */
1211     comment_len = H5Oget_comment_by_name(fid, "dataset", NULL, (size_t)0, H5P_DEFAULT);
1212     CHECK(comment_len, FAIL, "H5Oget_comment_by_name");
1213 
1214     ret = H5Oget_comment_by_name(fid, "dataset", check_comment, (size_t)comment_len+1, H5P_DEFAULT);
1215     CHECK(ret, FAIL, "H5Oget_comment_by_name");
1216 
1217     ret_value = HDstrcmp(dset_comment, check_comment);
1218     VERIFY(ret_value, 0, "H5Oget_comment_by_name");
1219 
1220     /* Close the IDs */
1221     ret = H5Gclose(grp);
1222     CHECK(ret, FAIL, "H5Gclose");
1223 
1224     /* Close the file */
1225     ret = H5Fclose(fid);
1226     CHECK(ret, FAIL, "H5Fclose");
1227 
1228 } /* test_h5o_comment_by_name() */
1229 
1230 
1231 /****************************************************************
1232 **
1233 **  test_h5o_getinfo_same_file():  Test that querying the object info for
1234 **      objects in the same file will return the same file "number"
1235 **
1236 ****************************************************************/
1237 static void
test_h5o_getinfo_same_file(void)1238 test_h5o_getinfo_same_file(void)
1239 {
1240     hid_t       fid1, fid2;             /* HDF5 File ID */
1241     hid_t       gid1, gid2;             /* Group IDs */
1242     H5O_info_t	oinfo1, oinfo2;         /* Object info structs */
1243     herr_t      ret;                    /* Value returned from API calls */
1244 
1245     /* Create a new HDF5 file */
1246     fid1 = H5Fcreate(TEST_FILENAME, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
1247     CHECK(fid1, FAIL, "H5Fcreate");
1248 
1249     /* Create two groups in the file */
1250     gid1 = H5Gcreate2(fid1, "group1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1251     CHECK(gid1, FAIL, "H5Gcreate2");
1252     gid2 = H5Gcreate2(fid1, "group2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
1253     CHECK(gid2, FAIL, "H5Gcreate2");
1254 
1255     /* Reset object info */
1256     HDmemset(&oinfo1, 0, sizeof(oinfo1));
1257     HDmemset(&oinfo2, 0, sizeof(oinfo2));
1258 
1259     /* Query the object info for each object, through group IDs */
1260     ret = H5Oget_info(gid1, &oinfo1);
1261     CHECK(ret, FAIL, "H5Oget_info");
1262     ret = H5Oget_info(gid2, &oinfo2);
1263     CHECK(ret, FAIL, "H5Oget_info");
1264 
1265     VERIFY(oinfo1.fileno, oinfo2.fileno, "file number from H5Oget_info");
1266 
1267     /* Reset object info */
1268     HDmemset(&oinfo1, 0, sizeof(oinfo1));
1269     HDmemset(&oinfo2, 0, sizeof(oinfo2));
1270 
1271     /* Query the object info for each object, by name */
1272     ret = H5Oget_info_by_name(fid1, "group1", &oinfo1, H5P_DEFAULT);
1273     CHECK(ret, FAIL, "H5Oget_info_by_name");
1274     ret = H5Oget_info_by_name(fid1, "group2", &oinfo2, H5P_DEFAULT);
1275     CHECK(ret, FAIL, "H5Oget_info_by_name");
1276 
1277     VERIFY(oinfo1.fileno, oinfo2.fileno, "file number from H5Oget_info");
1278 
1279     /* Close everything */
1280     ret = H5Gclose(gid1);
1281     CHECK(ret, FAIL, "H5Gclose");
1282     ret = H5Gclose(gid2);
1283     CHECK(ret, FAIL, "H5Gclose");
1284     ret = H5Fclose(fid1);
1285     CHECK(ret, FAIL, "H5Fclose");
1286 
1287 
1288     /* Open file twice */
1289     fid1 = H5Fopen(TEST_FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
1290     CHECK(fid1, FAIL, "H5Fopen");
1291     fid2 = H5Fopen(TEST_FILENAME, H5F_ACC_RDWR, H5P_DEFAULT);
1292     CHECK(fid2, FAIL, "H5Fopen");
1293 
1294     /* Open the two groups in the file */
1295     gid1 = H5Gopen2(fid1, "group1", H5P_DEFAULT);
1296     CHECK(gid1, FAIL, "H5Gopen2");
1297     gid2 = H5Gopen2(fid2, "group2", H5P_DEFAULT);
1298     CHECK(gid2, FAIL, "H5Gopen2");
1299 
1300     /* Reset object info */
1301     HDmemset(&oinfo1, 0, sizeof(oinfo1));
1302     HDmemset(&oinfo2, 0, sizeof(oinfo2));
1303 
1304     /* Query the object info for each object, through group IDs */
1305     ret = H5Oget_info(gid1, &oinfo1);
1306     CHECK(ret, FAIL, "H5Oget_info");
1307     ret = H5Oget_info(gid2, &oinfo2);
1308     CHECK(ret, FAIL, "H5Oget_info");
1309 
1310     VERIFY(oinfo1.fileno, oinfo2.fileno, "file number from H5Oget_info");
1311 
1312     /* Reset object info */
1313     HDmemset(&oinfo1, 0, sizeof(oinfo1));
1314     HDmemset(&oinfo2, 0, sizeof(oinfo2));
1315 
1316     /* Query the object info for each object, by name */
1317     ret = H5Oget_info_by_name(fid1, "group1", &oinfo1, H5P_DEFAULT);
1318     CHECK(ret, FAIL, "H5Oget_info_by_name");
1319     ret = H5Oget_info_by_name(fid1, "group2", &oinfo2, H5P_DEFAULT);
1320     CHECK(ret, FAIL, "H5Oget_info_by_name");
1321 
1322     VERIFY(oinfo1.fileno, oinfo2.fileno, "file number from H5Oget_info");
1323 
1324     /* Close everything */
1325     ret = H5Gclose(gid1);
1326     CHECK(ret, FAIL, "H5Gclose");
1327     ret = H5Gclose(gid2);
1328     CHECK(ret, FAIL, "H5Gclose");
1329     ret = H5Fclose(fid1);
1330     CHECK(ret, FAIL, "H5Fclose");
1331     ret = H5Fclose(fid2);
1332     CHECK(ret, FAIL, "H5Fclose");
1333 
1334 } /* test_h5o_getinfo_same_file() */
1335 
1336 
1337 /****************************************************************
1338 **
1339 **  test_h5o(): Main H5O (generic object) testing routine.
1340 **
1341 ****************************************************************/
1342 void
test_h5o(void)1343 test_h5o(void)
1344 {
1345     /* Output message about test being performed */
1346     MESSAGE(5, ("Testing Objects\n"));
1347 
1348     test_h5o_open();		/* Test generic open function */
1349     test_h5o_open_by_addr();	/* Test opening objects by address */
1350     test_h5o_close();		/* Test generic close function */
1351     test_h5o_refcount();        /* Test incrementing and decrementing reference count */
1352     test_h5o_plist();           /* Test object creation properties */
1353     test_h5o_link();            /* Test object link routine */
1354     test_h5o_comment();         /* Test routines for comment */
1355     test_h5o_comment_by_name(); /* Test routines for comment by name */
1356     test_h5o_getinfo_same_file(); /* Test info for objects in the same file */
1357 } /* test_h5o() */
1358 
1359 
1360 /*-------------------------------------------------------------------------
1361  * Function:	cleanup_h5o
1362  *
1363  * Purpose:	Cleanup temporary test files
1364  *
1365  * Return:	none
1366  *
1367  * Programmer:	James Laird
1368  *              June 3, 2006
1369  *
1370  *-------------------------------------------------------------------------
1371  */
1372 void
cleanup_h5o(void)1373 cleanup_h5o(void)
1374 {
1375     remove(TEST_FILENAME);
1376 }
1377 
1378