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