1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /****************/
15 /* Module Setup */
16 /****************/
17
18 #define H5S_PACKAGE /*suppress error about including H5Spkg */
19
20 /* Interface initialization */
21 #define H5_INTERFACE_INIT_FUNC H5S_init_interface
22
23
24 /***********/
25 /* Headers */
26 /***********/
27 #include "H5private.h" /* Generic Functions */
28 #include "H5Eprivate.h" /* Error handling */
29 #include "H5Fprivate.h" /* Files */
30 #include "H5FLprivate.h" /* Free lists */
31 #include "H5Iprivate.h" /* IDs */
32 #include "H5MMprivate.h" /* Memory management */
33 #include "H5Oprivate.h" /* Object headers */
34 #include "H5Spkg.h" /* Dataspaces */
35
36
37 /****************/
38 /* Local Macros */
39 /****************/
40
41 /* Version of datatype encoding */
42 #define H5S_ENCODE_VERSION 0
43
44
45 /******************/
46 /* Local Typedefs */
47 /******************/
48
49
50 /********************/
51 /* Local Prototypes */
52 /********************/
53 static herr_t H5S_set_extent_simple (H5S_t *space, unsigned rank,
54 const hsize_t *dims, const hsize_t *max);
55 static htri_t H5S_is_simple(const H5S_t *sdim);
56 static herr_t H5S_encode(H5S_t *obj, unsigned char *buf, size_t *nalloc);
57 static H5S_t *H5S_decode(const unsigned char *buf);
58
59
60 /*********************/
61 /* Package Variables */
62 /*********************/
63
64
65 /*****************************/
66 /* Library Private Variables */
67 /*****************************/
68
69
70 /*******************/
71 /* Local Variables */
72 /*******************/
73
74 /* Declare a free list to manage the H5S_extent_t struct */
75 H5FL_DEFINE(H5S_extent_t);
76
77 /* Declare a free list to manage the H5S_t struct */
78 H5FL_DEFINE(H5S_t);
79
80 /* Declare a free list to manage the array's of hsize_t's */
81 H5FL_ARR_DEFINE(hsize_t,H5S_MAX_RANK);
82
83 /* Dataspace ID class */
84 static const H5I_class_t H5I_DATASPACE_CLS[1] = {{
85 H5I_DATASPACE, /* ID class value */
86 H5I_CLASS_REUSE_IDS, /* Class flags */
87 2, /* # of reserved IDs for class */
88 (H5I_free_t)H5S_close /* Callback routine for closing objects of this class */
89 }};
90
91
92
93 /*--------------------------------------------------------------------------
94 NAME
95 H5S_init_interface -- Initialize interface-specific information
96 USAGE
97 herr_t H5S_init_interface()
98
99 RETURNS
100 Non-negative on success/Negative on failure
101 DESCRIPTION
102 Initializes any interface-specific data or routines.
103
104 --------------------------------------------------------------------------*/
105 static herr_t
H5S_init_interface(void)106 H5S_init_interface(void)
107 {
108 herr_t ret_value = SUCCEED; /* Return value */
109
110 FUNC_ENTER_NOAPI_NOINIT
111
112 /* Initialize the atom group for the file IDs */
113 if(H5I_register_type(H5I_DATASPACE_CLS) < 0)
114 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize interface")
115
116 done:
117 FUNC_LEAVE_NOAPI(ret_value)
118 } /* end H5S_init_interface() */
119
120
121 /*--------------------------------------------------------------------------
122 NAME
123 H5S_term_interface
124 PURPOSE
125 Terminate various H5S objects
126 USAGE
127 void H5S_term_interface()
128 RETURNS
129 Non-negative on success/Negative on failure
130 DESCRIPTION
131 Release the atom group and any other resources allocated.
132 GLOBAL VARIABLES
133 COMMENTS, BUGS, ASSUMPTIONS
134 Can't report errors...
135 EXAMPLES
136 REVISION LOG
137 --------------------------------------------------------------------------*/
138 int
H5S_term_interface(void)139 H5S_term_interface(void)
140 {
141 int n = 0;
142
143 FUNC_ENTER_NOAPI_NOINIT_NOERR
144
145 if(H5_interface_initialize_g) {
146 if(H5I_nmembers(H5I_DATASPACE) > 0) {
147 (void)H5I_clear_type(H5I_DATASPACE, FALSE, FALSE);
148 n++; /*H5I*/
149 } /* end if */
150 else {
151 /* Destroy the dataspace object id group */
152 (void)H5I_dec_type_ref(H5I_DATASPACE);
153 n++; /*H5I*/
154
155 /* Shut down interface */
156 H5_interface_initialize_g = 0;
157 } /* end else */
158 } /* end if */
159
160 FUNC_LEAVE_NOAPI(n)
161 } /* end H5S_term_interface() */
162
163
164 /*--------------------------------------------------------------------------
165 NAME
166 H5S_create
167 PURPOSE
168 Create empty, typed dataspace
169 USAGE
170 H5S_t *H5S_create(type)
171 H5S_type_t type; IN: Dataspace type to create
172 RETURNS
173 Pointer to dataspace on success, NULL on failure
174 DESCRIPTION
175 Creates a new dataspace of a given type. The extent is undefined and the
176 selection is set to the "all" selection.
177 GLOBAL VARIABLES
178 COMMENTS, BUGS, ASSUMPTIONS
179 EXAMPLES
180 REVISION LOG
181 --------------------------------------------------------------------------*/
182 H5S_t *
H5S_create(H5S_class_t type)183 H5S_create(H5S_class_t type)
184 {
185 H5S_t *new_ds = NULL; /* New dataspace created */
186 H5S_t *ret_value; /* Return value */
187
188 FUNC_ENTER_NOAPI(NULL)
189
190 /* Create a new dataspace */
191 if(NULL == (new_ds = H5FL_CALLOC(H5S_t)))
192 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
193
194 /* Initialize default dataspace state */
195 new_ds->extent.type = type;
196 if(type == H5S_NULL)
197 new_ds->extent.version = H5O_SDSPACE_VERSION_2;
198 else
199 new_ds->extent.version = H5O_SDSPACE_VERSION_1;
200 new_ds->extent.rank = 0;
201 new_ds->extent.size = new_ds->extent.max = NULL;
202
203 switch(type) {
204 case H5S_SCALAR:
205 new_ds->extent.nelem = 1;
206 break;
207
208 case H5S_SIMPLE:
209 case H5S_NULL:
210 new_ds->extent.nelem = 0;
211 break;
212
213 case H5S_NO_CLASS:
214 default:
215 HDassert("unknown dataspace (extent) type" && 0);
216 break;
217 } /* end switch */
218
219 /* Start with "all" selection */
220 if(H5S_select_all(new_ds, FALSE) < 0)
221 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection")
222
223 /* Reset common selection info pointer */
224 new_ds->select.sel_info.hslab = NULL;
225
226 /* Reset "shared" info on extent */
227 if(H5O_msg_reset_share(H5O_SDSPACE_ID, &(new_ds->extent.sh_loc)) < 0)
228 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRESET, NULL, "unable to reset shared component info")
229
230 /* Set return value */
231 ret_value = new_ds;
232
233 done:
234 if(ret_value == NULL) {
235 if(new_ds && H5S_close(new_ds) < 0)
236 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, NULL, "unable to release dataspace")
237 } /* end if */
238
239 FUNC_LEAVE_NOAPI(ret_value)
240 } /* end H5S_create() */
241
242
243 /*--------------------------------------------------------------------------
244 NAME
245 H5Screate
246 PURPOSE
247 Create empty, typed dataspace
248 USAGE
249 hid_t H5Screate(type)
250 H5S_type_t type; IN: Dataspace type to create
251 RETURNS
252 Valid dataspace ID on success, negative on failure
253 DESCRIPTION
254 Creates a new dataspace of a given type. The extent & selection are
255 undefined
256 GLOBAL VARIABLES
257 COMMENTS, BUGS, ASSUMPTIONS
258 EXAMPLES
259 REVISION LOG
260 --------------------------------------------------------------------------*/
261 hid_t
H5Screate(H5S_class_t type)262 H5Screate(H5S_class_t type)
263 {
264 H5S_t *new_ds=NULL; /* New dataspace structure */
265 hid_t ret_value; /* Return value */
266
267 FUNC_ENTER_API(FAIL)
268 H5TRACE1("i", "Sc", type);
269
270 /* Check args */
271 if(type <= H5S_NO_CLASS || type > H5S_NULL) /* don't allow complex dataspace yet */
272 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid dataspace type")
273
274 if(NULL == (new_ds = H5S_create(type)))
275 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create dataspace")
276
277 /* Atomize */
278 if((ret_value = H5I_register (H5I_DATASPACE, new_ds, TRUE)) < 0)
279 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
280
281 done:
282 if(ret_value < 0) {
283 if(new_ds && H5S_close(new_ds) < 0)
284 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
285 } /* end if */
286
287 FUNC_LEAVE_API(ret_value)
288 } /* end H5Screate() */
289
290
291 /*-------------------------------------------------------------------------
292 * Function: H5S_extent_release
293 *
294 * Purpose: Releases all memory associated with a dataspace extent.
295 *
296 * Return: Non-negative on success/Negative on failure
297 *
298 * Programmer: Quincey Koziol
299 * Thursday, July 23, 1998
300 *
301 * Modifications:
302 *
303 *-------------------------------------------------------------------------
304 */
305 herr_t
H5S_extent_release(H5S_extent_t * extent)306 H5S_extent_release(H5S_extent_t *extent)
307 {
308 herr_t ret_value=SUCCEED; /* Return value */
309
310 FUNC_ENTER_NOAPI(FAIL)
311
312 HDassert(extent);
313
314 /* Release extent */
315 if(extent->type == H5S_SIMPLE) {
316 if(extent->size)
317 extent->size = H5FL_ARR_FREE(hsize_t, extent->size);
318 if(extent->max)
319 extent->max = H5FL_ARR_FREE(hsize_t, extent->max);
320 } /* end if */
321
322 done:
323 FUNC_LEAVE_NOAPI(ret_value)
324 } /* end H5S_extent_release() */
325
326
327 /*-------------------------------------------------------------------------
328 * Function: H5S_close
329 *
330 * Purpose: Releases all memory associated with a dataspace.
331 *
332 * Return: Non-negative on success/Negative on failure
333 *
334 * Programmer: Robb Matzke
335 * Tuesday, December 9, 1997
336 *
337 *-------------------------------------------------------------------------
338 */
339 herr_t
H5S_close(H5S_t * ds)340 H5S_close(H5S_t *ds)
341 {
342 herr_t ret_value = SUCCEED; /* Return value */
343
344 FUNC_ENTER_NOAPI(FAIL)
345
346 HDassert(ds);
347
348 /* Release selection (this should come before the extent release) */
349 if(H5S_SELECT_RELEASE(ds) < 0)
350 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace selection")
351
352 /* Release extent */
353 if(H5S_extent_release(&ds->extent) < 0)
354 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace extent")
355
356 /* Release the main structure */
357 ds = H5FL_FREE(H5S_t, ds);
358
359 done:
360 FUNC_LEAVE_NOAPI(ret_value)
361 } /* end H5S_close() */
362
363
364 /*-------------------------------------------------------------------------
365 * Function: H5Sclose
366 *
367 * Purpose: Release access to a dataspace object.
368 *
369 * Return: Non-negative on success/Negative on failure
370 *
371 * Errors:
372 *
373 * Programmer: Robb Matzke
374 * Tuesday, December 9, 1997
375 *
376 * Modifications:
377 *
378 *-------------------------------------------------------------------------
379 */
380 herr_t
H5Sclose(hid_t space_id)381 H5Sclose(hid_t space_id)
382 {
383 herr_t ret_value = SUCCEED; /* Return value */
384
385 FUNC_ENTER_API(FAIL)
386 H5TRACE1("e", "i", space_id);
387
388 /* Check args */
389 if (NULL == H5I_object_verify(space_id,H5I_DATASPACE))
390 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
391
392 /* When the reference count reaches zero the resources are freed */
393 if(H5I_dec_app_ref(space_id) < 0)
394 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "problem freeing id")
395
396 done:
397 FUNC_LEAVE_API(ret_value)
398 } /* end H5Sclose() */
399
400
401 /*-------------------------------------------------------------------------
402 * Function: H5Scopy
403 *
404 * Purpose: Copies a dataspace.
405 *
406 * Return: Success: ID of the new dataspace
407 *
408 * Failure: Negative
409 *
410 * Programmer: Robb Matzke
411 * Friday, January 30, 1998
412 *
413 * Modifications:
414 *
415 *-------------------------------------------------------------------------
416 */
417 hid_t
H5Scopy(hid_t space_id)418 H5Scopy(hid_t space_id)
419 {
420 H5S_t *src;
421 H5S_t *dst = NULL;
422 hid_t ret_value;
423
424 FUNC_ENTER_API(FAIL)
425 H5TRACE1("i", "i", space_id);
426
427 /* Check args */
428 if(NULL == (src = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
429 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
430
431 /* Copy */
432 if(NULL == (dst = H5S_copy(src, FALSE, TRUE)))
433 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to copy dataspace")
434
435 /* Atomize */
436 if((ret_value = H5I_register (H5I_DATASPACE, dst, TRUE)) < 0)
437 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
438
439 done:
440 if(ret_value < 0) {
441 if(dst && H5S_close(dst) < 0)
442 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
443 } /* end if */
444
445 FUNC_LEAVE_API(ret_value)
446 } /* end H5Scopy() */
447
448
449 /*-------------------------------------------------------------------------
450 * Function: H5Sextent_copy
451 *
452 * Purpose: Copies a dataspace extent.
453 *
454 * Return: Non-negative on success/Negative on failure
455 *
456 * Programmer: Quincey Koziol
457 * Thursday, July 23, 1998
458 *
459 * Modifications:
460 *
461 *-------------------------------------------------------------------------
462 */
463 herr_t
H5Sextent_copy(hid_t dst_id,hid_t src_id)464 H5Sextent_copy(hid_t dst_id,hid_t src_id)
465 {
466 H5S_t *src;
467 H5S_t *dst;
468 hid_t ret_value = SUCCEED;
469
470 FUNC_ENTER_API(FAIL)
471 H5TRACE2("e", "ii", dst_id, src_id);
472
473 /* Check args */
474 if(NULL == (src = (H5S_t *)H5I_object_verify(src_id, H5I_DATASPACE)))
475 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
476 if(NULL == (dst = (H5S_t *)H5I_object_verify(dst_id, H5I_DATASPACE)))
477 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
478
479 /* Copy */
480 if(H5S_extent_copy(&(dst->extent), &(src->extent), TRUE) < 0)
481 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy extent")
482
483 /* If the selection is 'all', update the number of elements selected in the
484 * destination space */
485 if(H5S_SEL_ALL == H5S_GET_SELECT_TYPE(dst))
486 if(H5S_select_all(dst, FALSE) < 0)
487 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
488
489 done:
490 FUNC_LEAVE_API(ret_value)
491 } /* end H5Sextent_copy() */
492
493
494 /*-------------------------------------------------------------------------
495 * Function: H5S_extent_copy
496 *
497 * Purpose: Copies a dataspace extent
498 *
499 * Return: Non-negative on success/Negative on failure
500 *
501 * Programmer: Quincey Koziol
502 * Wednesday, June 3, 1998
503 *
504 * Modifications:
505 *
506 *-------------------------------------------------------------------------
507 */
508 herr_t
H5S_extent_copy(H5S_extent_t * dst,const H5S_extent_t * src,hbool_t copy_max)509 H5S_extent_copy(H5S_extent_t *dst, const H5S_extent_t *src, hbool_t copy_max)
510 {
511 unsigned u;
512 herr_t ret_value = SUCCEED; /* Return value */
513
514 FUNC_ENTER_NOAPI(FAIL)
515
516 /* Release destination extent before we copy over it */
517 if(H5S_extent_release(dst) < 0)
518 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace extent")
519
520 /* Copy the regular fields */
521 dst->type = src->type;
522 dst->version = src->version;
523 dst->nelem = src->nelem;
524 dst->rank = src->rank;
525
526 switch (src->type) {
527 case H5S_NULL:
528 case H5S_SCALAR:
529 dst->size = NULL;
530 dst->max = NULL;
531 break;
532
533 case H5S_SIMPLE:
534 if(src->size) {
535 dst->size = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)src->rank);
536 for(u = 0; u < src->rank; u++)
537 dst->size[u] = src->size[u];
538 } /* end if */
539 else
540 dst->size = NULL;
541 if(copy_max && src->max) {
542 dst->max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)src->rank);
543 for(u = 0; u < src->rank; u++)
544 dst->max[u] = src->max[u];
545 } /* end if */
546 else
547 dst->max = NULL;
548 break;
549
550 case H5S_NO_CLASS:
551 default:
552 HDassert("unknown dataspace type" && 0);
553 break;
554 } /* end switch */
555
556 /* Copy the shared object info */
557 if(H5O_set_shared(&(dst->sh_loc), &(src->sh_loc)) < 0)
558 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy shared information")
559
560 done:
561 FUNC_LEAVE_NOAPI(ret_value)
562 } /* end H5S_extent_copy() */
563
564
565 /*-------------------------------------------------------------------------
566 * Function: H5S_copy
567 *
568 * Purpose: Copies a dataspace, by copying the extent and selection through
569 * H5S_extent_copy and H5S_select_copy. If the SHARE_SELECTION flag
570 * is set, then the selection can be shared between the source and
571 * destination dataspaces. (This should only occur in situations
572 * where the destination dataspace will immediately change to a new
573 * selection)
574 *
575 * Return: Success: A pointer to a new copy of SRC
576 *
577 * Failure: NULL
578 *
579 * Programmer: Robb Matzke
580 * Thursday, December 4, 1997
581 *
582 * Modifications:
583 *
584 *-------------------------------------------------------------------------
585 */
586 H5S_t *
H5S_copy(const H5S_t * src,hbool_t share_selection,hbool_t copy_max)587 H5S_copy(const H5S_t *src, hbool_t share_selection, hbool_t copy_max)
588 {
589 H5S_t *dst = NULL;
590 H5S_t *ret_value; /* Return value */
591
592 FUNC_ENTER_NOAPI(NULL)
593
594 if(NULL == (dst = H5FL_CALLOC(H5S_t)))
595 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
596
597 /* Copy the source dataspace's extent */
598 if(H5S_extent_copy(&(dst->extent), &(src->extent), copy_max) < 0)
599 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy extent")
600
601 /* Copy the source dataspace's selection */
602 if(H5S_select_copy(dst, src, share_selection) < 0)
603 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy select")
604
605 /* Set the return value */
606 ret_value = dst;
607
608 done:
609 if(NULL == ret_value)
610 if(dst)
611 dst = H5FL_FREE(H5S_t, dst);
612
613 FUNC_LEAVE_NOAPI(ret_value)
614 } /* end H5S_copy() */
615
616
617 /*-------------------------------------------------------------------------
618 * Function: H5S_get_simple_extent_npoints
619 *
620 * Purpose: Determines how many data points a dataset extent has.
621 *
622 * Return: Success: Number of data points in the dataset extent.
623 *
624 * Failure: negative
625 *
626 * Programmer: Robb Matzke
627 * Tuesday, December 9, 1997
628 *
629 * Note: This routine participates in the "Inlining C function pointers"
630 * pattern, don't call it directly, use the appropriate macro
631 * defined in H5Sprivate.h.
632 *
633 * Modifications:
634 * Changed Name - QAK 7/7/98
635 *
636 *-------------------------------------------------------------------------
637 */
638 hssize_t
H5S_get_simple_extent_npoints(const H5S_t * ds)639 H5S_get_simple_extent_npoints(const H5S_t *ds)
640 {
641 hssize_t ret_value;
642
643 FUNC_ENTER_NOAPI(-1)
644
645 /* check args */
646 HDassert(ds);
647
648 /* Get the number of elements in extent */
649 ret_value = (hssize_t)ds->extent.nelem;
650
651 done:
652 FUNC_LEAVE_NOAPI(ret_value)
653 } /* end H5S_get_simple_extent_npoints() */
654
655
656 /*-------------------------------------------------------------------------
657 * Function: H5Sget_simple_extent_npoints
658 *
659 * Purpose: Determines how many data points a dataset extent has.
660 *
661 * Return: Success: Number of data points in the dataset.
662 *
663 * Failure: negative
664 *
665 * Programmer: Robb Matzke
666 * Tuesday, December 9, 1997
667 *
668 * Modifications:
669 * Changed Name - QAK 7/7/98
670 *
671 *-------------------------------------------------------------------------
672 */
673 hssize_t
H5Sget_simple_extent_npoints(hid_t space_id)674 H5Sget_simple_extent_npoints(hid_t space_id)
675 {
676 H5S_t *ds;
677 hssize_t ret_value;
678
679 FUNC_ENTER_API(FAIL)
680 H5TRACE1("Hs", "i", space_id);
681
682 /* Check args */
683 if(NULL == (ds = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
684 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
685
686 ret_value = (hssize_t)H5S_GET_EXTENT_NPOINTS(ds);
687
688 done:
689 FUNC_LEAVE_API(ret_value)
690 } /* end H5Sget_simple_extent_npoints() */
691
692
693 /*-------------------------------------------------------------------------
694 * Function: H5S_get_npoints_max
695 *
696 * Purpose: Determines the maximum number of data points a dataspace may
697 * have. If the `max' array is null then the maximum number of
698 * data points is the same as the current number of data points
699 * without regard to the hyperslab. If any element of the `max'
700 * array is zero then the maximum possible size is returned.
701 *
702 * Return: Success: Maximum number of data points the dataspace
703 * may have.
704 *
705 * Failure: 0
706 *
707 * Programmer: Robb Matzke
708 * Tuesday, December 9, 1997
709 *
710 * Modifications:
711 *
712 *-------------------------------------------------------------------------
713 */
714 hsize_t
H5S_get_npoints_max(const H5S_t * ds)715 H5S_get_npoints_max(const H5S_t *ds)
716 {
717 hsize_t ret_value;
718 unsigned u;
719
720 FUNC_ENTER_NOAPI(0)
721
722 /* check args */
723 HDassert(ds);
724
725 switch (H5S_GET_EXTENT_TYPE(ds)) {
726 case H5S_NULL:
727 ret_value = 0;
728 break;
729
730 case H5S_SCALAR:
731 ret_value = 1;
732 break;
733
734 case H5S_SIMPLE:
735 if (ds->extent.max) {
736 for (ret_value=1, u=0; u<ds->extent.rank; u++) {
737 if (H5S_UNLIMITED==ds->extent.max[u]) {
738 ret_value = HSIZET_MAX;
739 break;
740 }
741 else
742 ret_value *= ds->extent.max[u];
743 }
744 }
745 else {
746 for (ret_value=1, u=0; u<ds->extent.rank; u++)
747 ret_value *= ds->extent.size[u];
748 }
749 break;
750
751 case H5S_NO_CLASS:
752 default:
753 HDassert("unknown dataspace class" && 0);
754 HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, 0, "internal error (unknown dataspace class)")
755 }
756
757 done:
758 FUNC_LEAVE_NOAPI(ret_value)
759 }
760
761
762 /*-------------------------------------------------------------------------
763 * Function: H5Sget_simple_extent_ndims
764 *
765 * Purpose: Determines the dimensionality of a dataspace.
766 *
767 * Return: Success: The number of dimensions in a dataspace.
768 *
769 * Failure: Negative
770 *
771 * Programmer: Robb Matzke
772 * Thursday, December 11, 1997
773 *
774 * Modifications:
775 *
776 *-------------------------------------------------------------------------
777 */
778 int
H5Sget_simple_extent_ndims(hid_t space_id)779 H5Sget_simple_extent_ndims(hid_t space_id)
780 {
781 H5S_t *ds;
782 int ret_value;
783
784 FUNC_ENTER_API(FAIL)
785 H5TRACE1("Is", "i", space_id);
786
787 /* Check args */
788 if(NULL == (ds = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
789 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
790
791 ret_value = (int)H5S_GET_EXTENT_NDIMS(ds);
792
793 done:
794 FUNC_LEAVE_API(ret_value)
795 } /* end H5Sget_simple_extent_ndims() */
796
797
798 /*-------------------------------------------------------------------------
799 * Function: H5S_get_simple_extent_ndims
800 *
801 * Purpose: Returns the number of dimensions in a dataspace.
802 *
803 * Return: Success: Non-negative number of dimensions. Zero
804 * implies a scalar.
805 *
806 * Failure: Negative
807 *
808 * Programmer: Robb Matzke
809 * Thursday, December 11, 1997
810 *
811 * Note: This routine participates in the "Inlining C function pointers"
812 * pattern, don't call it directly, use the appropriate macro
813 * defined in H5Sprivate.h.
814 *
815 * Modifications:
816 *
817 *-------------------------------------------------------------------------
818 */
819 int
H5S_get_simple_extent_ndims(const H5S_t * ds)820 H5S_get_simple_extent_ndims(const H5S_t *ds)
821 {
822 int ret_value; /* Return value */
823
824 FUNC_ENTER_NOAPI(FAIL)
825
826 /* check args */
827 HDassert(ds);
828
829 switch(H5S_GET_EXTENT_TYPE(ds)) {
830 case H5S_NULL:
831 case H5S_SCALAR:
832 case H5S_SIMPLE:
833 ret_value = (int)ds->extent.rank;
834 break;
835
836 case H5S_NO_CLASS:
837 default:
838 HDassert("unknown dataspace class" && 0);
839 HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "internal error (unknown dataspace class)")
840 } /* end switch */
841
842 done:
843 FUNC_LEAVE_NOAPI(ret_value)
844 } /* end H5S_get_simple_extent_ndims() */
845
846
847 /*-------------------------------------------------------------------------
848 * Function: H5Sget_simple_extent_dims
849 *
850 * Purpose: Returns the size and maximum sizes in each dimension of
851 * a dataspace DS through the DIMS and MAXDIMS arguments.
852 *
853 * Return: Success: Number of dimensions, the same value as
854 * returned by H5Sget_simple_extent_ndims().
855 *
856 * Failure: Negative
857 *
858 * Programmer: Robb Matzke
859 * Thursday, December 11, 1997
860 *
861 * Modifications:
862 * June 18, 1998 Albert Cheng
863 * Added maxdims argument. Removed dims argument check
864 * since it can still return ndims even if both dims and
865 * maxdims are NULLs.
866 *
867 *-------------------------------------------------------------------------
868 */
869 int
H5Sget_simple_extent_dims(hid_t space_id,hsize_t dims[],hsize_t maxdims[])870 H5Sget_simple_extent_dims(hid_t space_id, hsize_t dims[]/*out*/,
871 hsize_t maxdims[]/*out*/)
872 {
873 H5S_t *ds;
874 int ret_value;
875
876 FUNC_ENTER_API(FAIL)
877 H5TRACE3("Is", "ixx", space_id, dims, maxdims);
878
879 /* Check args */
880 if (NULL == (ds = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
881 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
882
883 ret_value = H5S_get_simple_extent_dims(ds, dims, maxdims);
884
885 done:
886 FUNC_LEAVE_API(ret_value)
887 }
888
889
890 /*-------------------------------------------------------------------------
891 * Function: H5S_extent_get_dims
892 *
893 * Purpose: Returns the size in each dimension of a dataspace. This
894 * function may not be meaningful for all types of dataspaces.
895 *
896 * Return: Success: Number of dimensions. Zero implies scalar.
897 * Failure: Negative
898 *
899 * Programmer: Quincey Koziol
900 * Tuesday, June 30, 2009
901 *
902 *-------------------------------------------------------------------------
903 */
904 int
H5S_extent_get_dims(const H5S_extent_t * ext,hsize_t dims[],hsize_t max_dims[])905 H5S_extent_get_dims(const H5S_extent_t *ext, hsize_t dims[], hsize_t max_dims[])
906 {
907 int i; /* Local index variable */
908 int ret_value; /* Return value */
909
910 FUNC_ENTER_NOAPI(FAIL)
911
912 /* check args */
913 HDassert(ext);
914
915 switch(ext->type) {
916 case H5S_NULL:
917 case H5S_SCALAR:
918 ret_value = 0;
919 break;
920
921 case H5S_SIMPLE:
922 ret_value = (int)ext->rank;
923 for(i = 0; i < ret_value; i++) {
924 if(dims)
925 dims[i] = ext->size[i];
926 if(max_dims) {
927 if(ext->max)
928 max_dims[i] = ext->max[i];
929 else
930 max_dims[i] = ext->size[i];
931 } /* end if */
932 } /* end for */
933 break;
934
935 case H5S_NO_CLASS:
936 default:
937 HDassert("unknown dataspace class" && 0);
938 HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "internal error (unknown dataspace class)")
939 } /* end switch */
940
941 done:
942 FUNC_LEAVE_NOAPI(ret_value)
943 } /* end H5S_extent_get_dims() */
944
945
946 /*-------------------------------------------------------------------------
947 * Function: H5S_get_simple_extent_dims
948 *
949 * Purpose: Returns the size in each dimension of a dataspace. This
950 * function may not be meaningful for all types of dataspaces.
951 *
952 * Return: Success: Number of dimensions. Zero implies scalar.
953 *
954 * Failure: Negative
955 *
956 * Programmer: Robb Matzke
957 * Thursday, December 11, 1997
958 *
959 * Modifications:
960 *
961 *-------------------------------------------------------------------------
962 */
963 int
H5S_get_simple_extent_dims(const H5S_t * ds,hsize_t dims[],hsize_t max_dims[])964 H5S_get_simple_extent_dims(const H5S_t *ds, hsize_t dims[], hsize_t max_dims[])
965 {
966 int ret_value; /* Return value */
967
968 FUNC_ENTER_NOAPI(FAIL)
969
970 /* check args */
971 HDassert(ds);
972
973 /* Get dims for extent */
974 if((ret_value = H5S_extent_get_dims(&ds->extent, dims, max_dims)) < 0)
975 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve dataspace extent dims")
976
977 done:
978 FUNC_LEAVE_NOAPI(ret_value)
979 } /* end H5S_get_simple_extent_dims() */
980
981
982 /*-------------------------------------------------------------------------
983 * Function: H5S_write
984 *
985 * Purpose: Updates a dataspace by writing a message to an object
986 * header.
987 *
988 * Return: Non-negative on success/Negative on failure
989 *
990 * Programmer: Robb Matzke
991 * Tuesday, December 9, 1997
992 *
993 *-------------------------------------------------------------------------
994 */
995 herr_t
H5S_write(H5F_t * f,hid_t dxpl_id,H5O_t * oh,unsigned update_flags,H5S_t * ds)996 H5S_write(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned update_flags, H5S_t *ds)
997 {
998 herr_t ret_value = SUCCEED; /* Return value */
999
1000 FUNC_ENTER_NOAPI(FAIL)
1001
1002 HDassert(f);
1003 HDassert(oh);
1004 HDassert(ds);
1005 HDassert(H5S_GET_EXTENT_TYPE(ds) >= 0);
1006
1007 /* Write the current dataspace extent to the dataspace message */
1008 if(H5O_msg_write_oh(f, dxpl_id, oh, H5O_SDSPACE_ID, 0, update_flags, &(ds->extent)) < 0)
1009 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update simple dataspace message")
1010
1011 done:
1012 FUNC_LEAVE_NOAPI(ret_value)
1013 } /* end H5S_write() */
1014
1015
1016 /*-------------------------------------------------------------------------
1017 * Function: H5S_append
1018 *
1019 * Purpose: Updates a dataspace by adding a message to an object
1020 * header.
1021 *
1022 * Return: Non-negative on success/Negative on failure
1023 *
1024 * Programmer: Quincey Koziol
1025 * Tuesday, December 31, 2002
1026 *
1027 * Modifications:
1028 *
1029 * John Mainzer, 6/6/05
1030 * Updated function to use the new dirtied parameter of
1031 * H5AC_unprotect() instead of manipulating the is_dirty
1032 * field of the cache info.
1033 *
1034 *-------------------------------------------------------------------------
1035 */
1036 herr_t
H5S_append(H5F_t * f,hid_t dxpl_id,H5O_t * oh,H5S_t * ds)1037 H5S_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, H5S_t *ds)
1038 {
1039 herr_t ret_value = SUCCEED; /* Return value */
1040
1041 FUNC_ENTER_NOAPI(FAIL)
1042
1043 HDassert(f);
1044 HDassert(oh);
1045 HDassert(ds);
1046 HDassert(H5S_GET_EXTENT_TYPE(ds) >= 0);
1047
1048 /* Add the dataspace message to the object header */
1049 if(H5O_msg_append_oh(f, dxpl_id, oh, H5O_SDSPACE_ID, 0, 0, &(ds->extent)) < 0)
1050 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't add simple dataspace message")
1051
1052 done:
1053 FUNC_LEAVE_NOAPI(ret_value)
1054 } /* end H5S_append() */
1055
1056
1057 /*-------------------------------------------------------------------------
1058 * Function: H5S_read
1059 *
1060 * Purpose: Reads the dataspace from an object header.
1061 *
1062 * Return: Success: Pointer to a new dataspace.
1063 *
1064 * Failure: NULL
1065 *
1066 * Programmer: Robb Matzke
1067 * Tuesday, December 9, 1997
1068 *
1069 *-------------------------------------------------------------------------
1070 */
1071 H5S_t *
H5S_read(const H5O_loc_t * loc,hid_t dxpl_id)1072 H5S_read(const H5O_loc_t *loc, hid_t dxpl_id)
1073 {
1074 H5S_t *ds = NULL; /* Dataspace to return */
1075 H5S_t *ret_value; /* Return value */
1076
1077 FUNC_ENTER_NOAPI(NULL)
1078
1079 /* check args */
1080 HDassert(loc);
1081
1082 if(NULL == (ds = H5FL_CALLOC(H5S_t)))
1083 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
1084
1085 if(H5O_msg_read(loc, H5O_SDSPACE_ID, &(ds->extent), dxpl_id) == NULL)
1086 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to load dataspace info from dataset header")
1087
1088 /* Default to entire dataspace being selected */
1089 if(H5S_select_all(ds, FALSE) < 0)
1090 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection")
1091
1092 /* Set the value for successful return */
1093 ret_value = ds;
1094
1095 done:
1096 if(ret_value == NULL) {
1097 if(ds != NULL)
1098 ds = H5FL_FREE(H5S_t, ds);
1099 } /* end if */
1100
1101 FUNC_LEAVE_NOAPI(ret_value)
1102 } /* end H5S_read() */
1103
1104
1105 /*--------------------------------------------------------------------------
1106 NAME
1107 H5S_is_simple
1108 PURPOSE
1109 Check if a dataspace is simple (internal)
1110 USAGE
1111 htri_t H5S_is_simple(sdim)
1112 H5S_t *sdim; IN: Pointer to dataspace object to query
1113 RETURNS
1114 TRUE/FALSE/FAIL
1115 DESCRIPTION
1116 This function determines the if a dataspace is "simple". ie. if it
1117 has orthogonal, evenly spaced dimensions.
1118 --------------------------------------------------------------------------*/
1119 static htri_t
H5S_is_simple(const H5S_t * sdim)1120 H5S_is_simple(const H5S_t *sdim)
1121 {
1122 htri_t ret_value;
1123
1124 FUNC_ENTER_NOAPI_NOINIT_NOERR
1125
1126 /* Check args and all the boring stuff. */
1127 HDassert(sdim);
1128
1129 /* H5S_NULL shouldn't be simple dataspace */
1130 ret_value = (H5S_GET_EXTENT_TYPE(sdim) == H5S_SIMPLE ||
1131 H5S_GET_EXTENT_TYPE(sdim) == H5S_SCALAR) ? TRUE : FALSE;
1132
1133 FUNC_LEAVE_NOAPI(ret_value)
1134 } /* end H5S_is_simple() */
1135
1136
1137 /*--------------------------------------------------------------------------
1138 NAME
1139 H5Sis_simple
1140 PURPOSE
1141 Check if a dataspace is simple
1142 USAGE
1143 htri_t H5Sis_simple(space_id)
1144 hid_t space_id; IN: ID of dataspace object to query
1145 RETURNS
1146 TRUE/FALSE/FAIL
1147 DESCRIPTION
1148 This function determines the if a dataspace is "simple". ie. if it
1149 has orthogonal, evenly spaced dimensions.
1150 --------------------------------------------------------------------------*/
1151 htri_t
H5Sis_simple(hid_t space_id)1152 H5Sis_simple(hid_t space_id)
1153 {
1154 H5S_t *space; /* dataspace to modify */
1155 htri_t ret_value;
1156
1157 FUNC_ENTER_API(FAIL)
1158 H5TRACE1("t", "i", space_id);
1159
1160 /* Check args and all the boring stuff. */
1161 if ((space = (H5S_t *)H5I_object_verify(space_id,H5I_DATASPACE)) == NULL)
1162 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace")
1163
1164 ret_value = H5S_is_simple(space);
1165
1166 done:
1167 FUNC_LEAVE_API(ret_value)
1168 }
1169
1170
1171 /*--------------------------------------------------------------------------
1172 NAME
1173 H5Sset_extent_simple
1174 PURPOSE
1175 Sets the size of a simple dataspace
1176 USAGE
1177 herr_t H5Sset_extent_simple(space_id, rank, dims, max)
1178 hid_t space_id; IN: Dataspace object to query
1179 int rank; IN: # of dimensions for the dataspace
1180 const size_t *dims; IN: Size of each dimension for the dataspace
1181 const size_t *max; IN: Maximum size of each dimension for the
1182 dataspace
1183 RETURNS
1184 Non-negative on success/Negative on failure
1185 DESCRIPTION
1186 This function sets the number and size of each dimension in the
1187 dataspace. Setting RANK to a value of zero converts the dataspace to a
1188 scalar dataspace. Dimensions are specified from slowest to fastest
1189 changing in the DIMS array (i.e. 'C' order). Setting the size of a
1190 dimension in the MAX array to zero indicates that the dimension is of
1191 unlimited size and should be allowed to expand. If MAX is NULL, the
1192 dimensions in the DIMS array are used as the maximum dimensions.
1193 Currently, only the first dimension in the array (the slowest) may be
1194 unlimited in size.
1195
1196 MODIFICATION
1197 A null dataspace cannot be created from simple space with this function.
1198
1199 Christian Chilan 01/17/2007
1200 Verifies that each element of DIMS is not equal to H5S_UNLIMITED.
1201
1202 Raymond Lu 03/30/2011
1203 We allow 0 dimension size for non-unlimited dimension starting from 1.8.7
1204 release.
1205 --------------------------------------------------------------------------*/
1206 herr_t
H5Sset_extent_simple(hid_t space_id,int rank,const hsize_t dims[],const hsize_t max[])1207 H5Sset_extent_simple(hid_t space_id, int rank, const hsize_t dims[/*rank*/],
1208 const hsize_t max[/*rank*/])
1209 {
1210 H5S_t *space; /* dataspace to modify */
1211 int u; /* local counting variable */
1212 herr_t ret_value=SUCCEED; /* Return value */
1213
1214 FUNC_ENTER_API(FAIL)
1215 H5TRACE4("e", "iIs*[a1]h*[a1]h", space_id, rank, dims, max);
1216
1217 /* Check args */
1218 if ((space = (H5S_t *)H5I_object_verify(space_id,H5I_DATASPACE)) == NULL)
1219 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace")
1220 if (rank > 0 && dims == NULL)
1221 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no dimensions specified")
1222 if (rank<0 || rank>H5S_MAX_RANK)
1223 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid rank")
1224 if (dims) {
1225 for (u=0; u<rank; u++) {
1226 if (H5S_UNLIMITED==dims[u])
1227 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "current dimension must have a specific size, not H5S_UNLIMITED")
1228 }
1229 }
1230 if (max!=NULL) {
1231 if(dims==NULL)
1232 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "maximum dimension specified, but no current dimensions specified")
1233 for (u=0; u<rank; u++) {
1234 if (max[u]!=H5S_UNLIMITED && max[u]<dims[u])
1235 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid maximum dimension size")
1236 }
1237 }
1238
1239 /* Do it */
1240 if (H5S_set_extent_simple(space, (unsigned)rank, dims, max)<0)
1241 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to set simple extent")
1242
1243 done:
1244 FUNC_LEAVE_API(ret_value)
1245 }
1246
1247
1248 /*-------------------------------------------------------------------------
1249 * Function: H5S_set_extent_simple
1250 *
1251 * Purpose: This is where the real work happens for
1252 * H5Sset_extent_simple().
1253 *
1254 * Return: Non-negative on success/Negative on failure
1255 *
1256 * Programmer: Robb Matzke (copied from H5Sset_extent_simple)
1257 * Wednesday, July 8, 1998
1258 *
1259 * Modifications:
1260 *
1261 *-------------------------------------------------------------------------
1262 */
1263 static herr_t
H5S_set_extent_simple(H5S_t * space,unsigned rank,const hsize_t * dims,const hsize_t * max)1264 H5S_set_extent_simple(H5S_t *space, unsigned rank, const hsize_t *dims,
1265 const hsize_t *max)
1266 {
1267 unsigned u; /* Local index variable */
1268 herr_t ret_value = SUCCEED; /* Return value */
1269
1270 FUNC_ENTER_NOAPI_NOINIT
1271
1272 /* Check args */
1273 HDassert(rank <= H5S_MAX_RANK);
1274 HDassert(0 == rank || dims);
1275
1276 /* shift out of the previous state to a "simple" dataspace. */
1277 if(H5S_extent_release(&space->extent) < 0)
1278 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "failed to release previous dataspace extent")
1279
1280 if(rank == 0) { /* scalar variable */
1281 space->extent.type = H5S_SCALAR;
1282 space->extent.nelem = 1;
1283 space->extent.rank = 0; /* set to scalar rank */
1284 } /* end if */
1285 else {
1286 hsize_t nelem; /* Number of elements in extent */
1287
1288 space->extent.type = H5S_SIMPLE;
1289
1290 /* Set the rank and allocate space for the dims */
1291 space->extent.rank = rank;
1292 space->extent.size = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)rank);
1293
1294 /* Copy the dimensions & compute the number of elements in the extent */
1295 for(u = 0, nelem = 1; u < space->extent.rank; u++) {
1296 space->extent.size[u] = dims[u];
1297 nelem *= dims[u];
1298 } /* end for */
1299 space->extent.nelem = nelem;
1300
1301 /* Copy the maximum dimensions if specified. Otherwise, the maximal dimensions are the
1302 * same as the dimension */
1303 space->extent.max = (hsize_t *)H5FL_ARR_MALLOC(hsize_t, (size_t)rank);
1304 if(max != NULL) {
1305 HDmemcpy(space->extent.max, max, sizeof(hsize_t) * rank);
1306 } else {
1307 for(u = 0; u < space->extent.rank; u++)
1308 space->extent.max[u] = dims[u];
1309 }
1310 } /* end else */
1311
1312 /* Selection related cleanup */
1313
1314 /* Set offset to zeros */
1315 HDmemset(space->select.offset, 0, sizeof(hsize_t) * space->extent.rank);
1316 space->select.offset_changed = FALSE;
1317
1318 /* If the selection is 'all', update the number of elements selected */
1319 if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_ALL)
1320 if(H5S_select_all(space, FALSE) < 0)
1321 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
1322
1323 done:
1324 FUNC_LEAVE_NOAPI(ret_value)
1325 } /* H5S_set_extent_simple() */
1326
1327
1328 /*-------------------------------------------------------------------------
1329 * Function: H5Screate_simple
1330 *
1331 * Purpose: Creates a new simple dataspace object and opens it for
1332 * access. The DIMS argument is the size of the simple dataset
1333 * and the MAXDIMS argument is the upper limit on the size of
1334 * the dataset. MAXDIMS may be the null pointer in which case
1335 * the upper limit is the same as DIMS. If an element of
1336 * MAXDIMS is H5S_UNLIMITED then the corresponding dimension is
1337 * unlimited, otherwise no element of MAXDIMS should be smaller
1338 * than the corresponding element of DIMS.
1339 *
1340 * Return: Success: The ID for the new simple dataspace object.
1341 *
1342 * Failure: Negative
1343 *
1344 * Programmer: Quincey Koziol
1345 * Tuesday, January 27, 1998
1346 *
1347 * Modification:
1348 * Raymond Lu 03/30/2011
1349 * We allow 0-dimension for non-unlimited dimension starting
1350 * from 1.8.7 release.
1351 *
1352 *-------------------------------------------------------------------------
1353 */
1354 hid_t
H5Screate_simple(int rank,const hsize_t dims[],const hsize_t maxdims[])1355 H5Screate_simple(int rank, const hsize_t dims[/*rank*/],
1356 const hsize_t maxdims[/*rank*/])
1357 {
1358 H5S_t *space = NULL;
1359 int i;
1360 hid_t ret_value;
1361
1362 FUNC_ENTER_API(FAIL)
1363 H5TRACE3("i", "Is*[a0]h*[a0]h", rank, dims, maxdims);
1364
1365 /* Check arguments */
1366 if(rank < 0)
1367 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dimensionality cannot be negative")
1368 if(rank > H5S_MAX_RANK)
1369 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dimensionality is too large")
1370
1371 /* We allow users to use this function to create scalar or null dataspace.
1372 * Check DIMS isn't set when the RANK is 0.
1373 */
1374 if(!dims && rank != 0)
1375 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid dataspace information")
1376
1377 /* Check whether the current dimensions are valid */
1378 for(i = 0; i < rank; i++) {
1379 if(H5S_UNLIMITED == dims[i])
1380 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "current dimension must have a specific size, not H5S_UNLIMITED")
1381 if(maxdims && H5S_UNLIMITED != maxdims[i] && maxdims[i]<dims[i])
1382 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "maxdims is smaller than dims")
1383 } /* end for */
1384
1385 /* Create the space and set the extent */
1386 if(NULL == (space = H5S_create_simple((unsigned)rank,dims,maxdims)))
1387 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
1388
1389 /* Atomize */
1390 if((ret_value = H5I_register (H5I_DATASPACE, space, TRUE)) < 0)
1391 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID")
1392
1393 done:
1394 if(ret_value < 0) {
1395 if(space && H5S_close(space) < 0)
1396 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
1397 } /* end if */
1398
1399 FUNC_LEAVE_API(ret_value)
1400 } /* end H5Screate_simple() */
1401
1402
1403 /*-------------------------------------------------------------------------
1404 * Function: H5S_create_simple
1405 *
1406 * Purpose: Internal function to create simple dataspace
1407 *
1408 * Return: Success: The ID for the new simple dataspace object.
1409 * Failure: Negative
1410 *
1411 * Errors:
1412 *
1413 * Programmer: Quincey Koziol
1414 * Thursday, April 3, 2003
1415 *
1416 * Modifications:
1417 * Extracted from H5Screate_simple
1418 * Quincey Koziol, Thursday, April 3, 2003
1419 *
1420 *-------------------------------------------------------------------------
1421 */
1422 H5S_t *
H5S_create_simple(unsigned rank,const hsize_t dims[],const hsize_t maxdims[])1423 H5S_create_simple(unsigned rank, const hsize_t dims[/*rank*/],
1424 const hsize_t maxdims[/*rank*/])
1425 {
1426 H5S_t *ret_value; /* Return value */
1427
1428 FUNC_ENTER_NOAPI(NULL)
1429
1430 /* Check arguments */
1431 HDassert(rank <=H5S_MAX_RANK);
1432
1433 /* Create the space and set the extent */
1434 if(NULL==(ret_value=H5S_create(H5S_SIMPLE)))
1435 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, NULL, "can't create simple dataspace")
1436 if(H5S_set_extent_simple(ret_value,rank,dims,maxdims)<0)
1437 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "can't set dimensions")
1438
1439 done:
1440 FUNC_LEAVE_NOAPI(ret_value)
1441 } /* end H5S_create_simple() */
1442
1443
1444 /*-------------------------------------------------------------------------
1445 * Function: H5Sencode
1446 *
1447 * Purpose: Given a dataspace ID, converts the object description
1448 * (including selection) into binary in a buffer.
1449 *
1450 * Return: Success: non-negative
1451 *
1452 * Failure: negative
1453 *
1454 * Programmer: Raymond Lu
1455 * slu@ncsa.uiuc.edu
1456 * July 14, 2004
1457 *
1458 * Modifications:
1459 *
1460 *-------------------------------------------------------------------------
1461 */
1462 herr_t
H5Sencode(hid_t obj_id,void * buf,size_t * nalloc)1463 H5Sencode(hid_t obj_id, void *buf, size_t *nalloc)
1464 {
1465 H5S_t *dspace;
1466 herr_t ret_value=SUCCEED;
1467
1468 FUNC_ENTER_API(FAIL)
1469 H5TRACE3("e", "i*x*z", obj_id, buf, nalloc);
1470
1471 /* Check argument and retrieve object */
1472 if (NULL==(dspace=(H5S_t *)H5I_object_verify(obj_id, H5I_DATASPACE)))
1473 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
1474
1475 if(H5S_encode(dspace, (unsigned char *)buf, nalloc)<0)
1476 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTENCODE, FAIL, "can't encode datatype")
1477
1478 done:
1479 FUNC_LEAVE_API(ret_value)
1480 }
1481
1482
1483 /*-------------------------------------------------------------------------
1484 * Function: H5S_encode
1485 *
1486 * Purpose: Private function for H5Sencode. Converts an object
1487 * description for dataspace and its selection into binary
1488 * in a buffer.
1489 *
1490 * Return: Success: non-negative
1491 * Failure: negative
1492 *
1493 * Programmer: Raymond Lu
1494 * slu@ncsa.uiuc.edu
1495 * July 14, 2004
1496 *
1497 *-------------------------------------------------------------------------
1498 */
1499 static herr_t
H5S_encode(H5S_t * obj,unsigned char * buf,size_t * nalloc)1500 H5S_encode(H5S_t *obj, unsigned char *buf, size_t *nalloc)
1501 {
1502 size_t extent_size; /* Size of serialized dataspace extent */
1503 hssize_t sselect_size; /* Signed size of serialized dataspace selection */
1504 size_t select_size; /* Size of serialized dataspace selection */
1505 H5F_t *f = NULL; /* Fake file structure*/
1506 herr_t ret_value = SUCCEED;
1507
1508 FUNC_ENTER_NOAPI_NOINIT
1509
1510 /* Allocate "fake" file structure */
1511 if(NULL == (f = H5F_fake_alloc((uint8_t)0)))
1512 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate fake file struct")
1513
1514 /* Find out the size of buffer needed for extent */
1515 if((extent_size = H5O_msg_raw_size(f, H5O_SDSPACE_ID, TRUE, obj)) == 0)
1516 HGOTO_ERROR(H5E_DATASPACE, H5E_BADSIZE, FAIL, "can't find dataspace size")
1517
1518 /* Find out the size of buffer needed for selection */
1519 if((sselect_size = H5S_SELECT_SERIAL_SIZE(obj)) < 0)
1520 HGOTO_ERROR(H5E_DATASPACE, H5E_BADSIZE, FAIL, "can't find dataspace selection size")
1521 H5_CHECKED_ASSIGN(select_size, size_t, sselect_size, hssize_t);
1522
1523 /* Verify the size of buffer. If it's not big enough, simply return the
1524 * right size without filling the buffer. */
1525 if(!buf || *nalloc < (extent_size + select_size + 1 + 1 + 1 + 4))
1526 *nalloc = extent_size + select_size + 1 + 1 + 1 + 4;
1527 else {
1528 /* Encode the type of the information */
1529 *buf++ = H5O_SDSPACE_ID;
1530
1531 /* Encode the version of the dataspace information */
1532 *buf++ = H5S_ENCODE_VERSION;
1533
1534 /* Encode the "size of size" information */
1535 *buf++ = (unsigned char)H5F_SIZEOF_SIZE(f);
1536
1537 /* Encode size of extent information. Pointer is actually moved in this macro. */
1538 UINT32ENCODE(buf, extent_size);
1539
1540 /* Encode the extent part of dataspace */
1541 if(H5O_msg_encode(f, H5O_SDSPACE_ID, TRUE, buf, obj) < 0)
1542 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode extent space")
1543 buf += extent_size;
1544
1545 /* Encode the selection part of dataspace. */
1546 if(H5S_SELECT_SERIALIZE(obj, buf) < 0)
1547 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTENCODE, FAIL, "can't encode select space")
1548 } /* end else */
1549
1550 done:
1551 /* Release fake file structure */
1552 if(f && H5F_fake_free(f) < 0)
1553 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release fake file struct")
1554
1555 FUNC_LEAVE_NOAPI(ret_value)
1556 } /* end H5S_encode() */
1557
1558
1559 /*-------------------------------------------------------------------------
1560 * Function: H5Sdecode
1561 *
1562 * Purpose: Decode a binary object description of dataspace and
1563 * return a new object handle.
1564 *
1565 * Return: Success: dataspace ID(non-negative)
1566 *
1567 * Failure: negative
1568 *
1569 * Programmer: Raymond Lu
1570 * slu@ncsa.uiuc.edu
1571 * July 14, 2004
1572 *
1573 *-------------------------------------------------------------------------
1574 */
1575 hid_t
H5Sdecode(const void * buf)1576 H5Sdecode(const void *buf)
1577 {
1578 H5S_t *ds;
1579 hid_t ret_value;
1580
1581 FUNC_ENTER_API(FAIL)
1582 H5TRACE1("i", "*x", buf);
1583
1584 if(buf == NULL)
1585 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "empty buffer")
1586
1587 if((ds = H5S_decode((const unsigned char *)buf)) == NULL)
1588 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDECODE, FAIL, "can't decode object")
1589
1590 /* Register the type and return the ID */
1591 if((ret_value = H5I_register(H5I_DATASPACE, ds, TRUE)) < 0)
1592 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTREGISTER, FAIL, "unable to register dataspace")
1593
1594 done:
1595 FUNC_LEAVE_API(ret_value)
1596 } /* end H5Sdecode() */
1597
1598
1599 /*-------------------------------------------------------------------------
1600 * Function: H5S_decode
1601 *
1602 * Purpose: Private function for H5Sdecode. Reconstructs a binary
1603 * description of dataspace and returns a new object handle.
1604 *
1605 * Return: Success: dataspace ID(non-negative)
1606 *
1607 * Failure: negative
1608 *
1609 * Programmer: Raymond Lu
1610 * slu@ncsa.uiuc.edu
1611 * July 14, 2004
1612 *
1613 *-------------------------------------------------------------------------
1614 */
1615 static H5S_t*
H5S_decode(const unsigned char * buf)1616 H5S_decode(const unsigned char *buf)
1617 {
1618 H5S_t *ds;
1619 H5S_extent_t *extent;
1620 size_t extent_size; /* size of the extent message*/
1621 H5F_t *f = NULL; /* Fake file structure*/
1622 uint8_t sizeof_size; /* 'Size of sizes' for file */
1623 H5S_t *ret_value;
1624
1625 FUNC_ENTER_NOAPI_NOINIT
1626
1627 /* Decode the type of the information */
1628 if(*buf++ != H5O_SDSPACE_ID)
1629 HGOTO_ERROR(H5E_DATASPACE, H5E_BADMESG, NULL, "not an encoded dataspace")
1630
1631 /* Decode the version of the dataspace information */
1632 if(*buf++ != H5S_ENCODE_VERSION)
1633 HGOTO_ERROR(H5E_DATASPACE, H5E_VERSION, NULL, "unknown version of encoded dataspace")
1634
1635 /* Decode the "size of size" information */
1636 sizeof_size = *buf++;
1637
1638 /* Allocate "fake" file structure */
1639 if(NULL == (f = H5F_fake_alloc(sizeof_size)))
1640 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, NULL, "can't allocate fake file struct")
1641
1642 /* Decode size of extent information */
1643 UINT32DECODE(buf, extent_size);
1644
1645 /* Decode the extent part of dataspace */
1646 /* (pass mostly bogus file pointer and bogus DXPL) */
1647 if((extent = (H5S_extent_t *)H5O_msg_decode(f, H5P_DEFAULT, NULL, H5O_SDSPACE_ID, extent_size, buf))==NULL)
1648 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDECODE, NULL, "can't decode object")
1649 buf += extent_size;
1650
1651 /* Copy the extent into dataspace structure */
1652 if((ds = H5FL_CALLOC(H5S_t))==NULL)
1653 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for dataspace conversion path table")
1654 if(H5O_msg_copy(H5O_SDSPACE_ID, extent, &(ds->extent)) == NULL)
1655 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, NULL, "can't copy object")
1656 if(H5S_extent_release(extent) < 0)
1657 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTDELETE, NULL, "can't release previous dataspace")
1658 extent = H5FL_FREE(H5S_extent_t, extent);
1659
1660 /* Initialize to "all" selection. Deserialization relies on valid existing selection. */
1661 if(H5S_select_all(ds, FALSE) < 0)
1662 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection")
1663
1664 /* Decode the select part of dataspace. I believe this part always exists. */
1665 if(H5S_SELECT_DESERIALIZE(ds, buf) < 0)
1666 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDECODE, NULL, "can't decode space selection")
1667
1668 /* Set return value */
1669 ret_value = ds;
1670
1671 done:
1672 /* Release fake file structure */
1673 if(f && H5F_fake_free(f) < 0)
1674 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, NULL, "unable to release fake file struct")
1675
1676 FUNC_LEAVE_NOAPI(ret_value)
1677 } /* end H5S_decode() */
1678
1679
1680 /*-------------------------------------------------------------------------
1681 * Function: H5S_get_simple_extent_type
1682 *
1683 * Purpose: Internal function for retrieving the type of extent for a dataspace object
1684 *
1685 * Return: Success: The class of the dataspace object
1686 *
1687 * Failure: N5S_NO_CLASS
1688 *
1689 * Errors:
1690 *
1691 * Programmer: Quincey Koziol
1692 * Thursday, September 28, 2000
1693 *
1694 * Note: This routine participates in the "Inlining C function pointers"
1695 * pattern, don't call it directly, use the appropriate macro
1696 * defined in H5Sprivate.h.
1697 *
1698 * Modifications:
1699 *
1700 *-------------------------------------------------------------------------
1701 */
1702 H5S_class_t
H5S_get_simple_extent_type(const H5S_t * space)1703 H5S_get_simple_extent_type(const H5S_t *space)
1704 {
1705 H5S_class_t ret_value;
1706
1707 FUNC_ENTER_NOAPI(H5S_NO_CLASS)
1708
1709 HDassert(space);
1710
1711 ret_value=H5S_GET_EXTENT_TYPE(space);
1712
1713 done:
1714 FUNC_LEAVE_NOAPI(ret_value)
1715 }
1716
1717
1718 /*-------------------------------------------------------------------------
1719 * Function: H5Sget_simple_extent_type
1720 *
1721 * Purpose: Retrieves the type of extent for a dataspace object
1722 *
1723 * Return: Success: The class of the dataspace object
1724 *
1725 * Failure: N5S_NO_CLASS
1726 *
1727 * Errors:
1728 *
1729 * Programmer: Quincey Koziol
1730 * Thursday, July 23, 1998
1731 *
1732 * Modifications:
1733 *
1734 *-------------------------------------------------------------------------
1735 */
1736 H5S_class_t
H5Sget_simple_extent_type(hid_t sid)1737 H5Sget_simple_extent_type(hid_t sid)
1738 {
1739 H5S_t *space;
1740 H5S_class_t ret_value;
1741
1742 FUNC_ENTER_API(H5S_NO_CLASS)
1743 H5TRACE1("Sc", "i", sid);
1744
1745 /* Check arguments */
1746 if (NULL == (space = (H5S_t *)H5I_object_verify(sid, H5I_DATASPACE)))
1747 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5S_NO_CLASS, "not a dataspace")
1748
1749 ret_value=H5S_GET_EXTENT_TYPE(space);
1750
1751 done:
1752 FUNC_LEAVE_API(ret_value)
1753 }
1754
1755
1756 /*--------------------------------------------------------------------------
1757 NAME
1758 H5Sset_extent_none
1759 PURPOSE
1760 Resets the extent of a dataspace back to "none"
1761 USAGE
1762 herr_t H5Sset_extent_none(space_id)
1763 hid_t space_id; IN: Dataspace object to reset
1764 RETURNS
1765 Non-negative on success/Negative on failure
1766 DESCRIPTION
1767 This function resets the type of a dataspace back to "none" with no
1768 extent information stored for the dataspace.
1769 --------------------------------------------------------------------------*/
1770 herr_t
H5Sset_extent_none(hid_t space_id)1771 H5Sset_extent_none(hid_t space_id)
1772 {
1773 H5S_t *space; /* dataspace to modify */
1774 herr_t ret_value=SUCCEED; /* Return value */
1775
1776 FUNC_ENTER_API(FAIL)
1777 H5TRACE1("e", "i", space_id);
1778
1779 /* Check args */
1780 if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
1781 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace")
1782
1783 /* Clear the previous extent from the dataspace */
1784 if(H5S_extent_release(&space->extent)<0)
1785 HGOTO_ERROR(H5E_RESOURCE, H5E_CANTDELETE, FAIL, "can't release previous dataspace")
1786
1787 space->extent.type=H5S_NO_CLASS;
1788
1789 done:
1790 FUNC_LEAVE_API(ret_value)
1791 } /* end H5Sset_extent_none() */
1792
1793
1794 /*--------------------------------------------------------------------------
1795 NAME
1796 H5Soffset_simple
1797 PURPOSE
1798 Changes the offset of a selection within a simple dataspace extent
1799 USAGE
1800 herr_t H5Soffset_simple(space_id, offset)
1801 hid_t space_id; IN: Dataspace object to reset
1802 const hssize_t *offset; IN: Offset to position the selection at
1803 RETURNS
1804 Non-negative on success/Negative on failure
1805 DESCRIPTION
1806 This function creates an offset for the selection within an extent, allowing
1807 the same shaped selection to be moved to different locations within a
1808 dataspace without requiring it to be re-defined.
1809 --------------------------------------------------------------------------*/
1810 herr_t
H5Soffset_simple(hid_t space_id,const hssize_t * offset)1811 H5Soffset_simple(hid_t space_id, const hssize_t *offset)
1812 {
1813 H5S_t *space; /* dataspace to modify */
1814 herr_t ret_value=SUCCEED; /* Return value */
1815
1816 FUNC_ENTER_API(FAIL)
1817 H5TRACE2("e", "i*Hs", space_id, offset);
1818
1819 /* Check args */
1820 if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
1821 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "not a dataspace")
1822 if (space->extent.rank==0 || (H5S_GET_EXTENT_TYPE(space)==H5S_SCALAR
1823 || H5S_GET_EXTENT_TYPE(space)==H5S_NULL))
1824 HGOTO_ERROR(H5E_ATOM, H5E_UNSUPPORTED, FAIL, "can't set offset on scalar or null dataspace")
1825 if (offset == NULL)
1826 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no offset specified")
1827
1828 /* Set the selection offset */
1829 if(H5S_select_offset(space,offset)<0)
1830 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't set offset")
1831
1832 done:
1833 FUNC_LEAVE_API(ret_value)
1834 } /* end H5Soffset_simple() */
1835
1836
1837 /*-------------------------------------------------------------------------
1838 * Function: H5S_set_extent
1839 *
1840 * Purpose: Modify the dimensions of a dataspace. Based on H5S_extend
1841 *
1842 * Return: Success: Non-negative
1843 * Failure: Negative
1844 *
1845 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1846 * March 13, 2002
1847 *
1848 *-------------------------------------------------------------------------
1849 */
1850 htri_t
H5S_set_extent(H5S_t * space,const hsize_t * size)1851 H5S_set_extent(H5S_t *space, const hsize_t *size)
1852 {
1853 unsigned u; /* Local index variable */
1854 htri_t ret_value = FALSE; /* Return value */
1855
1856 FUNC_ENTER_NOAPI(FAIL)
1857
1858 /* Check args */
1859 HDassert(space && H5S_SIMPLE == H5S_GET_EXTENT_TYPE(space));
1860 HDassert(size);
1861
1862 /* Verify that the dimensions being changed are allowed to change */
1863 for(u = 0; u < space->extent.rank; u++) {
1864 if(space->extent.size[u] != size[u]) {
1865 /* Check for invalid dimension size modification */
1866 if(space->extent.max && H5S_UNLIMITED != space->extent.max[u] &&
1867 space->extent.max[u] < size[u])
1868 HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "dimension cannot exceed the existing maximal size (new: %llu max: %llu)", (unsigned long long)size[u], (unsigned long long)space->extent.max[u])
1869
1870 /* Indicate that dimension size can be modified */
1871 ret_value = TRUE;
1872 } /* end if */
1873 } /* end for */
1874
1875 /* Update dimension size(s) */
1876 if(ret_value)
1877 if(H5S_set_extent_real(space, size) < 0)
1878 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "failed to change dimension size(s)")
1879
1880 done:
1881 FUNC_LEAVE_NOAPI(ret_value)
1882 } /* end H5S_set_extent() */
1883
1884
1885 /*-------------------------------------------------------------------------
1886 * Function: H5S_has_extent
1887 *
1888 * Purpose: Determines if a simple dataspace's extent has been set (e.g.,
1889 * by H5Sset_extent_simple() ). Helps avoid write errors.
1890 *
1891 * Return: TRUE if dataspace has extent set
1892 * FALSE if dataspace's extent is uninitialized
1893 *
1894 * Programmer: James Laird
1895 *
1896 * Date: July 23, 2004
1897 *
1898 *-------------------------------------------------------------------------
1899 */
1900 hbool_t
H5S_has_extent(const H5S_t * ds)1901 H5S_has_extent(const H5S_t *ds)
1902 {
1903 hbool_t ret_value;
1904
1905 FUNC_ENTER_NOAPI_NOINIT_NOERR
1906
1907 HDassert(ds);
1908
1909 if(0 == ds->extent.rank && 0 == ds->extent.nelem && H5S_NULL != ds->extent.type)
1910 ret_value = FALSE;
1911 else
1912 ret_value = TRUE;
1913
1914 FUNC_LEAVE_NOAPI(ret_value)
1915 } /* end H5S_has_extent() */
1916
1917
1918 /*-------------------------------------------------------------------------
1919 * Function: H5S_set_extent_real
1920 *
1921 * Purpose: Modify the dimensions of a dataspace. Based on H5S_extend
1922 *
1923 * Return: Success: Non-negative
1924 * Failure: Negative
1925 *
1926 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
1927 * March 13, 2002
1928 *
1929 *-------------------------------------------------------------------------
1930 */
1931 herr_t
H5S_set_extent_real(H5S_t * space,const hsize_t * size)1932 H5S_set_extent_real(H5S_t *space, const hsize_t *size)
1933 {
1934 hsize_t nelem; /* Number of elements in extent */
1935 unsigned u; /* Local index variable */
1936 herr_t ret_value = SUCCEED; /* Return value */
1937
1938 FUNC_ENTER_NOAPI(FAIL)
1939
1940 /* Check args */
1941 HDassert(space && H5S_SIMPLE == H5S_GET_EXTENT_TYPE(space));
1942 HDassert(size);
1943
1944 /* Change the dataspace size & re-compute the number of elements in the extent */
1945 for(u = 0, nelem = 1; u < space->extent.rank; u++ ) {
1946 space->extent.size[u] = size[u];
1947 nelem *= size[u];
1948 } /* end for */
1949 space->extent.nelem = nelem;
1950
1951 /* If the selection is 'all', update the number of elements selected */
1952 if(H5S_SEL_ALL == H5S_GET_SELECT_TYPE(space))
1953 if(H5S_select_all(space, FALSE) < 0)
1954 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
1955
1956 /* Mark the dataspace as no longer shared if it was before */
1957 if(H5O_msg_reset_share(H5O_SDSPACE_ID, space) < 0)
1958 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRESET, FAIL, "can't stop sharing dataspace")
1959
1960 done:
1961 FUNC_LEAVE_NOAPI(ret_value)
1962 } /* end H5S_set_extent_real() */
1963
1964
1965 /*-------------------------------------------------------------------------
1966 * Function: H5Sextent_equal
1967 *
1968 * Purpose: Determines if two dataspace extents are equal.
1969 *
1970 * Return: Success: TRUE if equal, FALSE if unequal
1971 *
1972 * Failure: Negative
1973 *
1974 * Programmer: Quincey Koziol
1975 * Monday, October 24, 2005
1976 *
1977 *-------------------------------------------------------------------------
1978 */
1979 htri_t
H5Sextent_equal(hid_t space1_id,hid_t space2_id)1980 H5Sextent_equal(hid_t space1_id, hid_t space2_id)
1981 {
1982 const H5S_t *ds1, *ds2; /* Dataspaces to compare */
1983 htri_t ret_value;
1984
1985 FUNC_ENTER_API(FAIL)
1986 H5TRACE2("t", "ii", space1_id, space2_id);
1987
1988 /* check args */
1989 if(NULL == (ds1 = (const H5S_t *)H5I_object_verify(space1_id, H5I_DATASPACE)) ||
1990 NULL == (ds2 = (const H5S_t *)H5I_object_verify(space2_id, H5I_DATASPACE)))
1991 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
1992
1993 /* Check dataspaces for extent's equality */
1994 if((ret_value = H5S_extent_equal(ds1, ds2)) < 0)
1995 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "dataspace comparison failed")
1996
1997 done:
1998 FUNC_LEAVE_API(ret_value)
1999 } /* end H5Sextent_equal() */
2000
2001
2002 /*--------------------------------------------------------------------------
2003 NAME
2004 H5S_extent_equal
2005 PURPOSE
2006 Check if two dataspaces have equal extents
2007 USAGE
2008 htri_t H5S_extent_equal(ds1, ds2)
2009 H5S_t *ds1, *ds2; IN: Dataspace objects to compare
2010 RETURNS
2011 TRUE if equal, FALSE if unequal on succeess/Negative on failure
2012 DESCRIPTION
2013 Compare two dataspaces if their extents are identical.
2014 --------------------------------------------------------------------------*/
2015 htri_t
H5S_extent_equal(const H5S_t * ds1,const H5S_t * ds2)2016 H5S_extent_equal(const H5S_t *ds1, const H5S_t *ds2)
2017 {
2018 unsigned u; /* Local index variable */
2019 htri_t ret_value = TRUE; /* Return value */
2020
2021 FUNC_ENTER_NOAPI_NOINIT_NOERR
2022
2023 /* Check args */
2024 HDassert(ds1);
2025 HDassert(ds2);
2026
2027 /* Make certain the dataspaces are the same type */
2028 if(ds1->extent.type != ds2->extent.type)
2029 HGOTO_DONE(FALSE)
2030
2031 /* Make certain the dataspaces are the same rank */
2032 if(ds1->extent.rank != ds2->extent.rank)
2033 HGOTO_DONE(FALSE)
2034
2035 /* Make certain the dataspaces' current dimensions are the same size */
2036 if(ds1->extent.rank > 0) {
2037 HDassert(ds1->extent.size);
2038 HDassert(ds2->extent.size);
2039 for(u = 0; u < ds1->extent.rank; u++)
2040 if(ds1->extent.size[u] != ds2->extent.size[u])
2041 HGOTO_DONE(FALSE)
2042 } /* end if */
2043
2044 /* Make certain the dataspaces' maximum dimensions are the same size */
2045 if(ds1->extent.rank > 0) {
2046 /* Check for no maximum dimensions on dataspaces */
2047 if(ds1->extent.max != NULL && ds2->extent.max != NULL) {
2048 for(u = 0; u < ds1->extent.rank; u++)
2049 if(ds1->extent.max[u] != ds2->extent.max[u])
2050 HGOTO_DONE(FALSE)
2051 } /* end if */
2052 else
2053 if((ds1->extent.max == NULL && ds2->extent.max != NULL) ||
2054 (ds1->extent.max != NULL && ds2->extent.max == NULL))
2055 HGOTO_DONE(FALSE)
2056 } /* end if */
2057
2058 done:
2059 FUNC_LEAVE_NOAPI(ret_value)
2060 } /* end H5S_extent_equal() */
2061
2062
2063 /*-------------------------------------------------------------------------
2064 * Function: H5S_extent_nelem
2065 *
2066 * Purpose: Determines how many elements a dataset extent describes.
2067 *
2068 * Return: Success: Number of data points in the dataset extent.
2069 * Failure: negative
2070 *
2071 * Programmer: Quincey Koziol
2072 * Thursday, November 30, 2006
2073 *
2074 *-------------------------------------------------------------------------
2075 */
2076 hsize_t
H5S_extent_nelem(const H5S_extent_t * ext)2077 H5S_extent_nelem(const H5S_extent_t *ext)
2078 {
2079 FUNC_ENTER_NOAPI_NOINIT_NOERR
2080
2081 /* check args */
2082 HDassert(ext);
2083
2084 /* Return the number of elements in extent */
2085 FUNC_LEAVE_NOAPI(ext->nelem)
2086 } /* end H5S_extent_nelem() */
2087
2088
2089 /*-------------------------------------------------------------------------
2090 * Function: H5S_set_latest_version
2091 *
2092 * Purpose: Set the encoding for a dataspace to the latest version.
2093 *
2094 * Return: Non-negative on success/Negative on failure
2095 *
2096 * Programmer: Quincey Koziol
2097 * Tuesday, July 24, 2007
2098 *
2099 *-------------------------------------------------------------------------
2100 */
2101 herr_t
H5S_set_latest_version(H5S_t * ds)2102 H5S_set_latest_version(H5S_t *ds)
2103 {
2104 FUNC_ENTER_NOAPI_NOINIT_NOERR
2105
2106 /* Sanity check */
2107 HDassert(ds);
2108
2109 /* Set encoding of extent to latest version */
2110 ds->extent.version = H5O_SDSPACE_VERSION_LATEST;
2111
2112 FUNC_LEAVE_NOAPI(SUCCEED)
2113 } /* end H5S_set_latest_version() */
2114
2115 #ifndef H5_NO_DEPRECATED_SYMBOLS
2116
2117 /*-------------------------------------------------------------------------
2118 * Function: H5S_extend
2119 *
2120 * Purpose: Extend the dimensions of a dataspace.
2121 *
2122 * Return: Success: Number of dimensions whose size increased.
2123 *
2124 * Failure: Negative
2125 *
2126 * Programmer: Robb Matzke
2127 * Friday, January 30, 1998
2128 *
2129 *-------------------------------------------------------------------------
2130 */
2131 int
H5S_extend(H5S_t * space,const hsize_t * size)2132 H5S_extend(H5S_t *space, const hsize_t *size)
2133 {
2134 unsigned u;
2135 int ret_value = 0;
2136
2137 FUNC_ENTER_NOAPI(FAIL)
2138
2139 /* Check args */
2140 HDassert(space && H5S_SIMPLE == H5S_GET_EXTENT_TYPE(space));
2141 HDassert(size);
2142
2143 /* Check through all the dimensions to see if modifying the dataspace is allowed */
2144 for(u = 0; u < space->extent.rank; u++) {
2145 if(space->extent.size[u]<size[u]) {
2146 if(space->extent.max && H5S_UNLIMITED!=space->extent.max[u] &&
2147 space->extent.max[u]<size[u])
2148 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dimension cannot be increased")
2149 ret_value++;
2150 } /* end if */
2151 } /* end for */
2152
2153 /* Update */
2154 if(ret_value) {
2155 hsize_t nelem; /* Number of elements in extent */
2156
2157 /* Change the dataspace size & re-compute the number of elements in the extent */
2158 for(u = 0, nelem = 1; u < space->extent.rank; u++) {
2159 if(space->extent.size[u] < size[u])
2160 space->extent.size[u] = size[u];
2161
2162 nelem *= space->extent.size[u];
2163 } /* end for */
2164 space->extent.nelem = nelem;
2165
2166 /* If the selection is 'all', update the number of elements selected */
2167 if(H5S_GET_SELECT_TYPE(space) == H5S_SEL_ALL)
2168 if(H5S_select_all(space, FALSE) < 0)
2169 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
2170
2171 /* Mark the dataspace as no longer shared if it was before */
2172 if(H5O_msg_reset_share(H5O_SDSPACE_ID, space) < 0)
2173 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRESET, FAIL, "can't stop sharing dataspace")
2174 } /* end if */
2175
2176 done:
2177 FUNC_LEAVE_NOAPI(ret_value)
2178 } /* end H5S_extend() */
2179 #endif /* H5_NO_DEPRECATED_SYMBOLS */
2180
2181