1 #include "H5ATTR.h"
2 
3 #include "tables.h"
4 #include "utils.h"
5 #include "H5Zlzo.h"                    /* Import FILTER_LZO */
6 #include "H5Zbzip2.h"                  /* Import FILTER_BZIP2 */
7 #include "blosc_filter.h"              /* Import FILTER_BLOSC */
8 
9 #include <string.h>
10 #include <stdlib.h>
11 
12 /*-------------------------------------------------------------------------
13  *
14  * Public functions
15  *
16  *-------------------------------------------------------------------------
17  */
18 /*-------------------------------------------------------------------------
19  * Function: H5ARRAYmake
20  *
21  * Purpose: Creates and writes a dataset of a type type_id
22  *
23  * Return: Success: 0, Failure: -1
24  *
25  * Programmer: F. Alted. October 21, 2002
26  *
27  * Date: March 19, 2001
28  *
29  * Comments: Modified by F. Alted. November 07, 2003
30  *           Modified by A. Cobb. August 21, 2017 (track_times)
31  *
32  *-------------------------------------------------------------------------
33  */
34 
H5ARRAYmake(hid_t loc_id,const char * dset_name,const char * obversion,const int rank,const hsize_t * dims,int extdim,hid_t type_id,hsize_t * dims_chunk,void * fill_data,int compress,char * complib,int shuffle,int fletcher32,hbool_t track_times,const void * data)35 hid_t H5ARRAYmake(  hid_t loc_id,
36                     const char *dset_name,
37                     const char *obversion,
38                     const int rank,
39                     const hsize_t *dims,
40                     int   extdim,
41                     hid_t type_id,
42                     hsize_t *dims_chunk,
43                     void  *fill_data,
44                     int   compress,
45                     char  *complib,
46                     int   shuffle,
47                     int   fletcher32,
48 		    hbool_t track_times,
49                     const void *data)
50 {
51 
52  hid_t   dataset_id, space_id;
53  hsize_t *maxdims = NULL;
54  hid_t   plist_id = 0;
55  unsigned int cd_values[7];
56  int     blosc_compcode;
57  char    *blosc_compname = NULL;
58  int     chunked = 0;
59  int     i;
60 
61  /* Check whether the array has to be chunked or not */
62  if (dims_chunk) {
63    chunked = 1;
64  }
65 
66  if(chunked) {
67    maxdims = malloc(rank*sizeof(hsize_t));
68    if(!maxdims) return -1;
69 
70    for(i=0;i<rank;i++) {
71      if (i == extdim) {
72        maxdims[i] = H5S_UNLIMITED;
73      }
74      else {
75        maxdims[i] = dims[i] < dims_chunk[i] ? dims_chunk[i] : dims[i];
76      }
77    }
78  }
79 
80  /* Create the data space for the dataset. */
81  if ( (space_id = H5Screate_simple( rank, dims, maxdims )) < 0 )
82    return -1;
83 
84  /* Create dataset creation property list with default values */
85  plist_id = H5Pcreate (H5P_DATASET_CREATE);
86 
87  /* Enable or disable recording dataset times */
88  if ( H5Pset_obj_track_times( plist_id, track_times ) < 0 )
89    return -1;
90 
91  if (chunked) {
92    /* Modify dataset creation properties, i.e. enable chunking  */
93    if ( H5Pset_chunk ( plist_id, rank, dims_chunk ) < 0 )
94      return -1;
95 
96    /* Set the fill value using a struct as the data type. */
97    if (fill_data) {
98      if ( H5Pset_fill_value( plist_id, type_id, fill_data ) < 0 )
99        return -1;
100    }
101    else {
102      if ( H5Pset_fill_time(plist_id, H5D_FILL_TIME_ALLOC) < 0 )
103        return -1;
104    }
105 
106    /*
107       Dataset creation property list is modified to use
108    */
109 
110    /* Fletcher must be first */
111    if (fletcher32) {
112      if ( H5Pset_fletcher32( plist_id) < 0 )
113        return -1;
114    }
115    /* Then shuffle (blosc shuffles inplace) */
116    if ((shuffle && compress) && (strncmp(complib, "blosc", 5) != 0)) {
117      if ( H5Pset_shuffle( plist_id) < 0 )
118        return -1;
119    }
120    /* Finally compression */
121    if (compress) {
122      cd_values[0] = compress;
123      cd_values[1] = (int)(atof(obversion) * 10);
124      if (extdim <0)
125        cd_values[2] = CArray;
126      else
127        cd_values[2] = EArray;
128 
129      /* The default compressor in HDF5 (zlib) */
130      if (strcmp(complib, "zlib") == 0) {
131        if ( H5Pset_deflate( plist_id, compress) < 0 )
132          return -1;
133      }
134      /* The Blosc compressor does accept parameters */
135      else if (strcmp(complib, "blosc") == 0) {
136        cd_values[4] = compress;
137        cd_values[5] = shuffle;
138        if ( H5Pset_filter( plist_id, FILTER_BLOSC, H5Z_FLAG_OPTIONAL, 6, cd_values) < 0 )
139          return -1;
140      }
141      /* The Blosc compressor can use other compressors */
142      else if (strncmp(complib, "blosc:", 6) == 0) {
143        cd_values[4] = compress;
144        cd_values[5] = shuffle;
145        blosc_compname = complib + 6;
146        blosc_compcode = blosc_compname_to_compcode(blosc_compname);
147        cd_values[6] = blosc_compcode;
148        if ( H5Pset_filter( plist_id, FILTER_BLOSC, H5Z_FLAG_OPTIONAL, 7, cd_values) < 0 )
149          return -1;
150      }
151      /* The LZO compressor does accept parameters */
152      else if (strcmp(complib, "lzo") == 0) {
153        if ( H5Pset_filter( plist_id, FILTER_LZO, H5Z_FLAG_OPTIONAL, 3, cd_values) < 0 )
154          return -1;
155      }
156      /* The bzip2 compress does accept parameters */
157      else if (strcmp(complib, "bzip2") == 0) {
158        if ( H5Pset_filter( plist_id, FILTER_BZIP2, H5Z_FLAG_OPTIONAL, 3, cd_values) < 0 )
159          return -1;
160      }
161      else {
162        /* Compression library not supported */
163        fprintf(stderr, "Compression library not supported\n");
164        return -1;
165      }
166    }
167 
168    /* Create the (chunked) dataset */
169    if ((dataset_id = H5Dcreate(loc_id, dset_name, type_id, space_id,
170                                H5P_DEFAULT, plist_id, H5P_DEFAULT )) < 0 )
171      goto out;
172  }
173  else {         /* Not chunked case */
174    /* Create the dataset. */
175    if ((dataset_id = H5Dcreate(loc_id, dset_name, type_id, space_id,
176                                H5P_DEFAULT, plist_id, H5P_DEFAULT )) < 0 )
177      goto out;
178  }
179 
180  /* Write the dataset only if there is data to write */
181 
182  if (data)
183  {
184    if ( H5Dwrite( dataset_id, type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, data ) < 0 )
185    goto out;
186  }
187 
188  /* Terminate access to the data space. */
189  if ( H5Sclose( space_id ) < 0 )
190   return -1;
191 
192  /* End access to the property list */
193  if (plist_id)
194    if ( H5Pclose( plist_id ) < 0 )
195      goto out;
196 
197  /* Release resources */
198  if (maxdims)
199    free(maxdims);
200 
201  return dataset_id;
202 
203 out:
204  H5Dclose( dataset_id );
205  H5Sclose( space_id );
206  if (maxdims)
207    free(maxdims);
208  if (dims_chunk)
209    free(dims_chunk);
210  return -1;
211 
212 }
213 
214 
215 /*-------------------------------------------------------------------------
216  * Function: H5ARRAYappend_records
217  *
218  * Purpose: Appends records to an array
219  *
220  * Return: Success: 0, Failure: -1
221  *
222  * Programmers:
223  *  Francesc Alted
224  *
225  * Date: October 30, 2003
226  *
227  * Comments: Uses memory offsets
228  *
229  * Modifications:
230  *
231  *
232  *-------------------------------------------------------------------------
233  */
234 
235 
H5ARRAYappend_records(hid_t dataset_id,hid_t type_id,const int rank,hsize_t * dims_orig,hsize_t * dims_new,int extdim,const void * data)236 herr_t H5ARRAYappend_records( hid_t dataset_id,
237                               hid_t type_id,
238                               const int rank,
239                               hsize_t *dims_orig,
240                               hsize_t *dims_new,
241                               int extdim,
242                               const void *data )
243 {
244 
245  hid_t    space_id;
246  hid_t    mem_space_id;
247  hsize_t  *dims = NULL;         /* Shut up the compiler */
248  hsize_t  *start = NULL;        /* Shut up the compiler */
249  int      i;
250 
251  /* Compute the arrays for new dimensions and coordinates and extents */
252  dims = malloc(rank*sizeof(hsize_t));
253  start = malloc(rank*sizeof(hsize_t));
254  for(i=0;i<rank;i++) {
255    dims[i] = dims_orig[i];
256    start[i] = 0;
257  }
258  dims[extdim] += dims_new[extdim];
259  start[extdim] = (hsize_t )dims_orig[extdim];
260 
261  /* Extend the dataset */
262  if ( H5Dset_extent( dataset_id, dims ) < 0 )
263   goto out;
264 
265  /* Create a simple memory data space */
266  if ( (mem_space_id = H5Screate_simple( rank, dims_new, NULL )) < 0 )
267   return -1;
268 
269  /* Get the file data space */
270  if ( (space_id = H5Dget_space( dataset_id )) < 0 )
271   return -1;
272 
273  /* Define a hyperslab in the dataset */
274  if ( H5Sselect_hyperslab( space_id, H5S_SELECT_SET, start, NULL, dims_new, NULL) < 0 )
275    goto out;
276 
277  if ( H5Dwrite( dataset_id, type_id, mem_space_id, space_id, H5P_DEFAULT, data ) < 0 )
278      goto out;
279 
280  /* Update the original dimensions of the array after a successful append */
281  dims_orig[extdim] += dims_new[extdim];
282 
283  /* Terminate access to the dataspace */
284  if ( H5Sclose( mem_space_id ) < 0 )
285   goto out;
286 
287  if ( H5Sclose( space_id ) < 0 )
288   goto out;
289 
290  /* Release resources */
291  free(start);
292  free(dims);
293 
294 return 0;
295 
296 out:
297  if (start) free(start);
298  if (dims) free(dims);
299  return -1;
300 
301 }
302 
303 
304 /*-------------------------------------------------------------------------
305  * Function: H5ARRAYwrite_records
306  *
307  * Purpose: Write records to an array
308  *
309  * Return: Success: 0, Failure: -1
310  *
311  * Programmers:
312  *  Francesc Alted
313  *
314  * Date: October 26, 2004
315  *
316  * Comments: Uses memory offsets
317  *
318  * Modifications: Norbert Nemec for dealing with arrays of zero dimensions
319  *                Date: Wed, 15 Dec 2004 18:48:07 +0100
320  *
321  *
322  *-------------------------------------------------------------------------
323  */
324 
325 
H5ARRAYwrite_records(hid_t dataset_id,hid_t type_id,const int rank,hsize_t * start,hsize_t * step,hsize_t * count,const void * data)326 herr_t H5ARRAYwrite_records( hid_t dataset_id,
327                              hid_t type_id,
328                              const int rank,
329                              hsize_t *start,
330                              hsize_t *step,
331                              hsize_t *count,
332                              const void *data )
333 {
334 
335  hid_t    space_id;
336  hid_t    mem_space_id;
337 
338  /* Create a simple memory data space */
339  if ( (mem_space_id = H5Screate_simple( rank, count, NULL )) < 0 )
340    return -3;
341 
342  /* Get the file data space */
343  if ( (space_id = H5Dget_space( dataset_id )) < 0 )
344   return -4;
345 
346  /* Define a hyperslab in the dataset */
347  if ( rank != 0 && H5Sselect_hyperslab( space_id, H5S_SELECT_SET, start,
348                                         step, count, NULL) < 0 )
349   return -5;
350 
351  if ( H5Dwrite( dataset_id, type_id, mem_space_id, space_id, H5P_DEFAULT, data ) < 0 )
352    return -6;
353 
354  /* Terminate access to the dataspace */
355  if ( H5Sclose( mem_space_id ) < 0 )
356    return -7;
357 
358  if ( H5Sclose( space_id ) < 0 )
359    return -8;
360 
361  /* Everything went smoothly */
362  return 0;
363 }
364 
365 
366 /*-------------------------------------------------------------------------
367  * Function: H5ARRAYread
368  *
369  * Purpose: Reads an array from disk.
370  *
371  * Return: Success: 0, Failure: -1
372  *
373  * Programmer: Francesc Alted, faltet@pytables.com
374  *
375  * Date: October 22, 2002
376  *
377  *-------------------------------------------------------------------------
378  */
379 
H5ARRAYread(hid_t dataset_id,hid_t type_id,hsize_t start,hsize_t nrows,hsize_t step,int extdim,void * data)380 herr_t H5ARRAYread( hid_t dataset_id,
381                     hid_t type_id,
382                     hsize_t start,
383                     hsize_t nrows,
384                     hsize_t step,
385                     int extdim,
386                     void *data )
387 {
388 
389  hid_t    space_id;
390  hid_t    mem_space_id;
391  hsize_t  *dims = NULL;
392  hsize_t  *count = NULL;
393  hsize_t  *stride = NULL;
394  hsize_t  *offset = NULL;
395  int      rank;
396  int      i;
397  int      _extdim;
398 
399 
400  /* If dataset is not extensible, choose the first dimension as selectable */
401  if (extdim < 0)
402    _extdim = 0;
403  else
404    _extdim = extdim;
405 
406   /* Get the dataspace handle */
407  if ( (space_id = H5Dget_space( dataset_id )) < 0 )
408   goto out;
409 
410  /* Get the rank */
411  if ( (rank = H5Sget_simple_extent_ndims(space_id)) < 0 )
412    goto out;
413 
414  if (rank) {                    /* Array case */
415 
416    /* Book some memory for the selections */
417    dims = (hsize_t *)malloc(rank*sizeof(hsize_t));
418    count = (hsize_t *)malloc(rank*sizeof(hsize_t));
419    stride = (hsize_t *)malloc(rank*sizeof(hsize_t));
420    offset = (hsize_t  *)malloc(rank*sizeof(hsize_t));
421 
422    /* Get dataset dimensionality */
423    if ( H5Sget_simple_extent_dims( space_id, dims, NULL) < 0 )
424      goto out;
425 
426    if ( start + nrows > dims[_extdim] ) {
427      printf("Asking for a range of rows exceeding the available ones!.\n");
428      goto out;
429    }
430 
431    /* Define a hyperslab in the dataset of the size of the records */
432    for (i=0; i<rank;i++) {
433      offset[i] = 0;
434      count[i] = dims[i];
435      stride[i] = 1;
436      /*    printf("dims[%d]: %d\n",i, (int)dims[i]); */
437    }
438    offset[_extdim] = start;
439    count[_extdim]  = nrows;
440    stride[_extdim] = step;
441    if ( H5Sselect_hyperslab( space_id, H5S_SELECT_SET, offset, stride, count, NULL) < 0 )
442      goto out;
443 
444    /* Create a memory dataspace handle */
445    if ( (mem_space_id = H5Screate_simple( rank, count, NULL )) < 0 )
446      goto out;
447 
448    /* Read */
449    if ( H5Dread( dataset_id, type_id, mem_space_id, space_id, H5P_DEFAULT, data ) < 0 )
450      goto out;
451 
452    /* Release resources */
453    free(dims);
454    free(count);
455    free(stride);
456    free(offset);
457 
458    /* Terminate access to the memory dataspace */
459    if ( H5Sclose( mem_space_id ) < 0 )
460      goto out;
461  }
462  else {                 /* Scalar case */
463 
464    /* Read all the dataset */
465    if (H5Dread(dataset_id, type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, data) < 0)
466      goto out;
467  }
468 
469    /* Terminate access to the dataspace */
470  if ( H5Sclose( space_id ) < 0 )
471   goto out;
472 
473  return 0;
474 
475 out:
476  if (dims) free(dims);
477  if (count) free(count);
478  if (stride) free(stride);
479  if (offset) free(offset);
480  return -1;
481 
482 }
483 
484 
485 /*-------------------------------------------------------------------------
486  * Function: H5ARRAYreadSlice
487  *
488  * Purpose: Reads a slice of array from disk.
489  *
490  * Return: Success: 0, Failure: -1
491  *
492  * Programmer: Francesc Alted, faltet@pytables.com
493  *
494  * Date: December 16, 2003
495  *
496  *-------------------------------------------------------------------------
497  */
498 
H5ARRAYreadSlice(hid_t dataset_id,hid_t type_id,hsize_t * start,hsize_t * stop,hsize_t * step,void * data)499 herr_t H5ARRAYreadSlice( hid_t dataset_id,
500                          hid_t type_id,
501                          hsize_t *start,
502                          hsize_t *stop,
503                          hsize_t *step,
504                          void *data )
505 {
506 
507  hid_t    space_id;
508  hid_t    mem_space_id;
509  hsize_t  *dims = NULL;
510  hsize_t  *count = NULL;
511  hsize_t  *stride = (hsize_t *)step;
512  hsize_t  *offset = (hsize_t *)start;
513  int      rank;
514  int      i;
515 
516   /* Get the dataspace handle */
517  if ( (space_id = H5Dget_space( dataset_id )) < 0 )
518   goto out;
519 
520  /* Get the rank */
521  if ( (rank = H5Sget_simple_extent_ndims(space_id)) < 0 )
522    goto out;
523 
524  if (rank) {                    /* Array case */
525 
526    /* Book some memory for the selections */
527    dims = (hsize_t *)malloc(rank*sizeof(hsize_t));
528    count = (hsize_t *)malloc(rank*sizeof(hsize_t));
529 
530    /* Get dataset dimensionality */
531    if ( H5Sget_simple_extent_dims( space_id, dims, NULL) < 0 )
532      goto out;
533 
534    for(i=0;i<rank;i++) {
535      count[i] = get_len_of_range(start[i], stop[i], step[i]);
536      if ( stop[i] > dims[i] ) {
537        printf("Asking for a range of rows exceeding the available ones!.\n");
538        goto out;
539      }
540    }
541 
542    /* Define a hyperslab in the dataset of the size of the records */
543    if ( H5Sselect_hyperslab( space_id, H5S_SELECT_SET, offset, stride,
544                              count, NULL) < 0 )
545      goto out;
546 
547    /* Create a memory dataspace handle */
548    if ( (mem_space_id = H5Screate_simple( rank, count, NULL )) < 0 )
549      goto out;
550 
551    /* Read */
552    if ( H5Dread( dataset_id, type_id, mem_space_id, space_id, H5P_DEFAULT,
553                  data ) < 0 )
554      goto out;
555 
556    /* Release resources */
557    free(dims);
558    free(count);
559 
560    /* Terminate access to the memory dataspace */
561    if ( H5Sclose( mem_space_id ) < 0 )
562      goto out;
563  }
564  else {                     /* Scalar case */
565 
566    /* Read all the dataset */
567    if (H5Dread(dataset_id, type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, data) < 0)
568      goto out;
569  }
570 
571    /* Terminate access to the dataspace */
572  if ( H5Sclose( space_id ) < 0 )
573   goto out;
574 
575  return 0;
576 
577 out:
578 /*  H5Dclose( dataset_id ); */
579  if (dims) free(dims);
580  if (count) free(count);
581  return -1;
582 
583 }
584 
585 
586 /*   The next represents a try to implement getCoords for != operator */
587 /*   but it turned out to be too difficult, well, at least to me :( */
588 /*   2004-06-22 */
589 /*-------------------------------------------------------------------------
590  * Function: H5ARRAYreadIndex
591  *
592  * Purpose: Reads a slice of array from disk for indexing purposes.
593  *
594  * Return: Success: 0, Failure: -1
595  *
596  * Programmer: Francesc Alted, faltet@pytables.com
597  *
598  * Date: June 21, 2004
599  *
600  *-------------------------------------------------------------------------
601  */
602 
H5ARRAYreadIndex(hid_t dataset_id,hid_t type_id,int notequal,hsize_t * start,hsize_t * stop,hsize_t * step,void * data)603 herr_t H5ARRAYreadIndex( hid_t   dataset_id,
604                          hid_t   type_id,
605                          int     notequal,
606                          hsize_t *start,
607                          hsize_t *stop,
608                          hsize_t *step,
609                          void    *data )
610 {
611 
612  hid_t    mem_space_id;
613  hid_t    space_id;
614  hsize_t  *dims = NULL;
615  hsize_t  *count = NULL;
616  hsize_t  *count2 = NULL;
617  hsize_t  *offset2 = NULL;
618  hsize_t  *stride = (hsize_t *)step;
619  hsize_t  *offset = (hsize_t *)start;
620  int      rank;
621  int      i;
622 
623   /* Get the dataspace handle */
624  if ( (space_id = H5Dget_space( dataset_id )) < 0 )
625   goto out;
626 
627  /* Get the rank */
628  if ( (rank = H5Sget_simple_extent_ndims(space_id)) < 0 )
629    goto out;
630 
631  if (rank) {                    /* Array case */
632 
633    /* Book some memory for the selections */
634    dims = (hsize_t *)malloc(rank*sizeof(hsize_t));
635    count = (hsize_t *)malloc(rank*sizeof(hsize_t));
636    count2 = (hsize_t *)malloc(rank*sizeof(hsize_t));
637    offset2 = (hsize_t *)malloc(rank*sizeof(hsize_t));
638 
639    /* Get dataset dimensionality */
640    if ( H5Sget_simple_extent_dims( space_id, dims, NULL) < 0 )
641      goto out;
642 
643    for(i=0;i<rank;i++) {
644      count[i] = get_len_of_range(start[i], stop[i], step[i]);
645      if ( stop[i] > dims[i] ) {
646        printf("Asking for a range of rows exceeding the available ones!.\n");
647        goto out;
648      }
649    }
650 
651    /* Define a hyperslab in the dataset of the size of the records */
652    if ( H5Sselect_hyperslab( space_id, H5S_SELECT_SET, offset, stride,
653                              count, NULL) < 0 )
654      goto out;
655 
656    /* If we want the complementary, do a NOTA against all the row */
657    if (notequal) {
658      offset2[0] = offset[0]; count2[0] = count[0];
659      offset2[1] = 0; count2[1] = dims[1]; /* All the row */
660      count[0] = 1; count[1] = dims[1] - count[1]; /* For memory dataspace */
661      if ( H5Sselect_hyperslab( space_id, H5S_SELECT_NOTA, offset2, stride,
662                                count2, NULL) < 0 )
663        goto out;
664    }
665 
666    /* Create a memory dataspace handle */
667    if ( (mem_space_id = H5Screate_simple( rank, count, NULL )) < 0 )
668      goto out;
669 
670    /* Read */
671    if ( H5Dread( dataset_id, type_id, mem_space_id, space_id, H5P_DEFAULT, data ) < 0 )
672      goto out;
673 
674    /* Release resources */
675    free(dims);
676    free(count);
677    free(offset2);
678    free(count2);
679 
680    /* Terminate access to the memory dataspace */
681    if ( H5Sclose( mem_space_id ) < 0 )
682      goto out;
683  }
684  else {                         /* Scalar case */
685 
686    /* Read all the dataset */
687    if (H5Dread(dataset_id, type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, data) < 0)
688      goto out;
689  }
690 
691    /* Terminate access to the dataspace */
692  if ( H5Sclose( space_id ) < 0 )
693   goto out;
694 
695  return 0;
696 
697 out:
698  if (dims) free(dims);
699  if (count) free(count);
700  return -1;
701 
702 }
703 
704 
705 
706 /*-------------------------------------------------------------------------
707  * Function: H5ARRAYget_ndims
708  *
709  * Purpose: Gets the dimensionality of an array.
710  *
711  * Return: Success: 0, Failure: -1
712  *
713  * Programmer: Francesc Alted
714  *
715  * Date: October 22, 2002
716  *
717  * Modification: October 13, 2008
718  *   This routine not longer returns the dimensionality of data types
719  *   in case they are H5T_ARRAY.
720  *
721  *-------------------------------------------------------------------------
722  */
723 
H5ARRAYget_ndims(hid_t dataset_id,int * rank)724 herr_t H5ARRAYget_ndims( hid_t dataset_id,
725                          int *rank )
726 {
727   hid_t       space_id;
728 
729   /* Get the dataspace handle */
730   if ( (space_id = H5Dget_space( dataset_id )) < 0 )
731     goto out;
732 
733   /* Get rank */
734   if ( (*rank = H5Sget_simple_extent_ndims( space_id )) < 0 )
735     goto out;
736 
737   /* Terminate access to the dataspace */
738   if ( H5Sclose( space_id ) < 0 )
739     goto out;
740 
741 
742   return 0;
743 
744 out:
745   return -1;
746 
747 }
748 
749 
750 
751 /* Modified version of H5LTget_dataset_info. */
752 
H5ARRAYget_info(hid_t dataset_id,hid_t type_id,hsize_t * dims,hsize_t * maxdims,H5T_class_t * class_id,char * byteorder)753 herr_t H5ARRAYget_info( hid_t dataset_id,
754                         hid_t type_id,
755                         hsize_t *dims,
756                         hsize_t *maxdims,
757                         H5T_class_t *class_id,
758                         char *byteorder)
759 {
760   hid_t       space_id;
761 
762   /* Get the class. */
763   *class_id = H5Tget_class( type_id );
764 
765   /* Get the dataspace handle */
766   if ( (space_id = H5Dget_space( dataset_id )) < 0 )
767     goto out;
768 
769   /* Get dimensions */
770   if ( H5Sget_simple_extent_dims( space_id, dims, maxdims) < 0 )
771     goto out;
772 
773   /* Terminate access to the dataspace */
774   if ( H5Sclose( space_id ) < 0 )
775     goto out;
776 
777   /* Get the byteorder */
778   /* Only integer, float, time, enumerate and array classes can be
779      byteordered */
780   if ((*class_id == H5T_INTEGER) || (*class_id == H5T_FLOAT)
781       || (*class_id == H5T_BITFIELD) || (*class_id == H5T_COMPOUND)
782       || (*class_id == H5T_TIME) || (*class_id == H5T_ENUM)
783       || (*class_id == H5T_ARRAY)) {
784     get_order(type_id, byteorder);
785   }
786   else {
787     strcpy(byteorder, "irrelevant");
788   }
789 
790   return 0;
791 
792 out:
793  return -1;
794 
795 }
796 
797 
798 
799 /*-------------------------------------------------------------------------
800  * Function: H5ARRAYget_chunkshape
801  *
802  * Purpose: Gets the chunkshape of a dataset.
803  *
804  * Return: Success: 0, Failure: -1
805  *
806  * Programmer: Francesc Alted
807  *
808  * Date: May 20, 2004
809  *
810  *-------------------------------------------------------------------------
811  */
812 
H5ARRAYget_chunkshape(hid_t dataset_id,int rank,hsize_t * dims_chunk)813 herr_t H5ARRAYget_chunkshape( hid_t dataset_id,
814                               int rank,
815                               hsize_t *dims_chunk)
816 {
817   hid_t        plist_id;
818   H5D_layout_t layout;
819 
820   /* Get creation properties list */
821   if ( (plist_id = H5Dget_create_plist( dataset_id )) < 0 )
822     goto out;
823 
824   /* Get the dataset layout */
825   layout = H5Pget_layout(plist_id);
826   if (layout != H5D_CHUNKED) {
827     H5Pclose( plist_id );
828     return -1;
829   }
830 
831   /* Get the chunkshape for all dimensions */
832   if (H5Pget_chunk(plist_id, rank, dims_chunk ) < 0 )
833     goto out;
834 
835  /* Terminate access to the datatype */
836  if ( H5Pclose( plist_id ) < 0 )
837   goto out;
838 
839  return 0;
840 
841 out:
842  if (dims_chunk) free(dims_chunk);
843  return -1;
844 
845 }
846 
847 
848 /*-------------------------------------------------------------------------
849  * Function: H5ARRAYget_fill_value
850  *
851  * Purpose: Gets the fill value of a dataset.
852  *
853  * Return: Success: 0, Failure: -1
854  *
855  * Programmer: Francesc Alted
856  *
857  * Date: Mar 03, 2009
858  *
859  *-------------------------------------------------------------------------
860  */
861 
H5ARRAYget_fill_value(hid_t dataset_id,hid_t type_id,int * status,void * value)862 herr_t H5ARRAYget_fill_value( hid_t dataset_id,
863                               hid_t type_id,
864                               int *status,
865                               void *value)
866 {
867   hid_t        plist_id;
868 
869   /* Get creation properties list */
870   if ( (plist_id = H5Dget_create_plist(dataset_id)) < 0 )
871     goto out;
872 
873   /* How the fill value is defined? */
874   if ( (H5Pfill_value_defined(plist_id, status)) < 0 )
875     goto out;
876 
877   if ( *status == H5D_FILL_VALUE_USER_DEFINED ) {
878     if ( H5Pget_fill_value(plist_id, type_id, value) < 0 )
879       goto out;
880   }
881 
882   /* Terminate access to the datatype */
883   if ( H5Pclose( plist_id ) < 0 )
884     goto out;
885 
886   return 0;
887 
888 out:
889   return -1;
890 
891 }
892