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