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 #include <assert.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include "H5DSprivate.h"
18 #include "H5LTprivate.h"
19 #include "H5IMprivate.h"
20 #include "H5TBprivate.h"
21 
22 
23 /* Local routines */
24 static herr_t H5DS_is_reserved(hid_t did);
25 static hid_t H5DS_get_REFLIST_type(void);
26 
27 /*-------------------------------------------------------------------------
28 * Function: H5DSset_scale
29 *
30 * Purpose: The dataset DSID is converted to a Dimension Scale dataset.
31 *   Creates the CLASS attribute, set to the value "DIMENSION_SCALE"
32 *   and an empty REFERENCE_LIST attribute.
33 *   If DIMNAME is specified, then an attribute called NAME is created,
34 *   with the value DIMNAME.
35 *
36 * Return: Success: SUCCEED, Failure: FAIL
37 *
38 * Programmer: pvn@ncsa.uiuc.edu
39 *
40 * Date: January 04, 2005
41 *
42 * Comments:
43 *
44 * Modifications:
45 *
46 *-------------------------------------------------------------------------
47 */
48 
H5DSset_scale(hid_t dsid,const char * dimname)49 herr_t H5DSset_scale(hid_t dsid,
50                      const char *dimname)
51 {
52     int has_dimlist;
53     H5I_type_t it;
54 
55     /*-------------------------------------------------------------------------
56     * parameter checking
57     *-------------------------------------------------------------------------
58     */
59     /* get ID type */
60     if ((it = H5Iget_type(dsid)) < 0)
61         return FAIL;
62 
63     if (H5I_DATASET!=it)
64         return FAIL;
65 
66     /*-------------------------------------------------------------------------
67     * check if the dataset is a dataset wich has references to dimension scales
68     *-------------------------------------------------------------------------
69     */
70 
71     /* try to find the attribute "DIMENSION_LIST"  */
72     if ((has_dimlist = H5LT_find_attribute(dsid,DIMENSION_LIST)) < 0)
73         return FAIL;
74 
75     if (has_dimlist == 1)
76         return FAIL;
77 
78     /*-------------------------------------------------------------------------
79     * write the standard attributes for a Dimension Scale dataset
80     *-------------------------------------------------------------------------
81     */
82 
83     if (H5LT_set_attribute_string(dsid,"CLASS",DIMENSION_SCALE_CLASS) < 0)
84         return FAIL;
85 
86     if (dimname!=NULL)
87     {
88         if (H5LT_set_attribute_string(dsid,"NAME",dimname) < 0)
89             return FAIL;
90     }
91 
92     return SUCCEED;
93 }
94 
95 
96 
97 /*-------------------------------------------------------------------------
98 * Function: H5DSattach_scale
99 *
100 * Purpose: Define Dimension Scale DSID to be associated with dimension IDX
101 *  of Dataset DID. Entries are created in the DIMENSION_LIST and
102 *  REFERENCE_LIST attributes.
103 *
104 * Return:
105 *   Success: SUCCEED
106 *   Failure: FAIL
107 *
108 * Fails if: Bad arguments
109 *           If DSID is not a Dimension Scale
110 *           If DID is a Dimension Scale (A Dimension Scale cannot have scales)
111 *
112 * Programmer: pvn@ncsa.uiuc.edu
113 *
114 * Date: December 20, 2004
115 *
116 * Comments:
117 *
118 * Modifications:
119 *
120 *-------------------------------------------------------------------------
121 */
122 
H5DSattach_scale(hid_t did,hid_t dsid,unsigned int idx)123 herr_t H5DSattach_scale(hid_t did,
124                         hid_t dsid,
125                         unsigned int idx)
126 {
127     int        has_dimlist;
128     int        has_reflist;
129     int        is_ds;
130     hssize_t   nelmts;
131     hid_t      sid;          /* space ID */
132     hid_t      tid = -1;     /* attribute type ID */
133     hid_t      ntid = -1;    /* attribute native type ID */
134     hid_t      aid = -1;     /* attribute ID */
135     int        rank;         /* rank of dataset */
136     hsize_t    dims[1];      /* dimension of the "REFERENCE_LIST" array */
137     ds_list_t  dsl;          /* attribute data in the DS pointing to the dataset */
138     ds_list_t  *dsbuf = NULL; /* array of attribute data in the DS pointing to the dataset */
139     hobj_ref_t ref_to_ds;    /* reference to the DS */
140     hobj_ref_t ref_j;        /* iterator reference */
141     hvl_t      *buf = NULL;  /* VL buffer to store in the attribute */
142     hid_t      dsid_j;       /* DS dataset ID in DIMENSION_LIST */
143     H5O_info_t oi1, oi2;
144     H5I_type_t it1, it2;
145     int        i;
146     size_t len;
147     int        found_ds=0;
148     htri_t     is_scale;
149 
150     /*-------------------------------------------------------------------------
151     * parameter checking
152     *-------------------------------------------------------------------------
153     */
154 
155     if ((is_scale = H5DSis_scale(did)) < 0)
156         return FAIL;
157 
158     /* the dataset cannot be a DS dataset */
159     if ( is_scale == 1)
160         return FAIL;
161 
162     /* get info for the dataset in the parameter list */
163     if(H5Oget_info(did, &oi1) < 0)
164         return FAIL;
165 
166     /* get info for the scale in the parameter list */
167     if(H5Oget_info(dsid, &oi2) < 0)
168         return FAIL;
169 
170     /* same object, not valid */
171     if(oi1.fileno == oi2.fileno && oi1.addr == oi2.addr)
172         return FAIL;
173 
174     /* get ID type */
175     if ((it1 = H5Iget_type(did)) < 0)
176         return FAIL;
177     if ((it2 = H5Iget_type(dsid)) < 0)
178         return FAIL;
179 
180     if (H5I_DATASET!=it1 || H5I_DATASET!=it2)
181         return FAIL;
182 
183     /* the DS dataset cannot have dimension scales */
184     if (H5LT_find_attribute(dsid,DIMENSION_LIST)==1)
185         return FAIL;
186 
187     /* check if the dataset is a "reserved" dataset (image, table) */
188     if (H5DS_is_reserved(did)==1)
189         return FAIL;
190 
191 
192     /*-------------------------------------------------------------------------
193     * The dataset may or may not have the associated DS attribute
194     * First we try to open to see if it is already there; if not, it is created.
195     * If it exists, the array of references is extended to hold the reference
196     * to the new DS
197     *-------------------------------------------------------------------------
198     */
199 
200     /* get dataset space */
201     if ((sid = H5Dget_space(did)) < 0)
202         return FAIL;
203 
204     /* get rank */
205     if ((rank=H5Sget_simple_extent_ndims(sid)) < 0)
206         goto out;
207 
208     /* scalar rank */
209     if (rank==0)
210         rank=1;
211 
212     /* close dataset space */
213     if (H5Sclose(sid) < 0)
214         return FAIL;
215 
216     /* parameter range checking */
217     if (idx>(unsigned)rank-1)
218         return FAIL;
219 
220     /*-------------------------------------------------------------------------
221     * two references are created: one to the DS, saved in "DIMENSION_LIST"
222     *  and one to the dataset, saved in "REFERENCE_LIST"
223     *-------------------------------------------------------------------------
224     */
225     /* create a reference for the >>DS<< dataset */
226     if (H5Rcreate(&ref_to_ds, dsid, ".", H5R_OBJECT, (hid_t)-1) < 0)
227         return FAIL;
228 
229     /* create a reference for the >>data<< dataset */
230     if (H5Rcreate(&dsl.ref, did, ".", H5R_OBJECT, (hid_t)-1) < 0)
231         return FAIL;
232 
233     /* try to find the attribute "DIMENSION_LIST" on the >>data<< dataset */
234     if ((has_dimlist = H5LT_find_attribute(did,DIMENSION_LIST)) < 0)
235         return FAIL;
236 
237     /*-------------------------------------------------------------------------
238     * it does not exist. we create the attribute and its reference data
239     *-------------------------------------------------------------------------
240     */
241     if (has_dimlist == 0)
242     {
243 
244       dims[0] = (hsize_t)rank;
245 
246         /* space for the attribute */
247         if((sid = H5Screate_simple(1, dims, NULL)) < 0)
248             return FAIL;
249 
250         /* create the type for the attribute "DIMENSION_LIST" */
251         if((tid = H5Tvlen_create(H5T_STD_REF_OBJ)) < 0)
252             goto out;
253 
254         /* create the attribute */
255         if((aid = H5Acreate2(did, DIMENSION_LIST, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
256             goto out;
257 
258         /* allocate and initialize the VL */
259         buf = (hvl_t *)HDmalloc((size_t)rank * sizeof(hvl_t));
260         if(buf == NULL)
261             goto out;
262 
263         for(i = 0; i < rank; i++) {
264             buf[i].len = 0;
265             buf[i].p = NULL;
266         }
267 
268         /* store the REF information in the index of the dataset that has the DS */
269         buf[idx].len = 1;
270         buf[idx].p = HDmalloc( 1 * sizeof(hobj_ref_t));
271         ((hobj_ref_t *)buf[idx].p)[0] = ref_to_ds;
272 
273         /* write the attribute with the reference */
274         if(H5Awrite(aid, tid, buf) < 0)
275             goto out;
276 
277         /* close */
278         if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0)
279             goto out;
280         if(H5Sclose(sid) < 0)
281             goto out;
282         if(H5Tclose(tid) < 0)
283             goto out;
284         if(H5Aclose(aid) < 0)
285             goto out;
286 
287         HDfree(buf);
288         buf = NULL;
289     }
290 
291     /*-------------------------------------------------------------------------
292     * the attribute already exists, open it, extend the buffer,
293     *  and insert the new reference
294     *-------------------------------------------------------------------------
295     */
296     else if(has_dimlist == 1)
297     {
298         if((aid = H5Aopen(did, DIMENSION_LIST, H5P_DEFAULT)) < 0)
299             goto out;
300 
301         if((tid = H5Aget_type(aid)) < 0)
302             goto out;
303 
304         if((sid = H5Aget_space(aid)) < 0)
305             goto out;
306 
307         /* allocate and initialize the VL */
308         buf = (hvl_t *)HDmalloc((size_t)rank * sizeof(hvl_t));
309         if(buf == NULL)
310             goto out;
311 
312         /* read */
313         if(H5Aread(aid, tid, buf) < 0)
314             goto out;
315 
316         /* check to avoid inserting duplicates. it is not FAIL, just do nothing */
317         /* iterate all the REFs in this dimension IDX */
318         for(i = 0; i < (int)buf[idx].len; i++) {
319             /* get the reference */
320             ref_j = ((hobj_ref_t *)buf[idx].p)[i];
321 
322             /* get the scale id for this REF */
323             if((dsid_j = H5Rdereference(did,H5R_OBJECT,&ref_j)) < 0)
324                 goto out;
325 
326             /* get info for DS in the parameter list */
327             if(H5Oget_info(dsid, &oi1) < 0)
328                 goto out;
329 
330             /* get info for this DS */
331             if(H5Oget_info(dsid_j, &oi2) < 0)
332                 goto out;
333 
334             /* same object, so this DS scale is already in this DIM IDX */
335             if(oi1.fileno == oi2.fileno && oi1.addr == oi2.addr)
336                 found_ds = 1;
337 
338             /* close the dereferenced dataset */
339             if(H5Dclose(dsid_j) < 0)
340                 goto out;
341         } /* end for */
342 
343         if(found_ds == 0) {
344             /* we are adding one more DS to this dimension */
345             if(buf[idx].len > 0) {
346                 buf[idx].len++;
347                 len = buf[idx].len;
348                 buf[idx].p = HDrealloc(buf[idx].p, len * sizeof(hobj_ref_t));
349                 ((hobj_ref_t *)buf[idx].p)[len - 1] = ref_to_ds;
350             } /* end if */
351             else {
352                 /* store the REF information in the index of the dataset that has the DS */
353                 buf[idx].len = 1;
354                 buf[idx].p = HDmalloc(sizeof(hobj_ref_t));
355                 ((hobj_ref_t *)buf[idx].p)[0] = ref_to_ds;
356             } /* end else */
357         } /* end if */
358 
359         /* write the attribute with the new references */
360         if(H5Awrite(aid, tid, buf) < 0)
361             goto out;
362 
363         /* close */
364         if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0)
365             goto out;
366         if(H5Sclose(sid) < 0)
367             goto out;
368         if(H5Tclose(tid) < 0)
369             goto out;
370         if(H5Aclose(aid) < 0)
371             goto out;
372         HDfree(buf);
373         buf = NULL;
374     } /* has_dimlist */
375 
376     /*-------------------------------------------------------------------------
377     * save DS info on the >>DS<< dataset
378     *-------------------------------------------------------------------------
379     */
380 
381     /* try to find the attribute "REFERENCE_LIST" on the >>DS<< dataset */
382     if((has_reflist = H5LT_find_attribute(dsid, REFERENCE_LIST)) < 0)
383         goto out;
384 
385     /*-------------------------------------------------------------------------
386     * it does not exist. we create the attribute and its reference data
387     *-------------------------------------------------------------------------
388     */
389     if(has_reflist == 0) {
390         dims[0] = 1;
391 
392         /* space for the attribute */
393         if((sid = H5Screate_simple(1,dims,NULL)) < 0)
394             goto out;
395 
396         /* create the compound datatype for the attribute "REFERENCE_LIST" */
397         if((tid = H5Tcreate(H5T_COMPOUND, sizeof(ds_list_t))) < 0)
398             goto out;
399 
400         /* insert reference field */
401         if(H5Tinsert(tid, "dataset", HOFFSET(ds_list_t,ref), H5T_STD_REF_OBJ) < 0)
402             goto out;
403 
404         /* insert dimension idx of the dataset field */
405         if(H5Tinsert(tid, "dimension", HOFFSET(ds_list_t, dim_idx), H5T_NATIVE_INT) < 0)
406             goto out;
407 
408         /* create the attribute */
409         if((aid = H5Acreate2(dsid, REFERENCE_LIST, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
410             goto out;
411 
412         /* store the IDX information */
413         dsl.dim_idx = idx;
414 
415         /* write the attribute with the reference */
416         if(H5Awrite(aid, tid, &dsl) < 0)
417             goto out;
418 
419         /* close */
420         if(H5Sclose(sid) < 0)
421             goto out;
422         if(H5Tclose(tid) < 0)
423             goto out;
424         if(H5Aclose(aid) < 0)
425             goto out;
426     } /* end if */
427 
428     /*-------------------------------------------------------------------------
429     * the "REFERENCE_LIST" array already exists, open it and extend it
430     *-------------------------------------------------------------------------
431     */
432     else if(has_reflist ==  1) {
433         if((aid = H5Aopen(dsid, REFERENCE_LIST, H5P_DEFAULT)) < 0)
434             goto out;
435 
436         if((tid = H5Aget_type(aid)) < 0)
437             goto out;
438 
439         /* get native type to read attribute REFERENCE_LIST */
440         if((ntid = H5DS_get_REFLIST_type()) < 0)
441             goto out;
442 
443         /* get and save the old reference(s) */
444         if((sid = H5Aget_space(aid)) < 0)
445             goto out;
446 
447         if((nelmts = H5Sget_simple_extent_npoints(sid)) < 0)
448             goto out;
449 
450         nelmts++;
451 
452         dsbuf = (ds_list_t*) HDmalloc((size_t)nelmts * sizeof(ds_list_t));
453         if(dsbuf == NULL)
454             goto out;
455 
456         if(H5Aread(aid, ntid, dsbuf) < 0)
457             goto out;
458 
459         /* close */
460         if(H5Sclose(sid) < 0)
461             goto out;
462         if(H5Aclose(aid) < 0)
463             goto out;
464 
465         /*-------------------------------------------------------------------------
466         * create a new attribute
467         *-------------------------------------------------------------------------
468         */
469 
470         /* the attribute must be deleted, in order to the new one can reflect the changes*/
471         if(H5Adelete(dsid, REFERENCE_LIST) < 0)
472             goto out;
473 
474         /* store the IDX information (index of the dataset that has the DS) */
475         dsl.dim_idx = idx;
476         dsbuf[nelmts - 1] = dsl;
477 
478         /* create a new data space for the new references array */
479         dims[0] = (hsize_t)nelmts;
480 
481         if((sid = H5Screate_simple(1, dims, NULL)) < 0)
482             goto out;
483 
484         /* create the attribute again with the changes of space */
485         if((aid = H5Acreate2(dsid, REFERENCE_LIST, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
486             goto out;
487 
488         /* write the attribute with the new references */
489         if(H5Awrite(aid, ntid, dsbuf) < 0)
490             goto out;
491 
492         /* close */
493         if(H5Sclose(sid) < 0)
494             goto out;
495         if(H5Tclose(tid) < 0)
496             goto out;
497         if(H5Aclose(aid) < 0)
498             goto out;
499         if (H5Tclose(ntid) < 0)
500             goto out;
501 
502         HDfree(dsbuf);
503         dsbuf = NULL;
504     } /* has_reflist */
505 
506     /*-------------------------------------------------------------------------
507     * write the standard attributes for a Dimension Scale dataset
508     *-------------------------------------------------------------------------
509     */
510 
511     if((is_ds=H5DSis_scale(dsid)) < 0)
512         return FAIL;
513 
514     if(is_ds == 0) {
515         if (H5LT_set_attribute_string(dsid,"CLASS",DIMENSION_SCALE_CLASS) < 0)
516             return FAIL;
517     }
518 
519     return SUCCEED;
520 
521     /* error zone */
522 out:
523     if(buf)
524         HDfree(buf);
525     if(dsbuf)
526         HDfree(dsbuf);
527 
528     H5E_BEGIN_TRY {
529         H5Sclose(sid);
530         H5Aclose(aid);
531         H5Tclose(ntid);
532         H5Tclose(tid);
533     } H5E_END_TRY;
534     return FAIL;
535 }
536 
537 /*-------------------------------------------------------------------------
538 * Function: H5DSdetach_scale
539 *
540 * Purpose: If possible, deletes association of Dimension Scale DSID with
541 *     dimension IDX of Dataset DID. This deletes the entries in the
542 *     DIMENSION_LIST and REFERENCE_LIST attributes.
543 *
544 * Return:
545 *   Success: SUCCEED
546 *   Failure: FAIL
547 *
548 * Fails if: Bad arguments
549 *           The dataset DID or DSID do not exist.
550 *           The DSID is not a Dimension Scale
551 *           DSID is not attached to DID.
552 * Note that a scale may be associated with more than dimension of the same dataset.
553 * If so, the detach operation only deletes one of the associations, for DID.
554 *
555 * Programmer: pvn@ncsa.uiuc.edu
556 *
557 * Date: December 20, 2004
558 *
559 * Comments:
560 *
561 * Modifications: Function didn't delete DIMENSION_LIST attribute, when
562 *                all dimension scales were detached from a dataset; added.
563 *                                                           2010/05/13 EIP
564 *
565 *-------------------------------------------------------------------------
566 */
567 
H5DSdetach_scale(hid_t did,hid_t dsid,unsigned int idx)568 herr_t H5DSdetach_scale(hid_t did,
569                         hid_t dsid,
570                         unsigned int idx)
571 {
572     int        has_dimlist;
573     int        has_reflist;
574     hssize_t   nelmts;
575     hid_t      dsid_j;       /* DS dataset ID in DIMENSION_LIST */
576     hid_t      did_i;        /* dataset ID in REFERENCE_LIST */
577     hid_t      sid;          /* space ID */
578     hid_t      tid = -1;     /* attribute type ID */
579     hid_t      ntid = -1;    /* attribute native type ID */
580     hid_t      aid = -1;     /* attribute ID */
581     int        rank;         /* rank of dataset */
582     ds_list_t  *dsbuf = NULL;  /* array of attribute data in the DS pointing to the dataset */
583     hsize_t    dims[1];      /* dimension of the "REFERENCE_LIST" array */
584     hobj_ref_t ref;          /* reference to the DS */
585     hvl_t      *buf = NULL;  /* VL buffer to store in the attribute */
586     int        i;
587     size_t     j;
588     hssize_t   ii;
589     H5O_info_t did_oi, dsid_oi, tmp_oi;
590     int        found_dset = 0, found_ds = 0;
591     int        have_ds = 0;
592     htri_t     is_scale;
593 
594     /*-------------------------------------------------------------------------
595     * parameter checking
596     *-------------------------------------------------------------------------
597     */
598 
599     /* check for valid types of identifiers */
600 
601     if(H5I_DATASET!=H5Iget_type(did) || H5I_DATASET!=H5Iget_type(dsid))
602         return FAIL;
603 
604     if((is_scale = H5DSis_scale(did)) < 0)
605         return FAIL;
606 
607     /* the dataset cannot be a DS dataset */
608     if( is_scale == 1)
609         return FAIL;
610 
611     /* get info for the dataset in the parameter list */
612     if(H5Oget_info(did, &did_oi) < 0)
613         return FAIL;
614 
615     /* get info for the scale in the parameter list */
616     if(H5Oget_info(dsid, &dsid_oi) < 0)
617         return FAIL;
618 
619     /* same object, not valid */
620     if(did_oi.fileno == dsid_oi.fileno && did_oi.addr == dsid_oi.addr)
621         return FAIL;
622 
623 
624     /*-------------------------------------------------------------------------
625     * Find "DIMENSION_LIST"
626     *-------------------------------------------------------------------------
627     */
628     /* try to find the attribute "DIMENSION_LIST" on the >>data<< dataset */
629     if ((has_dimlist = H5LT_find_attribute(did,DIMENSION_LIST)) < 0)
630         return FAIL;
631 
632     if (has_dimlist == 0)
633         return FAIL;
634 
635     /* get dataset space */
636     if ((sid = H5Dget_space(did)) < 0)
637         return FAIL;
638 
639     /* get rank */
640     if ((rank=H5Sget_simple_extent_ndims(sid)) < 0)
641         goto out;
642 
643     /* close dataset space */
644     if (H5Sclose(sid) < 0)
645         return FAIL;
646 
647     /* parameter range checking */
648     if (idx>(unsigned)rank-1)
649         return FAIL;
650 
651     /*-------------------------------------------------------------------------
652     * find "REFERENCE_LIST"
653     *-------------------------------------------------------------------------
654     */
655 
656     /* try to find the attribute "REFERENCE_LIST" on the >>DS<< dataset */
657     if((has_reflist = H5LT_find_attribute(dsid, REFERENCE_LIST)) < 0)
658         return FAIL;
659 
660     if(has_reflist == 0)
661         return FAIL;
662 
663     /*-------------------------------------------------------------------------
664     * open "DIMENSION_LIST", and delete the reference
665     *-------------------------------------------------------------------------
666     */
667 
668     if((aid = H5Aopen(did, DIMENSION_LIST, H5P_DEFAULT)) < 0)
669         return FAIL;
670 
671     if((tid = H5Aget_type(aid)) < 0)
672         goto out;
673 
674     if((sid = H5Aget_space(aid)) < 0)
675         goto out;
676 
677     /* allocate and initialize the VL */
678     buf = (hvl_t *)HDmalloc((size_t)rank * sizeof(hvl_t));
679     if(buf == NULL)
680         goto out;
681 
682     /* read */
683     if(H5Aread(aid, tid, buf) < 0)
684         goto out;
685 
686     /* reset */
687     if ( buf[idx].len > 0 )
688     {
689         for (j=0; j<buf[idx].len; j++)
690         {
691             /* get the reference */
692             ref = ((hobj_ref_t *)buf[idx].p)[j];
693 
694             /* get the DS id */
695             if ((dsid_j = H5Rdereference(did,H5R_OBJECT,&ref)) < 0)
696                 goto out;
697 
698             /* get info for this DS */
699             if(H5Oget_info(dsid_j, &tmp_oi) < 0)
700                 goto out;
701 
702             /* Close the dereferenced dataset */
703             if (H5Dclose(dsid_j) < 0)
704                 goto out;
705 
706             /* same object, reset */
707             if(dsid_oi.fileno == tmp_oi.fileno && dsid_oi.addr == tmp_oi.addr)
708             {
709                 /* If there are more than one reference in the VL element
710                    and the reference we found is not the last one,
711                    copy the last one to replace the found one since the order
712                    of the references doesn't matter according to the spec;
713                    reduce the size of the VL element by 1;
714                    if the length of the element becomes 0, free the pointer
715                    and reset to NULL */
716 
717                 size_t len = buf[idx].len;
718 
719                 if(j < len - 1)
720                     ((hobj_ref_t *)buf[idx].p)[j] = ((hobj_ref_t *)buf[idx].p)[len-1];
721                 len = --buf[idx].len;
722                 if(len == 0) {
723                     HDfree(buf[idx].p);
724                     buf[idx].p = NULL;
725                 }
726                 /* Since a reference to a dim. scale can be inserted only once,
727                    we do not need to continue the search if it is found */
728                 found_ds = 1;
729                 break;
730             }
731         } /* j */
732     } /* if */
733 
734     /* the scale must be present to continue */
735     if(found_ds == 0)
736         goto out;
737 
738     /* Write the attribute, but check first, if we have any scales left,
739        because if not, we should delete the attribute according to the spec */
740     for(i = 0; i < rank; i++) {
741         if(buf[i].len > 0)  {
742             have_ds = 1;
743             break;
744         }
745     }
746     if(have_ds) {
747         if(H5Awrite(aid, tid, buf) < 0)
748             goto out;
749     }
750     else {
751         if(H5Adelete(did, DIMENSION_LIST) < 0)
752             goto out;
753     }
754 
755     /* close */
756     if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0)
757         goto out;
758     if(H5Sclose(sid) < 0)
759         goto out;
760     if(H5Tclose(tid) < 0)
761         goto out;
762     if(H5Aclose(aid) < 0)
763         goto out;
764 
765     HDfree(buf);
766     buf = NULL;
767 
768 
769     /*-------------------------------------------------------------------------
770     * the "REFERENCE_LIST" array exists, update
771     *-------------------------------------------------------------------------
772     */
773 
774     if((aid = H5Aopen(dsid, REFERENCE_LIST, H5P_DEFAULT)) < 0)
775         goto out;
776 
777     if((tid = H5Aget_type(aid)) < 0)
778         goto out;
779 
780     /* get native type to read attribute REFERENCE_LIST */
781     if((ntid = H5DS_get_REFLIST_type()) < 0)
782         goto out;
783 
784     /* get and save the old reference(s) */
785     if((sid = H5Aget_space(aid)) < 0)
786         goto out;
787 
788     if((nelmts = H5Sget_simple_extent_npoints(sid)) < 0)
789         goto out;
790 
791     dsbuf = (ds_list_t*) HDmalloc((size_t)nelmts * sizeof(ds_list_t));
792     if(dsbuf == NULL)
793         goto out;
794 
795     if(H5Aread(aid, ntid, dsbuf) < 0)
796         goto out;
797 
798     for(ii=0; ii<nelmts; ii++) {
799         /* First check if we have the same dimension index */
800       if(idx == dsbuf[ii].dim_idx) {
801             /* get the reference to the dataset */
802             ref = dsbuf[ii].ref;
803 
804             /* get the dataset id */
805             if ((did_i = H5Rdereference(did,H5R_OBJECT,&ref)) < 0)
806                 goto out;
807 
808             /* get info for this dataset */
809             if(H5Oget_info(did_i, &tmp_oi) < 0)
810                 goto out;
811 
812             /* close the dereferenced dataset */
813             if(H5Dclose(did_i) < 0)
814                 goto out;
815 
816             /* same object, reset. we want to detach only for this DIM */
817             if(did_oi.fileno == tmp_oi.fileno && did_oi.addr == tmp_oi.addr) {
818                 /* copy the last one to replace the one which is found */
819                 dsbuf[ii] = dsbuf[nelmts-1];
820                 nelmts--;
821                 found_dset=1;
822                 break;
823             } /* if */
824         } /* if we have the same dimension index */
825     } /* ii */
826 
827     /* close space and attribute */
828     if (H5Sclose(sid) < 0)
829         goto out;
830     if (H5Aclose(aid) < 0)
831         goto out;
832 
833     /*-------------------------------------------------------------------------
834     * check if we found the pointed dataset
835     *-------------------------------------------------------------------------
836     */
837 
838     /* the pointed dataset must exist */
839     if (found_dset == 0)
840         goto out;
841 
842     /*-------------------------------------------------------------------------
843     * create a new attribute
844     *-------------------------------------------------------------------------
845     */
846 
847     /* the attribute must be deleted, in order to the new one can reflect the changes*/
848     if (H5Adelete(dsid, REFERENCE_LIST) < 0)
849         goto out;
850 
851     /* don't do anything for an empty array */
852     if(nelmts)
853     {
854         /* create a new data space for the new references array */
855       dims[0] = (hsize_t)nelmts;
856 
857         if((sid = H5Screate_simple(1, dims, NULL)) < 0)
858             goto out;
859 
860         /* create the attribute again with the changes of space */
861         if((aid = H5Acreate2(dsid, REFERENCE_LIST, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
862             goto out;
863 
864         /* write the new attribute with the new references */
865         if(H5Awrite(aid, ntid, dsbuf) < 0)
866             goto out;
867 
868         /* close space and attribute */
869         if(H5Sclose(sid) < 0)
870             goto out;
871         if(H5Aclose(aid) < 0)
872             goto out;
873     } /* nelmts */
874 
875     /* close type */
876     if (H5Tclose(tid) < 0)
877         goto out;
878     if (H5Tclose(ntid) < 0)
879         goto out;
880 
881     HDfree(dsbuf);
882     dsbuf = NULL;
883 
884     return SUCCEED;
885 
886     /* error zone */
887 out:
888     H5E_BEGIN_TRY {
889         H5Sclose(sid);
890         H5Aclose(aid);
891         H5Tclose(ntid);
892         H5Tclose(tid);
893 
894         if(dsbuf) {
895             HDfree(dsbuf);
896             dsbuf = NULL;
897         }
898         if(buf) {
899             /* Failure occured before H5Dvlen_reclaim was called;
900                free the pointers allocated when we read data in */
901             for(i = 0; i < rank; i++) {
902                 if(buf[i].p)
903                     HDfree(buf[i].p);
904             }
905             HDfree(buf);
906             buf = NULL;
907         }
908     } H5E_END_TRY;
909     return FAIL;
910 
911 }
912 
913 /*-------------------------------------------------------------------------
914 * Function: H5DSis_attached
915 *
916 * Purpose: Report if dimension scale DSID is currently attached to
917 *  dimension IDX of dataset DID by checking if DID has a pointer in the REFERENCE_LIST
918 *  attribute and DSID (scale ) has a pointer in the DIMENSION_LIST attribute
919 *
920 * Return:
921 *   1: both the DS and the dataset pointers match
922 *   0: one of them or both do not match
923 *   FAIL (-1): error
924 *
925 * Fails if: Bad arguments
926 *           If DSID is not a Dimension Scale
927 *           If DID is a Dimension Scale (A Dimension Scale cannot have scales)
928 *
929 * Programmer: pvn@ncsa.uiuc.edu
930 *
931 * Date: February 18, 2005
932 *
933 * Comments:
934 *
935 * Modifications:
936 *
937 *-------------------------------------------------------------------------
938 */
939 
H5DSis_attached(hid_t did,hid_t dsid,unsigned int idx)940 htri_t H5DSis_attached(hid_t did,
941                        hid_t dsid,
942                        unsigned int idx)
943 {
944     int        has_dimlist;
945     int        has_reflist;
946     hssize_t   nelmts;
947     hid_t      sid;          /* space ID */
948     hid_t      tid = -1;     /* attribute type ID */
949     hid_t      ntid = -1;    /* attribute native type ID */
950     hid_t      aid = -1;     /* attribute ID */
951     int        rank;         /* rank of dataset */
952     ds_list_t  *dsbuf = NULL;   /* array of attribute data in the DS pointing to the dataset */
953     hobj_ref_t ref;          /* reference to the DS */
954     hvl_t      *buf = NULL;  /* VL buffer to store in the attribute */
955     hid_t      dsid_j;       /* DS dataset ID in DIMENSION_LIST */
956     hid_t      did_i;        /* dataset ID in REFERENCE_LIST */
957     H5O_info_t oi1, oi2, oi3, oi4;
958     H5I_type_t it1, it2;
959     int        i;
960     int        found_dset=0, found_ds=0;
961     htri_t     is_scale;
962 
963     /*-------------------------------------------------------------------------
964     * parameter checking
965     *-------------------------------------------------------------------------
966     */
967 
968     if ((is_scale = H5DSis_scale(did)) < 0)
969         return FAIL;
970 
971     /* the dataset cannot be a DS dataset */
972     if ( is_scale == 1)
973         return FAIL;
974 
975     /* get info for the dataset in the parameter list */
976     if(H5Oget_info(did, &oi1) < 0)
977         return FAIL;
978 
979     /* get info for the scale in the parameter list */
980     if(H5Oget_info(dsid, &oi2) < 0)
981         return FAIL;
982 
983     /* same object, not valid */
984     if(oi1.fileno == oi2.fileno && oi1.addr == oi2.addr)
985         return FAIL;
986 
987     /* get ID type */
988     if ((it1 = H5Iget_type(did)) < 0)
989         return FAIL;
990     if ((it2 = H5Iget_type(dsid)) < 0)
991         return FAIL;
992 
993     if (H5I_DATASET!=it1 || H5I_DATASET!=it2)
994         return FAIL;
995 
996     /*-------------------------------------------------------------------------
997     * get space
998     *-------------------------------------------------------------------------
999     */
1000 
1001     /* get dataset space */
1002     if ((sid = H5Dget_space(did)) < 0)
1003         return FAIL;
1004 
1005     /* get rank */
1006     if ((rank=H5Sget_simple_extent_ndims(sid)) < 0)
1007         goto out;
1008 
1009     /* close dataset space */
1010     if (H5Sclose(sid) < 0)
1011         goto out;
1012 
1013     /* parameter range checking */
1014     if(idx > ((unsigned)rank - 1))
1015         return FAIL;
1016 
1017     /* try to find the attribute "DIMENSION_LIST" on the >>data<< dataset */
1018     if((has_dimlist = H5LT_find_attribute(did, DIMENSION_LIST)) < 0)
1019         return FAIL;
1020 
1021     /*-------------------------------------------------------------------------
1022     * open "DIMENSION_LIST"
1023     *-------------------------------------------------------------------------
1024     */
1025 
1026     if(has_dimlist == 1)
1027     {
1028         if((aid = H5Aopen(did, DIMENSION_LIST, H5P_DEFAULT)) < 0)
1029             goto out;
1030 
1031         if((tid = H5Aget_type(aid)) < 0)
1032             goto out;
1033 
1034         if((sid = H5Aget_space(aid)) < 0)
1035             goto out;
1036 
1037         /* allocate and initialize the VL */
1038         buf = (hvl_t*)HDmalloc((size_t)rank * sizeof(hvl_t));
1039         if(buf == NULL)
1040             goto out;
1041 
1042         /* read */
1043         if (H5Aread(aid,tid,buf) < 0)
1044             goto out;
1045 
1046         /* iterate all the REFs in this dimension IDX */
1047         for (i=0; i<(int)buf[idx].len; i++)
1048         {
1049             /* get the reference */
1050             ref = ((hobj_ref_t *)buf[idx].p)[i];
1051 
1052             /* get the scale id for this REF */
1053             if ((dsid_j = H5Rdereference(did,H5R_OBJECT,&ref)) < 0)
1054                 goto out;
1055 
1056             /* get info for DS in the parameter list */
1057             if(H5Oget_info(dsid, &oi1) < 0)
1058                 goto out;
1059 
1060             /* get info for this DS */
1061             if(H5Oget_info(dsid_j, &oi2) < 0)
1062                 goto out;
1063 
1064             /* same object */
1065             if(oi1.fileno == oi2.fileno && oi1.addr == oi2.addr)
1066                 found_ds = 1;
1067 
1068             /* close the dereferenced dataset */
1069             if (H5Dclose(dsid_j) < 0)
1070                 goto out;
1071 
1072         }
1073 
1074 
1075         /* close */
1076         if (H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf) < 0)
1077             goto out;
1078         if (H5Sclose(sid) < 0)
1079             goto out;
1080         if (H5Tclose(tid) < 0)
1081             goto out;
1082         if (H5Aclose(aid) < 0)
1083             goto out;
1084         HDfree(buf);
1085         buf = NULL;
1086     } /* has_dimlist */
1087 
1088     /*-------------------------------------------------------------------------
1089     * info on the >>DS<< dataset
1090     *-------------------------------------------------------------------------
1091     */
1092 
1093     /* try to find the attribute "REFERENCE_LIST" on the >>DS<< dataset */
1094     if((has_reflist = H5LT_find_attribute(dsid, REFERENCE_LIST)) < 0)
1095         goto out;
1096 
1097     /*-------------------------------------------------------------------------
1098     * open "REFERENCE_LIST"
1099     *-------------------------------------------------------------------------
1100     */
1101 
1102     if(has_reflist ==  1)
1103     {
1104         if((aid = H5Aopen(dsid, REFERENCE_LIST, H5P_DEFAULT)) < 0)
1105             goto out;
1106 
1107         if((tid = H5Aget_type(aid)) < 0)
1108             goto out;
1109 
1110         /* get native type to read REFERENCE_LIST attribute */
1111         if((ntid = H5DS_get_REFLIST_type()) < 0)
1112             goto out;
1113 
1114         /* get and save the old reference(s) */
1115         if((sid = H5Aget_space(aid)) < 0)
1116             goto out;
1117 
1118         if((nelmts = H5Sget_simple_extent_npoints(sid)) < 0)
1119             goto out;
1120 
1121         dsbuf = (ds_list_t*) HDmalloc((size_t)nelmts * sizeof(ds_list_t));
1122 
1123         if (dsbuf == NULL)
1124             goto out;
1125 
1126         if (H5Aread(aid,ntid,dsbuf) < 0)
1127             goto out;
1128 
1129         /*-------------------------------------------------------------------------
1130         * iterate
1131         *-------------------------------------------------------------------------
1132         */
1133 
1134         for(i=0; i<nelmts; i++)
1135         {
1136             /* get the reference */
1137             ref = dsbuf[i].ref;
1138 
1139             /* the reference was not deleted  */
1140             if (ref)
1141             {
1142                 /* get the dataset id */
1143                 if ((did_i = H5Rdereference(did,H5R_OBJECT,&ref)) < 0)
1144                     goto out;
1145 
1146                 /* get info for dataset in the parameter list */
1147                 if(H5Oget_info(did, &oi3) < 0)
1148                     goto out;
1149 
1150                 /* get info for this dataset */
1151                 if(H5Oget_info(did_i, &oi4) < 0)
1152                     goto out;
1153 
1154                 /* same object */
1155                 if(oi3.fileno == oi4.fileno && oi3.addr == oi4.addr && idx==dsbuf[i].dim_idx)
1156                     found_dset=1;
1157 
1158                 /* close the dereferenced dataset */
1159                 if (H5Dclose(did_i) < 0)
1160                     goto out;
1161             } /* if */
1162         } /* i */
1163 
1164 
1165         /* close */
1166         if (H5Sclose(sid) < 0)
1167             goto out;
1168         if (H5Tclose(ntid) < 0)
1169             goto out;
1170         if (H5Tclose(tid) < 0)
1171             goto out;
1172         if (H5Aclose(aid) < 0)
1173             goto out;
1174 
1175         HDfree(dsbuf);
1176         dsbuf = NULL;
1177     } /* has_reflist */
1178 
1179     if (found_ds && found_dset)
1180         return 1;
1181     else
1182         return 0;
1183 
1184     /* error zone */
1185 out:
1186     H5E_BEGIN_TRY {
1187         H5Sclose(sid);
1188         H5Aclose(aid);
1189         H5Tclose(tid);
1190         H5Tclose(ntid);
1191     } H5E_END_TRY;
1192 
1193     if (buf) {
1194         HDfree(buf);
1195         buf = NULL;
1196     }
1197     if(dsbuf) {
1198         HDfree(dsbuf);
1199         dsbuf = NULL;
1200     }
1201     return FAIL;
1202 }
1203 
1204 /*-------------------------------------------------------------------------
1205 * Function: H5DSiterate_scales
1206 *
1207 * Purpose: H5DSiterate_scales iterates over the scales attached to dimension DIM
1208 *  of dataset DID. For each scale in the list, the visitor_data and some
1209 *  additional information, specified below, are passed to the visitor function.
1210 *  The iteration begins with the IDX object in the group and the next element
1211 *  to be processed by the operator is returned in IDX. If IDX is NULL, then the
1212 *  iterator starts at zero.
1213 *
1214 * Parameters:
1215 *
1216 *  hid_t DID;               IN: the dataset
1217 *  unsigned int DIM;        IN: the dimension of the dataset
1218 *  int *DS_IDX;             IN/OUT: on input the dimension scale index to start iterating,
1219 *                               on output the next index to visit. If NULL, start at
1220 *                               the first position.
1221 *  H5DS_iterate_t VISITOR;  IN: the visitor function
1222 *  void *VISITOR_DATA;      IN: arbitrary data to pass to the visitor function.
1223 *
1224 *  Iterate over all scales of DIM, calling an application callback
1225 *   with the item, key and any operator data.
1226 *
1227 *   The operator callback receives a pointer to the item ,
1228 *   and the pointer to the operator data passed
1229 *   in to H5SL_iterate ('op_data').  The return values from an operator are:
1230 *       A. Zero causes the iterator to continue, returning zero when all
1231 *           nodes of that type have been processed.
1232 *       B. Positive causes the iterator to immediately return that positive
1233 *           value, indicating short-circuit success.
1234 *       C. Negative causes the iterator to immediately return that value,
1235 *           indicating failure.
1236 *
1237 * Programmer: pvn@ncsa.uiuc.edu
1238 *
1239 * Date: January 31, 2005
1240 *
1241 * Comments:
1242 *
1243 * Modifications:
1244 *
1245 *-------------------------------------------------------------------------
1246 */
1247 
H5DSiterate_scales(hid_t did,unsigned int dim,int * ds_idx,H5DS_iterate_t visitor,void * visitor_data)1248 herr_t H5DSiterate_scales(hid_t did,
1249                           unsigned int dim,
1250                           int *ds_idx,
1251                           H5DS_iterate_t visitor,
1252                           void *visitor_data )
1253 {
1254     hid_t        scale_id;
1255     int          rank;
1256     hobj_ref_t   ref;          /* reference to the DS */
1257     hid_t        sid;          /* space ID */
1258     hid_t        tid = -1;     /* attribute type ID */
1259     hid_t        aid = -1;     /* attribute ID */
1260     hvl_t        *buf = NULL;    /* VL buffer to store in the attribute */
1261     H5I_type_t   it;           /* ID type */
1262     herr_t       ret_value=0;
1263     int          j_idx;
1264     int          nscales;
1265     int          has_dimlist;
1266     int          i;
1267 
1268     /*-------------------------------------------------------------------------
1269     * parameter checking
1270     *-------------------------------------------------------------------------
1271     */
1272     /* get ID type */
1273     if ((it = H5Iget_type(did)) < 0)
1274         return FAIL;
1275 
1276     if (H5I_DATASET!=it)
1277         return FAIL;
1278 
1279     /* get the number of scales assotiated with this DIM */
1280     if ((nscales = H5DSget_num_scales(did,dim)) < 0)
1281         return FAIL;
1282 
1283     /* parameter range checking */
1284     if (ds_idx!=NULL)
1285     {
1286         if (*ds_idx>=nscales)
1287             return FAIL;
1288     }
1289 
1290     /* get dataset space */
1291     if ((sid = H5Dget_space(did)) < 0)
1292         return FAIL;
1293 
1294     /* get rank */
1295     if ((rank=H5Sget_simple_extent_ndims(sid)) < 0)
1296         goto out;
1297 
1298     /* close dataset space */
1299     if(H5Sclose(sid) < 0)
1300         goto out;
1301 
1302     if ( dim >= (unsigned)rank )
1303         return FAIL;
1304 
1305     /* try to find the attribute "DIMENSION_LIST" on the >>data<< dataset */
1306     if((has_dimlist = H5LT_find_attribute(did, DIMENSION_LIST)) < 0)
1307         return FAIL;
1308 
1309     if(has_dimlist == 0)
1310         return SUCCEED;
1311 
1312     else if(has_dimlist == 1)
1313     {
1314         if((aid = H5Aopen(did, DIMENSION_LIST, H5P_DEFAULT)) < 0)
1315             goto out;
1316         if((tid = H5Aget_type(aid)) < 0)
1317             goto out;
1318         if((sid = H5Aget_space(aid)) < 0)
1319             goto out;
1320 
1321         /* allocate and initialize the VL */
1322         buf = (hvl_t*)HDmalloc((size_t)rank * sizeof(hvl_t));
1323 
1324         if(buf == NULL)
1325             goto out;
1326 
1327         /* read */
1328         if(H5Aread(aid, tid, buf) < 0)
1329             goto out;
1330 
1331         if ( buf[dim].len > 0 )
1332         {
1333             if (ds_idx!=NULL)
1334                 j_idx = *ds_idx;
1335             else
1336                 j_idx=0;
1337 
1338             /* iterate */
1339             for(i=j_idx; i<nscales; i++)
1340             {
1341                 /* get the reference */
1342                 ref = ((hobj_ref_t *)buf[dim].p)[ i ];
1343 
1344                 /* disable error reporting, the ID might refer to a deleted dataset */
1345                 H5E_BEGIN_TRY {
1346                     /* get the DS id */
1347                     if ((scale_id = H5Rdereference(did,H5R_OBJECT,&ref)) < 0)
1348                         goto out;
1349                 } H5E_END_TRY;
1350 
1351                 /* set the return IDX OUT value at current scale index */
1352                 if (ds_idx!=NULL)
1353                 {
1354                     *ds_idx = i;
1355                 }
1356 
1357                 if((ret_value=(visitor)(did,dim,scale_id,visitor_data))!=0)
1358                 {
1359                     /* break */
1360 
1361                     /* close the DS id */
1362                     if (H5Dclose(scale_id) < 0)
1363                         goto out;
1364 
1365                     break;
1366                 }
1367 
1368                 /* close the DS id */
1369                 if (H5Dclose(scale_id) < 0)
1370                     goto out;
1371 
1372             } /* i */
1373         } /* if */
1374 
1375         /* close */
1376         if (H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf) < 0)
1377             goto out;
1378         if (H5Sclose(sid) < 0)
1379             goto out;
1380         if (H5Tclose(tid) < 0)
1381             goto out;
1382         if (H5Aclose(aid) < 0)
1383             goto out;
1384 
1385         HDfree(buf);
1386         buf = NULL;
1387     } /* if has_dimlist */
1388 
1389     return ret_value;
1390 
1391 out:
1392     H5E_BEGIN_TRY {
1393         if(buf) {
1394             H5Dvlen_reclaim(tid,sid,H5P_DEFAULT,buf);
1395             HDfree(buf);
1396         }
1397         H5Sclose(sid);
1398         H5Aclose(aid);
1399         H5Tclose(tid);
1400     } H5E_END_TRY;
1401 
1402     return FAIL;
1403 }
1404 
1405 /*-------------------------------------------------------------------------
1406 * Function: H5DSset_label
1407 *
1408 * Purpose: Set label for the dimension IDX of dataset DID to the value LABEL
1409 *
1410 * Return: Success: SUCCEED, Failure: FAIL
1411 *
1412 * Programmer: pvn@ncsa.uiuc.edu
1413 *
1414 * Date: January 11, 2005
1415 *
1416 * Comments:
1417 *
1418 * Modifications:
1419 *
1420 *-------------------------------------------------------------------------
1421 */
1422 
H5DSset_label(hid_t did,unsigned int idx,const char * label)1423 herr_t H5DSset_label(hid_t did, unsigned int idx, const char *label)
1424 {
1425     int        has_labels;
1426     hid_t      sid = -1;      /* space ID */
1427     hid_t      tid = -1;      /* attribute type ID */
1428     hid_t      aid = -1;      /* attribute ID */
1429     int        rank;          /* rank of dataset */
1430     hsize_t    dims[1];       /* dimensions of dataset */
1431     H5I_type_t it;            /* ID type */
1432     unsigned   int i;
1433     union {                    /* union is needed to eliminate compiler warnings about */
1434       char  ** buf;            /* discarding the 'const' qualifier in the free */
1435       char const ** const_buf; /* buf calls */
1436     } u;
1437     /*-------------------------------------------------------------------------
1438     * parameter checking
1439     *-------------------------------------------------------------------------
1440     */
1441     /* get ID type */
1442     if ((it = H5Iget_type(did)) < 0)
1443         return FAIL;
1444 
1445     if (H5I_DATASET != it)
1446         return FAIL;
1447 
1448     if (label == NULL)
1449         return FAIL;
1450 
1451      /* get dataset space */
1452     if ((sid = H5Dget_space(did)) < 0)
1453         return FAIL;
1454 
1455     /* get rank */
1456     if ((rank = H5Sget_simple_extent_ndims(sid)) < 0)
1457         goto out;
1458 
1459     /* close dataset space */
1460     if (H5Sclose(sid) < 0)
1461         goto out;
1462 
1463     if ( idx >= (unsigned)rank )
1464         return FAIL;
1465 
1466     /*-------------------------------------------------------------------------
1467     * attribute "DIMENSION_LABELS"
1468     *-------------------------------------------------------------------------
1469     */
1470 
1471     /* try to find the attribute "DIMENSION_LABELS" on the >>data<< dataset */
1472     if ((has_labels = H5LT_find_attribute(did, DIMENSION_LABELS)) < 0)
1473         return FAIL;
1474 
1475     /*-------------------------------------------------------------------------
1476     * make the attribute and insert label
1477     *-------------------------------------------------------------------------
1478     */
1479 
1480     if (has_labels == 0)
1481     {
1482         dims[0] = (hsize_t)rank;
1483 
1484         /* space for the attribute */
1485         if ((sid = H5Screate_simple(1, dims, NULL)) < 0)
1486             goto out;
1487 
1488         /* create the datatype  */
1489         if ((tid = H5Tcopy(H5T_C_S1)) < 0)
1490             goto out;
1491         if (H5Tset_size(tid, H5T_VARIABLE) < 0)
1492             goto out;
1493 
1494         /* create the attribute */
1495         if ((aid = H5Acreate2(did, DIMENSION_LABELS, tid, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
1496             goto out;
1497 
1498         /* allocate and initialize */
1499         u.const_buf = (char const **) HDmalloc((size_t) rank * sizeof(char *));
1500 
1501         if (u.const_buf == NULL)
1502             goto out;
1503 
1504         for (i = 0; i < (unsigned int) rank; i++)
1505 	  u.const_buf[i] = NULL;
1506 
1507         /* store the label information in the required index */
1508         u.const_buf[idx] = label;
1509 
1510         /* write the attribute with the label */
1511         if (H5Awrite(aid, tid, u.const_buf) < 0)
1512             goto out;
1513 
1514         /* close */
1515         if (H5Sclose(sid) < 0)
1516             goto out;
1517         if (H5Tclose(tid) < 0)
1518             goto out;
1519         if (H5Aclose(aid) < 0)
1520             goto out;
1521         if (u.const_buf)
1522         {
1523             HDfree(u.const_buf);
1524             u.const_buf = NULL;
1525         }
1526     }
1527 
1528     /*-------------------------------------------------------------------------
1529     * just insert label
1530     *-------------------------------------------------------------------------
1531     */
1532 
1533     else
1534     {
1535 
1536         if ((aid = H5Aopen(did, DIMENSION_LABELS, H5P_DEFAULT)) < 0)
1537             goto out;
1538 
1539         if ((tid = H5Aget_type(aid)) < 0)
1540             goto out;
1541 
1542         /* allocate and initialize */
1543         u.buf = (char **) HDmalloc((size_t) rank * sizeof(char *));
1544 
1545         if (u.buf == NULL)
1546             goto out;
1547 
1548         /* read */
1549         if (H5Aread(aid, tid, (void *)u.buf) < 0)
1550             goto out;
1551 
1552         /* free the ptr that will be replaced by label */
1553         if (u.buf[idx])
1554             HDfree(u.buf[idx]);
1555 
1556         /* store the label information in the required index */
1557         u.const_buf[idx] = label;
1558 
1559         /* write the attribute with the new references */
1560         if (H5Awrite(aid, tid, u.buf) < 0)
1561             goto out;
1562 
1563         /* label was brought in, so don't free */
1564         u.buf[idx] = NULL;
1565 
1566         /* free all the ptr's from the H5Aread() */
1567         for (i = 0; i < (unsigned int) rank; i++)
1568         {
1569             if (u.buf[i])
1570                 HDfree(u.buf[i]);
1571         }
1572 
1573         /* close */
1574         if (H5Tclose(tid) < 0)
1575             goto out;
1576         if (H5Aclose(aid) < 0)
1577             goto out;
1578         if (u.buf)
1579         {
1580             HDfree(u.buf);
1581             u.buf = NULL;
1582         }
1583     }
1584 
1585     return SUCCEED;
1586 
1587     /* error zone */
1588 
1589 out:
1590     if (u.buf)
1591     {
1592         if (u.buf[idx]) /* check if we errored during H5Awrite */
1593             u.buf[idx] = NULL; /* don't free label */
1594         /* free all the ptr's from the H5Aread() */
1595         for (i = 0; i < (unsigned int) rank; i++)
1596         {
1597             if (u.buf[i])
1598                 HDfree(u.buf[i]);
1599         }
1600         HDfree(u.buf);
1601     }
1602     H5E_BEGIN_TRY
1603     {
1604         H5Sclose(sid);
1605         H5Aclose(aid);
1606         H5Tclose(tid);
1607     }H5E_END_TRY;
1608     return FAIL;
1609 }
1610 
1611 /*-------------------------------------------------------------------------
1612 * Function: H5DSget_label
1613 *
1614 * Purpose: Read the label LABEL for dimension IDX of dataset DID
1615 *   Up to 'size' characters are stored in 'label' followed by a '\0' string
1616 *   terminator.  If the label is longer than 'size'-1,
1617 *   the string terminator is stored in the last position of the buffer to
1618 *   properly terminate the string.
1619 *
1620 * Return: 0 if no label found, size of label if found, Failure: FAIL
1621 *
1622 * Programmer: pvn@ncsa.uiuc.edu
1623 *
1624 * Date: January 11, 2005
1625 *
1626 * Comments:
1627 *
1628 * Modifications:
1629 *     JIRA HDFFV-7673: Added a check to see if the label name exists,
1630 *     if not then returns zero. July 30, 2011. MSB
1631 *
1632 *-------------------------------------------------------------------------
1633 */
H5DSget_label(hid_t did,unsigned int idx,char * label,size_t size)1634 ssize_t H5DSget_label(hid_t did, unsigned int idx, char *label, size_t size)
1635 {
1636     int        has_labels;
1637     hid_t      sid = -1;     /* space ID */
1638     hid_t      tid = -1;     /* attribute type ID */
1639     hid_t      aid = -1;     /* attribute ID */
1640     int        rank;         /* rank of dataset */
1641     char       **buf = NULL; /* buffer to store in the attribute */
1642     H5I_type_t it;           /* ID type */
1643     size_t     nbytes = 0;
1644     size_t     copy_len;
1645     int        i;
1646 
1647     /*-------------------------------------------------------------------------
1648     * parameter checking
1649     *-------------------------------------------------------------------------
1650     */
1651     /* get ID type */
1652     if ((it = H5Iget_type(did)) < 0)
1653         return FAIL;
1654 
1655     if (H5I_DATASET != it)
1656         return FAIL;
1657 
1658      /* get dataset space */
1659     if ((sid = H5Dget_space(did)) < 0)
1660         return FAIL;
1661 
1662     /* get rank */
1663     if ((rank = H5Sget_simple_extent_ndims(sid)) < 0)
1664         goto out;
1665 
1666     /* close dataset space */
1667     if (H5Sclose(sid) < 0)
1668         goto out;
1669 
1670     if ( idx >= (unsigned)rank )
1671         return FAIL;
1672 
1673     /*-------------------------------------------------------------------------
1674     * attribute "DIMENSION_LABELS"
1675     *-------------------------------------------------------------------------
1676     */
1677 
1678     /* try to find the attribute "DIMENSION_LABELS" on the >>data<< dataset */
1679     if ((has_labels = H5LT_find_attribute(did, DIMENSION_LABELS)) < 0)
1680         return FAIL;
1681 
1682     /* return 0 and NULL for label if no label found */
1683     if (has_labels == 0)
1684     {
1685         if (label)
1686             label[0] = 0;
1687         return 0;
1688     }
1689 
1690     /*-------------------------------------------------------------------------
1691     * open the attribute and read label
1692     *-------------------------------------------------------------------------
1693     */
1694 
1695     assert (has_labels == 1);
1696     if ((aid = H5Aopen(did, DIMENSION_LABELS, H5P_DEFAULT)) < 0)
1697         goto out;
1698 
1699 
1700     if ((tid = H5Aget_type(aid)) < 0)
1701         goto out;
1702 
1703     /* allocate and initialize */
1704     buf = (char **) HDmalloc((size_t) rank * sizeof(char *));
1705 
1706     if (buf == NULL)
1707         goto out;
1708 
1709     /* read */
1710     if (H5Aread(aid, tid, buf) < 0)
1711         goto out;
1712 
1713     /* do only if the label name exists for the dimension */
1714     if (buf[idx] != NULL)
1715     {
1716         /* get the real string length */
1717         nbytes = strlen(buf[idx]);
1718 
1719 	/* compute the string length which will fit into the user's buffer */
1720 	copy_len = MIN(size-1, nbytes);
1721 
1722 	/* copy all/some of the name */
1723 	if (label)
1724 	  {
1725 	    memcpy(label, buf[idx], copy_len);
1726 
1727 	    /* terminate the string */
1728 	    label[copy_len] = '\0';
1729 	  }
1730 
1731     }
1732     /* free all the ptr's from the H5Aread() */
1733     for (i = 0; i < rank; i++)
1734     {
1735         if (buf[i])
1736 	  HDfree(buf[i]);
1737     }
1738 
1739     /* close */
1740     if (H5Tclose(tid) < 0)
1741         goto out;
1742     if (H5Aclose(aid) < 0)
1743         goto out;
1744     if (buf)
1745     {
1746         HDfree(buf);
1747         buf = NULL;
1748     }
1749 
1750     return (ssize_t) nbytes;
1751 
1752     /* error zone */
1753 out:
1754     if (buf)
1755     {
1756         /* free all the ptr's from the H5Aread() */
1757         for (i = 0; i < rank; i++)
1758         {
1759             if (buf[i])
1760                 HDfree(buf[i]);
1761         }
1762         HDfree(buf);
1763     }
1764     H5E_BEGIN_TRY
1765     {
1766         H5Sclose(sid);
1767         H5Aclose(aid);
1768         H5Tclose(tid);
1769     }H5E_END_TRY;
1770     return FAIL;
1771 }
1772 
1773 /*-------------------------------------------------------------------------
1774 * Function: H5DSget_scale_name
1775 *
1776 * Purpose: Read the name of dataset scale DID into buffer NAME
1777 *   Up to 'size' characters are stored in 'name' followed by a '\0' string
1778 *   terminator.  If the name is longer than 'size'-1,
1779 *   the string terminator is stored in the last position of the buffer to
1780 *   properly terminate the string.
1781 *
1782 * Return: size of name if found, zero if not found,  Failure: FAIL
1783 *
1784 * Programmer: pvn@ncsa.uiuc.edu
1785 *
1786 * Date: January 04, 2005
1787 *
1788 * Comments:
1789 *
1790 * Modifications:
1791 *  The size of the name returned should not include the NULL termination
1792 *  in its value so as to be consistent with other HDF5 APIs.
1793 *
1794 *-------------------------------------------------------------------------
1795 */
1796 
H5DSget_scale_name(hid_t did,char * name,size_t size)1797 ssize_t H5DSget_scale_name(hid_t did,
1798                            char *name,
1799                            size_t size)
1800 {
1801     hid_t      aid;      /* attribute ID  */
1802     hid_t      tid = -1; /* attribute type ID */
1803     hid_t      sid;      /* space ID  */
1804     H5I_type_t it;       /* ID type */
1805     size_t     nbytes;
1806     size_t     copy_len;
1807     int        has_name;
1808     char       *buf=NULL;
1809 
1810     /*-------------------------------------------------------------------------
1811     * parameter checking
1812     *-------------------------------------------------------------------------
1813     */
1814     /* get ID type */
1815     if ((it = H5Iget_type(did)) < 0)
1816         return FAIL;
1817 
1818     if (H5I_DATASET!=it)
1819         return FAIL;
1820 
1821     if ((H5DSis_scale(did))<=0)
1822         return FAIL;
1823 
1824     /*-------------------------------------------------------------------------
1825     * check if the DS has a name
1826     *-------------------------------------------------------------------------
1827     */
1828 
1829     /* try to find the attribute "NAME" on the >>DS<< dataset */
1830     if ((has_name = H5LT_find_attribute(did, "NAME")) < 0)
1831         return FAIL;
1832 
1833     if (has_name == 0)
1834         return 0;
1835 
1836     /*-------------------------------------------------------------------------
1837     * open the attribute
1838     *-------------------------------------------------------------------------
1839     */
1840 
1841     if((aid = H5Aopen(did, "NAME", H5P_DEFAULT)) < 0)
1842         return FAIL;
1843 
1844     /* get space */
1845     if((sid = H5Aget_space(aid)) < 0)
1846         goto out;
1847 
1848     /* get type */
1849     if((tid = H5Aget_type(aid)) < 0)
1850         goto out;
1851 
1852     /* get the size */
1853     if((nbytes = H5Tget_size(tid)) == 0)
1854         goto out;
1855 
1856     /* allocate a temporary buffer */
1857     buf = (char*)HDmalloc(nbytes * sizeof(char));
1858     if (buf == NULL)
1859         goto out;
1860 
1861     /* read */
1862     if (H5Aread(aid,tid,buf) < 0)
1863         goto out;
1864 
1865     /* compute the string length which will fit into the user's buffer */
1866     copy_len = MIN(size-1, nbytes);
1867 
1868     /* copy all/some of the name */
1869     if (name) {
1870         memcpy(name, buf, copy_len);
1871 
1872         /* terminate the string */
1873         name[copy_len]='\0';
1874     }
1875 
1876     /* close */
1877     if (H5Tclose(tid) < 0)
1878         goto out;
1879     if (H5Aclose(aid) < 0)
1880         goto out;
1881     if (H5Sclose(sid) < 0)
1882         goto out;
1883     if (buf)
1884         HDfree(buf);
1885 
1886     return (ssize_t) MAX(0,nbytes-1);
1887 
1888     /* error zone */
1889 out:
1890     H5E_BEGIN_TRY {
1891         H5Aclose(aid);
1892         H5Tclose(tid);
1893         H5Sclose(sid);
1894     } H5E_END_TRY;
1895     if (buf)
1896         HDfree(buf);
1897     return FAIL;
1898 }
1899 
1900 /*-------------------------------------------------------------------------
1901 * Function: H5DSis_scale
1902 *
1903 * Purpose: check if the dataset DID is a dimension scale
1904 *
1905 * Return: 1, is, 0, not, FAIL, error
1906 *
1907 * Programmer: pvn@ncsa.uiuc.edu
1908 *
1909 * Date: January 04, 2005
1910 *
1911 * Comments:
1912 *
1913 * Modifications:
1914 *
1915 *-------------------------------------------------------------------------
1916 */
1917 
H5DSis_scale(hid_t did)1918 htri_t H5DSis_scale(hid_t did)
1919 {
1920     hid_t      tid = -1;   /* attribute type ID */
1921     hid_t      aid = -1;   /* attribute ID */
1922     herr_t     has_class;  /* has the "CLASS" attribute */
1923     htri_t     is_ds;      /* boolean return value */
1924     H5I_type_t it;           /* ID type */
1925     char       *buf;         /* Name of attribute */
1926     hsize_t    storage_size; /* Size of storage for attribute */
1927 
1928     /*-------------------------------------------------------------------------
1929     * parameter checking
1930     *-------------------------------------------------------------------------
1931     */
1932     /* get ID type */
1933     if ((it = H5Iget_type(did)) < 0)
1934         return FAIL;
1935 
1936     if(H5I_DATASET != it)
1937         return FAIL;
1938 
1939     /* try to find the attribute "CLASS" on the dataset */
1940     if((has_class = H5LT_find_attribute(did, "CLASS")) < 0)
1941         return FAIL;
1942 
1943     if(has_class == 0)
1944         is_ds = 0;
1945 
1946     else
1947     {
1948         if((aid = H5Aopen(did, "CLASS", H5P_DEFAULT)) < 0)
1949             goto out;
1950 
1951         if((tid = H5Aget_type(aid)) < 0)
1952             goto out;
1953 
1954 	/* check to make sure attribute is a string */
1955 	if(H5T_STRING != H5Tget_class(tid))
1956 	    goto out;
1957 
1958 	/* check to make sure string is null-terminated */
1959 	if(H5T_STR_NULLTERM != H5Tget_strpad(tid))
1960 	    goto out;
1961 
1962 	/* allocate buffer large enough to hold string */
1963 	if((storage_size = H5Aget_storage_size(aid)) == 0)
1964 	    goto out;
1965 
1966 	buf = (char*)HDmalloc( (size_t)storage_size * sizeof(char) + 1);
1967 	if(buf == NULL)
1968 	    goto out;
1969 
1970 	/* Read the attribute */
1971         if(H5Aread(aid, tid, buf) < 0)
1972 	    goto out;
1973 
1974 	/* compare strings */
1975         if(HDstrncmp(buf, DIMENSION_SCALE_CLASS, MIN(HDstrlen(DIMENSION_SCALE_CLASS),HDstrlen(buf)))==0)
1976             is_ds = 1;
1977         else
1978             is_ds = 0;
1979 
1980 	HDfree(buf);
1981 
1982         if(H5Tclose(tid) < 0)
1983             goto out;
1984 
1985         if (H5Aclose(aid) < 0)
1986             goto out;
1987 
1988 
1989     }
1990 
1991     return is_ds;
1992 
1993     /* error zone */
1994 out:
1995     H5E_BEGIN_TRY {
1996         H5Aclose(aid);
1997         H5Tclose(tid);
1998     } H5E_END_TRY;
1999     return FAIL;
2000 
2001 }
2002 
2003 /*-------------------------------------------------------------------------
2004 * Function: H5DSget_num_scales
2005 *
2006 * Purpose: get the number of scales linked to the IDX dimension of dataset DID
2007 *
2008 * Return:
2009 *   Success: number of scales
2010 *   Failure: FAIL
2011 *
2012 * Programmer: pvn@ncsa.uiuc.edu
2013 *
2014 * Date: January 13, 2005
2015 *
2016 * Comments:
2017 *
2018 * Modifications:
2019 *
2020 *-------------------------------------------------------------------------
2021 */
2022 
H5DSget_num_scales(hid_t did,unsigned int idx)2023 int H5DSget_num_scales(hid_t did,
2024                        unsigned int idx)
2025 {
2026     int        has_dimlist;
2027     hid_t      sid;          /* space ID */
2028     hid_t      tid = -1;     /* attribute type ID */
2029     hid_t      aid = -1;     /* attribute ID */
2030     int        rank;         /* rank of dataset */
2031     hvl_t      *buf = NULL;  /* VL buffer to store in the attribute */
2032     H5I_type_t it;           /* ID type */
2033     int        nscales;
2034 
2035     /*-------------------------------------------------------------------------
2036     * parameter checking
2037     *-------------------------------------------------------------------------
2038     */
2039     /* get ID type */
2040     if((it = H5Iget_type(did)) < 0)
2041         return FAIL;
2042 
2043     if(H5I_DATASET != it)
2044         return FAIL;
2045 
2046     /*-------------------------------------------------------------------------
2047     * the attribute "DIMENSION_LIST" on the >>data<< dataset must exist
2048     *-------------------------------------------------------------------------
2049     */
2050     /* get dataset space */
2051     if((sid = H5Dget_space(did)) < 0)
2052         return FAIL;
2053 
2054     /* get rank */
2055     if((rank = H5Sget_simple_extent_ndims(sid)) < 0)
2056         goto out;
2057 
2058     /* close dataset space */
2059     if(H5Sclose(sid) < 0)
2060         goto out;
2061 
2062     /* dimemsion index IDX range checking */
2063     if(idx >= (unsigned int )rank)
2064         return FAIL;
2065 
2066     /* try to find the attribute "DIMENSION_LIST" on the >>data<< dataset */
2067     if((has_dimlist = H5LT_find_attribute(did, DIMENSION_LIST)) < 0)
2068         return FAIL;
2069 
2070     /* it does not exist */
2071     if(has_dimlist == 0)
2072         return 0;
2073 
2074     /*-------------------------------------------------------------------------
2075     * the attribute exists, open it
2076     *-------------------------------------------------------------------------
2077     */
2078     else {
2079         if((aid = H5Aopen(did, DIMENSION_LIST, H5P_DEFAULT)) < 0)
2080             goto out;
2081         if((tid = H5Aget_type(aid)) < 0)
2082             goto out;
2083         if((sid = H5Aget_space(aid)) < 0)
2084             goto out;
2085 
2086         /* allocate and initialize the VL */
2087         buf = (hvl_t *)HDmalloc((size_t)rank * sizeof(hvl_t));
2088         if(buf == NULL)
2089             goto out;
2090 
2091         /* read */
2092         if(H5Aread(aid, tid, buf) < 0)
2093             goto out;
2094 
2095         nscales = (int)buf[idx].len;
2096 
2097         /* close */
2098         if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, buf) < 0)
2099             goto out;
2100         if(H5Sclose(sid) < 0)
2101             goto out;
2102         if(H5Tclose(tid) < 0)
2103             goto out;
2104         if(H5Aclose(aid) < 0)
2105             goto out;
2106         HDfree(buf);
2107         buf = NULL;
2108     } /* has_dimlist */
2109 
2110     return nscales;
2111 
2112     /* error zone */
2113 out:
2114     H5E_BEGIN_TRY {
2115         H5Sclose(sid);
2116         H5Aclose(aid);
2117         H5Tclose(tid);
2118     } H5E_END_TRY;
2119 
2120     if(buf)
2121         HDfree(buf);
2122 
2123     return FAIL;
2124 }
2125 
2126 /*-------------------------------------------------------------------------
2127 * Function: H5DS_is_reserved
2128 *
2129 * Purpose: Verify that a dataset's CLASS is either an image, palette or table
2130 *
2131 * Return: true, false, fail
2132 *
2133 * Programmer: pvn@ncsa.uiuc.edu
2134 *
2135 * Date: March 19, 2005
2136 *
2137 * Comments:
2138 *
2139 * Modifications:
2140 *
2141 *-------------------------------------------------------------------------
2142 */
2143 
2144 static
H5DS_is_reserved(hid_t did)2145 herr_t H5DS_is_reserved(hid_t did)
2146 {
2147     int    has_class;
2148     hid_t  tid = -1;
2149     hid_t  aid = -1;
2150     char *buf;            /* Name of attribute */
2151     hsize_t storage_size; /* Size of storage for attribute */
2152     herr_t ret;
2153 
2154     /* try to find the attribute "CLASS" on the dataset */
2155     if((has_class = H5LT_find_attribute(did, "CLASS")) < 0)
2156         return -1;
2157 
2158     if(has_class ==  0)
2159         return 0;
2160 
2161     assert(has_class ==  1);
2162     if((aid = H5Aopen(did, "CLASS", H5P_DEFAULT)) < 0)
2163         goto out;
2164 
2165     if((tid = H5Aget_type(aid)) < 0)
2166         goto out;
2167 
2168     /* check to make sure attribute is a string */
2169     if(H5T_STRING != H5Tget_class(tid))
2170       goto out;
2171 
2172     /* check to make sure string is null-terminated */
2173     if(H5T_STR_NULLTERM != H5Tget_strpad(tid))
2174       goto out;
2175 
2176     /* allocate buffer large enough to hold string */
2177     if((storage_size = H5Aget_storage_size(aid)) == 0)
2178       goto out;
2179 
2180     buf = (char*)HDmalloc( (size_t)storage_size * sizeof(char) + 1);
2181     if(buf == NULL)
2182       goto out;
2183 
2184     /* Read the attribute */
2185     if(H5Aread(aid, tid, buf) < 0)
2186       goto out;
2187 
2188 
2189     if(HDstrncmp(buf, IMAGE_CLASS, MIN(HDstrlen(IMAGE_CLASS),HDstrlen(buf))) == 0 ||
2190        HDstrncmp(buf, PALETTE_CLASS, MIN(HDstrlen(PALETTE_CLASS),HDstrlen(buf))) == 0 ||
2191        HDstrncmp(buf, TABLE_CLASS, MIN(HDstrlen(TABLE_CLASS),HDstrlen(buf))) == 0 )
2192         ret = 1;
2193     else
2194         ret = 0;
2195 
2196     HDfree(buf);
2197 
2198     if (H5Tclose(tid) < 0)
2199         goto out;
2200 
2201     if (H5Aclose(aid) < 0)
2202         goto out;
2203 
2204 
2205     return ret;
2206 
2207     /* error zone */
2208 out:
2209     H5E_BEGIN_TRY
2210     {
2211         H5Tclose(tid);
2212         H5Aclose(aid);
2213     } H5E_END_TRY;
2214     return FAIL;
2215 }
2216 
2217 /*-------------------------------------------------------------------------
2218 * Function: H5DS_get_REFLIST_type
2219 *
2220 * Purpose: This is a helper function to return a native type for
2221 *          the REFERENCE_LIST attribute.
2222 *
2223 * Return: Type identifier on success and negative on failure
2224 *
2225 * Programmer: epourmal@hdfgroup.org
2226 *
2227 * Date: May 22, 2010
2228 *
2229 * Comments:
2230 *
2231 * Modifications:
2232 *
2233 *-------------------------------------------------------------------------
2234 */
2235 
2236 static
H5DS_get_REFLIST_type(void)2237 hid_t H5DS_get_REFLIST_type(void)
2238 {
2239     hid_t ntid_t = -1;
2240 
2241     /* Build native type that corresponds to compound datatype
2242        used to store ds_list_t structure in the REFERENCE_LIST
2243        attribute */
2244 
2245     if((ntid_t = H5Tcreate(H5T_COMPOUND, sizeof(ds_list_t))) < 0)
2246         goto out;
2247 
2248     if(H5Tinsert(ntid_t, "dataset", HOFFSET(ds_list_t,ref), H5T_STD_REF_OBJ) < 0)
2249         goto out;
2250 
2251     if(H5Tinsert(ntid_t, "dimension", HOFFSET(ds_list_t, dim_idx), H5T_NATIVE_INT) < 0)
2252         goto out;
2253 
2254     return ntid_t;
2255 out:
2256     H5E_BEGIN_TRY {
2257         H5Tclose(ntid_t);
2258     } H5E_END_TRY;
2259     return FAIL;
2260 }
2261 
2262