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 /* Programmer: Quincey Koziol <koziol@ncsa.uiuc.ued>
15 * Friday, May 29, 1998
16 *
17 * Purpose: Dataspace selection functions.
18 */
19
20 #include "H5Smodule.h" /* This source code file is part of the H5S module */
21
22
23 #include "H5private.h" /* Generic Functions */
24 #include "H5Dprivate.h" /* Datasets */
25 #include "H5Eprivate.h" /* Error handling */
26 #include "H5FLprivate.h" /* Free Lists */
27 #include "H5Iprivate.h" /* IDs */
28 #include "H5MMprivate.h" /* Memory management */
29 #include "H5Spkg.h" /* Dataspaces */
30 #include "H5VMprivate.h" /* Vector and array functions */
31 #include "H5WBprivate.h" /* Wrapped Buffers */
32
33 /* Local functions */
34 #ifdef LATER
35 static herr_t H5S_select_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end);
36 static htri_t H5S_select_iter_has_next_block(const H5S_sel_iter_t *iter);
37 static herr_t H5S_select_iter_next_block(H5S_sel_iter_t *iter);
38 #endif /* LATER */
39
40 /* Declare a free list to manage the H5S_sel_iter_t struct */
41 H5FL_DEFINE(H5S_sel_iter_t);
42
43 /* Declare extern free list to manage sequences of size_t */
44 H5FL_SEQ_EXTERN(size_t);
45
46 /* Declare extern free list to manage sequences of hsize_t */
47 H5FL_SEQ_EXTERN(hsize_t);
48
49
50
51 /*--------------------------------------------------------------------------
52 NAME
53 H5S_select_offset
54 PURPOSE
55 Set the selection offset for a datapace
56 USAGE
57 herr_t H5S_select_offset(space, offset)
58 H5S_t *space; IN/OUT: Dataspace object to set selection offset
59 const hssize_t *offset; IN: Offset to position the selection at
60 RETURNS
61 Non-negative on success/Negative on failure
62 DESCRIPTION
63 Sets the selection offset for the dataspace
64 GLOBAL VARIABLES
65 COMMENTS, BUGS, ASSUMPTIONS
66 Only works for simple dataspaces currently
67 EXAMPLES
68 REVISION LOG
69 --------------------------------------------------------------------------*/
70 herr_t
H5S_select_offset(H5S_t * space,const hssize_t * offset)71 H5S_select_offset(H5S_t *space, const hssize_t *offset)
72 {
73 FUNC_ENTER_NOAPI_NOINIT_NOERR
74
75 /* Check args */
76 HDassert(space);
77 HDassert(0 < space->extent.rank && space->extent.rank <= H5S_MAX_RANK);
78 HDassert(offset);
79
80 /* Copy the offset over */
81 HDmemcpy(space->select.offset, offset, sizeof(hssize_t)*space->extent.rank);
82
83 /* Indicate that the offset was changed */
84 space->select.offset_changed = TRUE;
85
86 FUNC_LEAVE_NOAPI(SUCCEED)
87 } /* H5S_select_offset() */
88
89
90 /*--------------------------------------------------------------------------
91 NAME
92 H5S_select_copy
93 PURPOSE
94 Copy a selection from one dataspace to another
95 USAGE
96 herr_t H5S_select_copy(dst, src)
97 H5S_t *dst; OUT: Pointer to the destination dataspace
98 H5S_t *src; IN: Pointer to the source dataspace
99 RETURNS
100 Non-negative on success/Negative on failure
101 DESCRIPTION
102 Copies all the selection information (include offset) from the source
103 dataspace to the destination dataspace.
104
105 If the SHARE_SELECTION flag is set, then the selection can be shared
106 between the source and destination dataspaces. (This should only occur in
107 situations where the destination dataspace will immediately change to a new
108 selection)
109 GLOBAL VARIABLES
110 COMMENTS, BUGS, ASSUMPTIONS
111 EXAMPLES
112 REVISION LOG
113 --------------------------------------------------------------------------*/
114 herr_t
H5S_select_copy(H5S_t * dst,const H5S_t * src,hbool_t share_selection)115 H5S_select_copy(H5S_t *dst, const H5S_t *src, hbool_t share_selection)
116 {
117 herr_t ret_value = FAIL; /* Return value */
118
119 FUNC_ENTER_NOAPI(FAIL)
120
121 /* Check args */
122 HDassert(dst);
123 HDassert(src);
124
125 /* Copy regular fields */
126 dst->select = src->select;
127
128 /* Perform correct type of copy based on the type of selection */
129 if((ret_value = (*src->select.type->copy)(dst,src,share_selection)) < 0)
130 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy selection specific information")
131
132 done:
133 FUNC_LEAVE_NOAPI(ret_value)
134 } /* H5S_select_copy() */
135
136
137 /*-------------------------------------------------------------------------
138 * Function: H5S_select_release
139 *
140 * Purpose: Releases all memory associated with a dataspace selection.
141 *
142 * Return: Non-negative on success/Negative on failure
143 *
144 * Programmer: Quincey Koziol
145 * Friday, May 30, 2003
146 *
147 * Note: This routine participates in the "Inlining C function pointers"
148 * pattern, don't call it directly, use the appropriate macro
149 * defined in H5Sprivate.h.
150 *
151 *-------------------------------------------------------------------------
152 */
153 herr_t
H5S_select_release(H5S_t * ds)154 H5S_select_release(H5S_t *ds)
155 {
156 herr_t ret_value = FAIL; /* Return value */
157
158 FUNC_ENTER_NOAPI_NOINIT
159
160 HDassert(ds);
161
162 /* Call the selection type's release function */
163 if((ds->select.type) && ((ret_value = (*ds->select.type->release)(ds)) < 0))
164 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection")
165
166 done:
167 FUNC_LEAVE_NOAPI(ret_value)
168 } /* end H5S_select_release() */
169
170
171 /*-------------------------------------------------------------------------
172 * Function: H5S_select_get_seq_list
173 *
174 * Purpose: Retrieves the next sequence of offset/length pairs for an
175 * iterator on a dataspace
176 *
177 * Return: Non-negative on success/Negative on failure
178 *
179 * Programmer: Quincey Koziol
180 * Tuesday, May 18, 2004
181 *
182 * Note: This routine participates in the "Inlining C function pointers"
183 * pattern, don't call it directly, use the appropriate macro
184 * defined in H5Sprivate.h.
185 *
186 *-------------------------------------------------------------------------
187 */
188 herr_t
H5S_select_get_seq_list(const H5S_t * space,unsigned flags,H5S_sel_iter_t * iter,size_t maxseq,size_t maxbytes,size_t * nseq,size_t * nbytes,hsize_t * off,size_t * len)189 H5S_select_get_seq_list(const H5S_t *space, unsigned flags,
190 H5S_sel_iter_t *iter, size_t maxseq, size_t maxbytes,
191 size_t *nseq, size_t *nbytes, hsize_t *off, size_t *len)
192 {
193 herr_t ret_value = FAIL; /* Return value */
194
195 FUNC_ENTER_NOAPI_NOINIT
196
197 HDassert(space);
198
199 /* Call the selection type's get_seq_list function */
200 if((ret_value = (*space->select.type->get_seq_list)(space, flags, iter, maxseq, maxbytes, nseq, nbytes, off, len)) < 0)
201 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get selection sequence list")
202
203 done:
204 FUNC_LEAVE_NOAPI(ret_value)
205 } /* end H5S_select_get_seq_list() */
206
207
208 /*-------------------------------------------------------------------------
209 * Function: H5S_select_serial_size
210 *
211 * Purpose: Determines the number of bytes required to store the current
212 * selection
213 *
214 * Return: Non-negative on success/Negative on failure
215 *
216 * Programmer: Quincey Koziol
217 * Tuesday, May 18, 2004
218 *
219 * Note: This routine participates in the "Inlining C function pointers"
220 * pattern, don't call it directly, use the appropriate macro
221 * defined in H5Sprivate.h.
222 *
223 *-------------------------------------------------------------------------
224 */
225 hssize_t
H5S_select_serial_size(const H5S_t * space)226 H5S_select_serial_size(const H5S_t *space)
227 {
228 hssize_t ret_value = -1; /* Return value */
229
230 FUNC_ENTER_NOAPI_NOINIT_NOERR
231
232 HDassert(space);
233
234 /* Call the selection type's serial_size function */
235 ret_value=(*space->select.type->serial_size)(space);
236
237 FUNC_LEAVE_NOAPI(ret_value)
238 } /* end H5S_select_serial_size() */
239
240
241 /*--------------------------------------------------------------------------
242 NAME
243 H5S_select_serialize
244 PURPOSE
245 Serialize the selection for a dataspace into a buffer
246 USAGE
247 herr_t H5S_select_serialize(space, p)
248 const H5S_t *space; IN: Dataspace with selection to serialize
249 uint8_t **p; OUT: Pointer to buffer to put serialized
250 selection. Will be advanced to end of
251 serialized selection.
252 RETURNS
253 Non-negative on success/Negative on failure
254 DESCRIPTION
255 Calls the appropriate dataspace selection callback to serialize the
256 current selection into a buffer.
257 GLOBAL VARIABLES
258 COMMENTS, BUGS, ASSUMPTIONS
259 This routine participates in the "Inlining C function pointers"
260 pattern, don't call it directly, use the appropriate macro
261 defined in H5Sprivate.h.
262 EXAMPLES
263 REVISION LOG
264 --------------------------------------------------------------------------*/
265 herr_t
H5S_select_serialize(const H5S_t * space,uint8_t ** p)266 H5S_select_serialize(const H5S_t *space, uint8_t **p)
267 {
268 herr_t ret_value=SUCCEED; /* Return value */
269
270 FUNC_ENTER_NOAPI_NOINIT_NOERR
271
272 HDassert(space);
273 HDassert(p);
274
275 /* Call the selection type's serialize function */
276 ret_value=(*space->select.type->serialize)(space,p);
277
278 FUNC_LEAVE_NOAPI(ret_value)
279 } /* end H5S_select_serialize() */
280
281
282 /*--------------------------------------------------------------------------
283 NAME
284 H5Sget_select_npoints
285 PURPOSE
286 Get the number of elements in current selection
287 USAGE
288 hssize_t H5Sget_select_npoints(dsid)
289 hid_t dsid; IN: Dataspace ID of selection to query
290 RETURNS
291 Non-negative on success/Negative on failure
292 DESCRIPTION
293 Returns the number of elements in current selection for dataspace.
294 GLOBAL VARIABLES
295 COMMENTS, BUGS, ASSUMPTIONS
296 EXAMPLES
297 REVISION LOG
298 --------------------------------------------------------------------------*/
299 hssize_t
H5Sget_select_npoints(hid_t spaceid)300 H5Sget_select_npoints(hid_t spaceid)
301 {
302 H5S_t *space; /* Dataspace to modify selection of */
303 hssize_t ret_value; /* return value */
304
305 FUNC_ENTER_API(FAIL)
306 H5TRACE1("Hs", "i", spaceid);
307
308 /* Check args */
309 if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
310 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
311
312 ret_value = (hssize_t)H5S_GET_SELECT_NPOINTS(space);
313
314 done:
315 FUNC_LEAVE_API(ret_value)
316 } /* H5Sget_select_npoints() */
317
318
319 /*--------------------------------------------------------------------------
320 NAME
321 H5S_get_select_npoints
322 PURPOSE
323 Get the number of elements in current selection
324 USAGE
325 hssize_t H5Sget_select_npoints(space)
326 H5S_t *space; IN: Dataspace of selection to query
327 RETURNS
328 The number of elements in selection on success, 0 on failure
329 DESCRIPTION
330 Returns the number of elements in current selection for dataspace.
331 GLOBAL VARIABLES
332 COMMENTS, BUGS, ASSUMPTIONS
333 This routine participates in the "Inlining C function pointers"
334 pattern, don't call it directly, use the appropriate macro
335 defined in H5Sprivate.h.
336 EXAMPLES
337 REVISION LOG
338 --------------------------------------------------------------------------*/
339 hssize_t
H5S_get_select_npoints(const H5S_t * space)340 H5S_get_select_npoints(const H5S_t *space)
341 {
342 FUNC_ENTER_NOAPI_NOINIT_NOERR
343
344 /* Check args */
345 HDassert(space);
346
347 FUNC_LEAVE_NOAPI((hssize_t)space->select.num_elem)
348 } /* H5S_get_select_npoints() */
349
350
351 /*--------------------------------------------------------------------------
352 NAME
353 H5Sselect_valid
354 PURPOSE
355 Check whether the selection fits within the extent, with the current
356 offset defined.
357 USAGE
358 htri_t H5Sselect_void(dsid)
359 hid_t dsid; IN: Dataspace ID to query
360 RETURNS
361 TRUE if the selection fits within the extent, FALSE if it does not and
362 Negative on an error.
363 DESCRIPTION
364 Determines if the current selection at the current offset fits within the
365 extent for the dataspace.
366 GLOBAL VARIABLES
367 COMMENTS, BUGS, ASSUMPTIONS
368 EXAMPLES
369 REVISION LOG
370 Christian Chilan 01/17/2007
371 Changed the error return value from 0 to FAIL.
372 --------------------------------------------------------------------------*/
373 htri_t
H5Sselect_valid(hid_t spaceid)374 H5Sselect_valid(hid_t spaceid)
375 {
376 H5S_t *space; /* Dataspace to modify selection of */
377 htri_t ret_value; /* return value */
378
379 FUNC_ENTER_API(FAIL)
380 H5TRACE1("t", "i", spaceid);
381
382 /* Check args */
383 if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
384 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
385
386 ret_value = H5S_SELECT_VALID(space);
387
388 done:
389 FUNC_LEAVE_API(ret_value)
390 } /* H5Sselect_valid() */
391
392
393 /*--------------------------------------------------------------------------
394 NAME
395 H5S_select_valid
396 PURPOSE
397 Check whether the selection fits within the extent, with the current
398 offset defined.
399 USAGE
400 htri_t H5S_select_void(space)
401 H5S_t *space; IN: Dataspace to query
402 RETURNS
403 TRUE if the selection fits within the extent, FALSE if it does not and
404 Negative on an error.
405 DESCRIPTION
406 Determines if the current selection at the current offset fits within the
407 extent for the dataspace.
408 GLOBAL VARIABLES
409 COMMENTS, BUGS, ASSUMPTIONS
410 This routine participates in the "Inlining C function pointers"
411 pattern, don't call it directly, use the appropriate macro
412 defined in H5Sprivate.h.
413 EXAMPLES
414 REVISION LOG
415 --------------------------------------------------------------------------*/
416 htri_t
H5S_select_valid(const H5S_t * space)417 H5S_select_valid(const H5S_t *space)
418 {
419 htri_t ret_value = FAIL; /* Return value */
420
421 FUNC_ENTER_NOAPI_NOINIT_NOERR
422
423 HDassert(space);
424
425 ret_value = (*space->select.type->is_valid)(space);
426
427 FUNC_LEAVE_NOAPI(ret_value)
428 } /* H5S_select_valid() */
429
430
431 /*--------------------------------------------------------------------------
432 NAME
433 H5S_select_deserialize
434 PURPOSE
435 Deserialize the current selection from a user-provided buffer into a real
436 selection in the dataspace.
437 USAGE
438 herr_t H5S_select_deserialize(space, p)
439 H5S_t **space; IN/OUT: Dataspace pointer to place
440 selection into. Will be allocated if not
441 provided.
442 uint8 **p; OUT: Pointer to buffer holding serialized
443 selection. Will be advanced to end of
444 serialized selection.
445 RETURNS
446 Non-negative on success/Negative on failure
447 DESCRIPTION
448 Deserializes the current selection into a buffer. (Primarily for retrieving
449 from disk). This routine just hands off to the appropriate routine for each
450 type of selection. The format of the serialized information is shown in
451 the H5S_select_serialize() header.
452 GLOBAL VARIABLES
453 COMMENTS, BUGS, ASSUMPTIONS
454 EXAMPLES
455 REVISION LOG
456 --------------------------------------------------------------------------*/
457 herr_t
H5S_select_deserialize(H5S_t ** space,const uint8_t ** p)458 H5S_select_deserialize(H5S_t **space, const uint8_t **p)
459 {
460 uint32_t sel_type; /* Pointer to the selection type */
461 herr_t ret_value = FAIL; /* Return value */
462
463 FUNC_ENTER_NOAPI(FAIL)
464
465 HDassert(space);
466
467 /* Selection-type specific coding is moved to the callbacks. */
468
469 /* Decode selection type */
470 UINT32DECODE(*p, sel_type);
471
472 /* Make routine for selection type */
473 switch(sel_type) {
474 case H5S_SEL_POINTS: /* Sequence of points selected */
475 ret_value = (*H5S_sel_point->deserialize)(space, p);
476 break;
477
478 case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */
479 ret_value = (*H5S_sel_hyper->deserialize)(space, p);
480 break;
481
482 case H5S_SEL_ALL: /* Entire extent selected */
483 ret_value = (*H5S_sel_all->deserialize)(space, p);
484 break;
485
486 case H5S_SEL_NONE: /* Nothing selected */
487 ret_value = (*H5S_sel_all->deserialize)(space, p);
488 break;
489
490 default:
491 break;
492 }
493
494 if(ret_value < 0)
495 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "can't deserialize selection")
496
497 done:
498 FUNC_LEAVE_NOAPI(ret_value)
499 } /* H5S_select_deserialize() */
500
501
502 /*--------------------------------------------------------------------------
503 NAME
504 H5Sget_select_bounds
505 PURPOSE
506 Gets the bounding box containing the selection.
507 USAGE
508 herr_t H5S_get_select_bounds(space, start, end)
509 hid_t dsid; IN: Dataspace ID of selection to query
510 hsize_t start[]; OUT: Starting coordinate of bounding box
511 hsize_t end[]; OUT: Opposite coordinate of bounding box
512 RETURNS
513 Non-negative on success, negative on failure
514 DESCRIPTION
515 Retrieves the bounding box containing the current selection and places
516 it into the user's buffers. The start and end buffers must be large
517 enough to hold the dataspace rank number of coordinates. The bounding box
518 exactly contains the selection, ie. if a 2-D element selection is currently
519 defined with the following points: (4,5), (6,8) (10,7), the bounding box
520 with be (4, 5), (10, 8). Calling this function on a "none" selection
521 returns fail.
522 The bounding box calculations _does_ include the current offset of the
523 selection within the dataspace extent.
524 GLOBAL VARIABLES
525 COMMENTS, BUGS, ASSUMPTIONS
526 This routine participates in the "Inlining C function pointers"
527 pattern, don't call it directly, use the appropriate macro
528 defined in H5Sprivate.h.
529 EXAMPLES
530 REVISION LOG
531 --------------------------------------------------------------------------*/
532 herr_t
H5Sget_select_bounds(hid_t spaceid,hsize_t start[],hsize_t end[])533 H5Sget_select_bounds(hid_t spaceid, hsize_t start[], hsize_t end[])
534 {
535 H5S_t *space; /* Dataspace to modify selection of */
536 herr_t ret_value; /* return value */
537
538 FUNC_ENTER_API(FAIL)
539 H5TRACE3("e", "i*h*h", spaceid, start, end);
540
541 /* Check args */
542 if(start == NULL || end == NULL)
543 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer")
544 if(NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE)))
545 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
546
547 ret_value = H5S_SELECT_BOUNDS(space, start, end);
548
549 done:
550 FUNC_LEAVE_API(ret_value)
551 } /* H5Sget_select_bounds() */
552
553
554 /*--------------------------------------------------------------------------
555 NAME
556 H5S_get_select_bounds
557 PURPOSE
558 Gets the bounding box containing the selection.
559 USAGE
560 herr_t H5S_get_select_bounds(space, start, end)
561 H5S_t *space; IN: Dataspace ID of selection to query
562 hsize_t *start; OUT: Starting coordinate of bounding box
563 hsize_t *end; OUT: Opposite coordinate of bounding box
564 RETURNS
565 Non-negative on success, negative on failure
566 DESCRIPTION
567 Retrieves the bounding box containing the current selection and places
568 it into the user's buffers. The start and end buffers must be large
569 enough to hold the dataspace rank number of coordinates. The bounding box
570 exactly contains the selection, ie. if a 2-D element selection is currently
571 defined with the following points: (4,5), (6,8) (10,7), the bounding box
572 with be (4, 5), (10, 8). Calling this function on a "none" selection
573 returns fail.
574 The bounding box calculations _does_ include the current offset of the
575 selection within the dataspace extent.
576 GLOBAL VARIABLES
577 COMMENTS, BUGS, ASSUMPTIONS
578 EXAMPLES
579 REVISION LOG
580 --------------------------------------------------------------------------*/
581 herr_t
H5S_get_select_bounds(const H5S_t * space,hsize_t * start,hsize_t * end)582 H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end)
583 {
584 herr_t ret_value = FAIL; /* Return value */
585
586 FUNC_ENTER_NOAPI_NOINIT_NOERR
587
588 /* Check args */
589 HDassert(space);
590 HDassert(start);
591 HDassert(end);
592
593 ret_value = (*space->select.type->bounds)(space,start,end);
594
595 FUNC_LEAVE_NOAPI(ret_value)
596 } /* H5S_get_select_bounds() */
597
598
599 /*--------------------------------------------------------------------------
600 NAME
601 H5S_get_select_offset
602 PURPOSE
603 Gets the linear offset of the first element for the selection.
604 USAGE
605 herr_t H5S_get_select_offset(space, offset)
606 const H5S_t *space; IN: Dataspace pointer of selection to query
607 hsize_t *offset; OUT: Linear offset of first element in selection
608 RETURNS
609 Non-negative on success, negative on failure
610 DESCRIPTION
611 Retrieves the linear offset (in "units" of elements) of the first element
612 selected within the dataspace.
613 GLOBAL VARIABLES
614 COMMENTS, BUGS, ASSUMPTIONS
615 The offset calculation _does_ include the current offset of the
616 selection within the dataspace extent.
617
618 Calling this function on a "none" selection returns fail.
619 EXAMPLES
620 REVISION LOG
621 --------------------------------------------------------------------------*/
622 herr_t
H5S_get_select_offset(const H5S_t * space,hsize_t * offset)623 H5S_get_select_offset(const H5S_t *space, hsize_t *offset)
624 {
625 herr_t ret_value = FAIL; /* Return value */
626
627 FUNC_ENTER_NOAPI_NOINIT_NOERR
628
629 /* Check args */
630 HDassert(space);
631 HDassert(offset);
632
633 ret_value = (*space->select.type->offset)(space, offset);
634
635 FUNC_LEAVE_NOAPI(ret_value)
636 } /* H5S_get_select_offset() */
637
638
639 /*--------------------------------------------------------------------------
640 NAME
641 H5S_get_select_unlim_dim
642 PURPOSE
643 Gets the unlimited dimension in the selection, or -1 if there is no
644 unlimited dimension.
645 USAGE
646 int H5S_get_select_unlim_dim(space)
647 const H5S_t *space; IN: Dataspace pointer of selection to query
648 RETURNS
649 Unlimited dimension in the selection, or -1 if there is no unlimited
650 dimension (never fails)
651 DESCRIPTION
652 Gets the unlimited dimension in the selection, or -1 if there is no
653 unlimited dimension.
654 GLOBAL VARIABLES
655 COMMENTS, BUGS, ASSUMPTIONS
656 Currently only implemented for hyperslab selections, all others
657 simply return -1.
658 EXAMPLES
659 REVISION LOG
660 --------------------------------------------------------------------------*/
661 int
H5S_get_select_unlim_dim(const H5S_t * space)662 H5S_get_select_unlim_dim(const H5S_t *space)
663 {
664 herr_t ret_value = FAIL; /* Return value */
665
666 FUNC_ENTER_NOAPI_NOINIT_NOERR
667
668 /* Check args */
669 HDassert(space);
670
671 ret_value = (*space->select.type->unlim_dim)(space);
672
673 FUNC_LEAVE_NOAPI(ret_value)
674 } /* H5S_get_select_unlim_dim() */
675
676
677 /*--------------------------------------------------------------------------
678 NAME
679 H5S_get_select_num_elem_non_unlim
680 PURPOSE
681 Gets the number of elements in the non-unlimited dimensions
682 USAGE
683 herr_t H5S_get_select_num_elem_non_unlim(space,num_elem_non_unlim)
684 H5S_t *space; IN: Dataspace pointer to check
685 hsize_t *num_elem_non_unlim; OUT: Number of elements in the non-unlimited dimensions
686 RETURNS
687 Non-negative on success/Negative on failure
688 DESCRIPTION
689 Returns the number of elements in a slice through the non-unlimited
690 dimensions of the selection. Fails if the selection has no unlimited
691 dimension.
692 GLOBAL VARIABLES
693 COMMENTS, BUGS, ASSUMPTIONS
694 EXAMPLES
695 REVISION LOG
696 --------------------------------------------------------------------------*/
697 herr_t
H5S_get_select_num_elem_non_unlim(const H5S_t * space,hsize_t * num_elem_non_unlim)698 H5S_get_select_num_elem_non_unlim(const H5S_t *space,
699 hsize_t *num_elem_non_unlim)
700 {
701 herr_t ret_value = SUCCEED; /* return value */
702
703 FUNC_ENTER_NOAPI(FAIL)
704
705 /* Check args */
706 HDassert(space);
707 HDassert(num_elem_non_unlim);
708
709 /* Check for selection callback */
710 if(!space->select.type->num_elem_non_unlim)
711 HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "selection type has no num_elem_non_unlim callback")
712
713 /* Make selection callback */
714 if((*space->select.type->num_elem_non_unlim)(space, num_elem_non_unlim) < 0)
715 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements in non-unlimited dimension")
716
717 done:
718 FUNC_LEAVE_NOAPI(ret_value)
719 } /* H5S_get_select_unlim_dim() */
720
721
722 /*--------------------------------------------------------------------------
723 NAME
724 H5S_select_is_contiguous
725 PURPOSE
726 Determines if a selection is contiguous in the dataspace
727 USAGE
728 htri_t H5S_select_is_contiguous(space)
729 const H5S_t *space; IN: Dataspace of selection to query
730 RETURNS
731 Non-negative (TRUE/FALSE) on success, negative on failure
732 DESCRIPTION
733 Checks the selection to determine if the points to iterated over will be
734 contiguous in the particular dataspace.
735 GLOBAL VARIABLES
736 COMMENTS, BUGS, ASSUMPTIONS
737 This routine participates in the "Inlining C function pointers"
738 pattern, don't call it directly, use the appropriate macro
739 defined in H5Sprivate.h.
740 EXAMPLES
741 REVISION LOG
742 --------------------------------------------------------------------------*/
743 htri_t
H5S_select_is_contiguous(const H5S_t * space)744 H5S_select_is_contiguous(const H5S_t *space)
745 {
746 herr_t ret_value = FAIL; /* Return value */
747
748 FUNC_ENTER_NOAPI_NOINIT_NOERR
749
750 /* Check args */
751 HDassert(space);
752
753 ret_value = (*space->select.type->is_contiguous)(space);
754
755 FUNC_LEAVE_NOAPI(ret_value)
756 } /* H5S_select_is_contiguous() */
757
758
759 /*--------------------------------------------------------------------------
760 NAME
761 H5S_select_is_single
762 PURPOSE
763 Determines if a selection is a single block in the dataspace
764 USAGE
765 htri_t H5S_select_is_single(space)
766 const H5S_t *space; IN: Dataspace of selection to query
767 RETURNS
768 Non-negative (TRUE/FALSE) on success, negative on failure
769 DESCRIPTION
770 Checks the selection to determine if it occupies a single block in the
771 particular dataspace.
772 GLOBAL VARIABLES
773 COMMENTS, BUGS, ASSUMPTIONS
774 This routine participates in the "Inlining C function pointers"
775 pattern, don't call it directly, use the appropriate macro
776 defined in H5Sprivate.h.
777 EXAMPLES
778 REVISION LOG
779 --------------------------------------------------------------------------*/
780 htri_t
H5S_select_is_single(const H5S_t * space)781 H5S_select_is_single(const H5S_t *space)
782 {
783 herr_t ret_value = FAIL; /* Return value */
784
785 FUNC_ENTER_NOAPI_NOINIT_NOERR
786
787 /* Check args */
788 HDassert(space);
789
790 ret_value = (*space->select.type->is_single)(space);
791
792 FUNC_LEAVE_NOAPI(ret_value)
793 } /* H5S_select_is_single() */
794
795
796 /*--------------------------------------------------------------------------
797 NAME
798 H5S_select_is_regular
799 PURPOSE
800 Determines if a selection is "regular" in the dataspace
801 USAGE
802 htri_t H5S_select_is_regular(space)
803 const H5S_t *space; IN: Dataspace of selection to query
804 RETURNS
805 Non-negative (TRUE/FALSE) on success, negative on failure
806 DESCRIPTION
807 Checks the selection to determine if it is "regular" (i.e. a single
808 block or a strided pattern) in the particular dataspace.
809 GLOBAL VARIABLES
810 COMMENTS, BUGS, ASSUMPTIONS
811 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 EXAMPLES
815 REVISION LOG
816 --------------------------------------------------------------------------*/
817 htri_t
H5S_select_is_regular(const H5S_t * space)818 H5S_select_is_regular(const H5S_t *space)
819 {
820 herr_t ret_value = FAIL; /* Return value */
821
822 FUNC_ENTER_NOAPI_NOINIT_NOERR
823
824 /* Check args */
825 HDassert(space);
826
827 ret_value = (*space->select.type->is_regular)(space);
828
829 FUNC_LEAVE_NOAPI(ret_value)
830 } /* H5S_select_is_regular() */
831
832
833 /*--------------------------------------------------------------------------
834 NAME
835 H5S_select_adjust_u
836 PURPOSE
837 Adjust a selection by subtracting an offset
838 USAGE
839 void H5S_select_adjust_u(space, offset)
840 H5S_t *space; IN/OUT: Pointer to dataspace to adjust
841 const hsize_t *offset; IN: Offset to subtract
842 RETURNS
843 None
844 DESCRIPTION
845 Moves a selection by subtracting an offset from it.
846 GLOBAL VARIABLES
847 COMMENTS, BUGS, ASSUMPTIONS
848 This routine participates in the "Inlining C function pointers"
849 pattern, don't call it directly, use the appropriate macro
850 defined in H5Sprivate.h.
851 EXAMPLES
852 REVISION LOG
853 --------------------------------------------------------------------------*/
854 void
H5S_select_adjust_u(H5S_t * space,const hsize_t * offset)855 H5S_select_adjust_u(H5S_t *space, const hsize_t *offset)
856 {
857 FUNC_ENTER_NOAPI_NOINIT_NOERR
858
859 /* Check args */
860 HDassert(space);
861 HDassert(offset);
862
863 (*space->select.type->adjust_u)(space, offset);
864
865 FUNC_LEAVE_NOAPI_VOID
866 } /* H5S_select_adjust_u() */
867
868
869 /*--------------------------------------------------------------------------
870 NAME
871 H5S_select_project_scalar
872 PURPOSE
873 Project a single element selection for a scalar dataspace
874 USAGE
875 herr_t H5S_select_project_scalar(space, offset)
876 const H5S_t *space; IN: Pointer to dataspace to project
877 hsize_t *offset; IN/OUT: Offset of projected point
878 RETURNS
879 Non-negative on success, negative on failure
880 DESCRIPTION
881 Projects a selection of a single element into a scalar dataspace, computing
882 the offset of the element in the original selection.
883 GLOBAL VARIABLES
884 COMMENTS, BUGS, ASSUMPTIONS
885 This routine participates in the "Inlining C function pointers"
886 pattern, don't call it directly, use the appropriate macro
887 defined in H5Sprivate.h.
888 EXAMPLES
889 REVISION LOG
890 --------------------------------------------------------------------------*/
891 herr_t
H5S_select_project_scalar(const H5S_t * space,hsize_t * offset)892 H5S_select_project_scalar(const H5S_t *space, hsize_t *offset)
893 {
894 herr_t ret_value = FAIL; /* Return value */
895
896 FUNC_ENTER_NOAPI_NOINIT_NOERR
897
898 /* Check args */
899 HDassert(space);
900 HDassert(offset);
901
902 ret_value = (*space->select.type->project_scalar)(space, offset);
903
904 FUNC_LEAVE_NOAPI(ret_value)
905 } /* H5S_select_project_scalar() */
906
907
908 /*--------------------------------------------------------------------------
909 NAME
910 H5S_select_project_simple
911 PURPOSE
912 Project a selection onto/into a dataspace of different rank
913 USAGE
914 herr_t H5S_select_project_simple(space, new_space, offset)
915 const H5S_t *space; IN: Pointer to dataspace to project
916 H5S_t *new_space; IN/OUT: Pointer to dataspace projected onto
917 hsize_t *offset; IN/OUT: Offset of projected point
918 RETURNS
919 Non-negative on success, negative on failure
920 DESCRIPTION
921 Projects a selection onto/into a simple dataspace, computing
922 the offset of the first element in the original selection.
923 GLOBAL VARIABLES
924 COMMENTS, BUGS, ASSUMPTIONS
925 This routine participates in the "Inlining C function pointers"
926 pattern, don't call it directly, use the appropriate macro
927 defined in H5Sprivate.h.
928 EXAMPLES
929 REVISION LOG
930 --------------------------------------------------------------------------*/
931 herr_t
H5S_select_project_simple(const H5S_t * space,H5S_t * new_space,hsize_t * offset)932 H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset)
933 {
934 herr_t ret_value = FAIL; /* Return value */
935
936 FUNC_ENTER_NOAPI_NOINIT_NOERR
937
938 /* Check args */
939 HDassert(space);
940 HDassert(new_space);
941 HDassert(offset);
942
943 ret_value = (*space->select.type->project_simple)(space, new_space, offset);
944
945 FUNC_LEAVE_NOAPI(ret_value)
946 } /* H5S_select_project_simple() */
947
948
949 /*--------------------------------------------------------------------------
950 NAME
951 H5S_select_iter_init
952 PURPOSE
953 Initializes iteration information for a selection.
954 USAGE
955 herr_t H5S_select_iter_init(sel_iter, space, elmt_size)
956 H5S_sel_iter_t *sel_iter; OUT: Selection iterator to initialize.
957 H5S_t *space; IN: Dataspace object containing selection to
958 iterate over
959 size_t elmt_size; IN: Size of elements in the selection
960 RETURNS
961 Non-negative on success, negative on failure.
962 DESCRIPTION
963 Initialize the selection iterator object to point to the first element
964 in the dataspace's selection.
965 --------------------------------------------------------------------------*/
966 herr_t
H5S_select_iter_init(H5S_sel_iter_t * sel_iter,const H5S_t * space,size_t elmt_size)967 H5S_select_iter_init(H5S_sel_iter_t *sel_iter, const H5S_t *space, size_t elmt_size)
968 {
969 herr_t ret_value = FAIL; /* Return value */
970
971 FUNC_ENTER_NOAPI_NOINIT_NOERR
972
973 /* Check args */
974 HDassert(sel_iter);
975 HDassert(space);
976
977 /* Initialize common information */
978
979 /* Save the dataspace's rank */
980 sel_iter->rank = space->extent.rank;
981
982 /* Point to the dataspace dimensions, if there are any */
983 if(sel_iter->rank > 0)
984 sel_iter->dims = space->extent.size;
985 else
986 sel_iter->dims = NULL;
987
988 /* Save the element size */
989 sel_iter->elmt_size = elmt_size;
990
991 /* Call initialization routine for selection type */
992 ret_value = (*space->select.type->iter_init)(sel_iter, space);
993 HDassert(sel_iter->type);
994
995 FUNC_LEAVE_NOAPI(ret_value)
996 } /* H5S_select_iter_init() */
997
998
999 /*--------------------------------------------------------------------------
1000 NAME
1001 H5S_select_iter_coords
1002 PURPOSE
1003 Get the coordinates of the current iterator position
1004 USAGE
1005 herr_t H5S_select_iter_coords(sel_iter,coords)
1006 H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
1007 hsize_t *coords; OUT: Array to place iterator coordinates in
1008 RETURNS
1009 Non-negative on success, negative on failure.
1010 DESCRIPTION
1011 The current location of the iterator within the selection is placed in
1012 the COORDS array.
1013 GLOBAL VARIABLES
1014 COMMENTS, BUGS, ASSUMPTIONS
1015 This routine participates in the "Inlining C function pointers"
1016 pattern, don't call it directly, use the appropriate macro
1017 defined in H5Sprivate.h.
1018 EXAMPLES
1019 REVISION LOG
1020 --------------------------------------------------------------------------*/
1021 herr_t
H5S_select_iter_coords(const H5S_sel_iter_t * sel_iter,hsize_t * coords)1022 H5S_select_iter_coords(const H5S_sel_iter_t *sel_iter, hsize_t *coords)
1023 {
1024 herr_t ret_value = FAIL; /* Return value */
1025
1026 FUNC_ENTER_NOAPI_NOINIT_NOERR
1027
1028 /* Check args */
1029 HDassert(sel_iter);
1030 HDassert(coords);
1031
1032 /* Call iter_coords routine for selection type */
1033 ret_value = (*sel_iter->type->iter_coords)(sel_iter,coords);
1034
1035 FUNC_LEAVE_NOAPI(ret_value)
1036 } /* H5S_select_iter_coords() */
1037
1038 #ifdef LATER
1039
1040 /*--------------------------------------------------------------------------
1041 NAME
1042 H5S_select_iter_block
1043 PURPOSE
1044 Get the block of the current iterator position
1045 USAGE
1046 herr_t H5S_select_iter_block(sel_iter,start,end)
1047 const H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
1048 hsize_t *start; OUT: Array to place iterator start block coordinates
1049 hsize_t *end; OUT: Array to place iterator end block coordinates
1050 RETURNS
1051 Non-negative on success, negative on failure.
1052 DESCRIPTION
1053 The current location of the iterator within the selection is placed in
1054 the COORDS array.
1055 GLOBAL VARIABLES
1056 COMMENTS, BUGS, ASSUMPTIONS
1057 This routine participates in the "Inlining C function pointers"
1058 pattern, don't call it directly, use the appropriate macro
1059 defined in H5Sprivate.h.
1060 EXAMPLES
1061 REVISION LOG
1062 --------------------------------------------------------------------------*/
1063 static herr_t
H5S_select_iter_block(const H5S_sel_iter_t * iter,hsize_t * start,hsize_t * end)1064 H5S_select_iter_block(const H5S_sel_iter_t *iter, hsize_t *start, hsize_t *end)
1065 {
1066 herr_t ret_value; /* return value */
1067
1068 FUNC_ENTER_NOAPI_NOINIT_NOINIT_NOERR
1069
1070 /* Check args */
1071 HDassert(iter);
1072 HDassert(start);
1073 HDassert(end);
1074
1075 /* Call iter_block routine for selection type */
1076 ret_value = (*iter->type->iter_block)(iter,start,end);
1077
1078 FUNC_LEAVE_NOAPI(ret_value)
1079 } /* H5S_select_iter_block() */
1080 #endif /* LATER */
1081
1082
1083 /*--------------------------------------------------------------------------
1084 NAME
1085 H5S_select_iter_nelmts
1086 PURPOSE
1087 Get the number of elements left to iterate over in selection
1088 USAGE
1089 hssize_t H5S_select_iter_nelmts(sel_iter)
1090 H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
1091 RETURNS
1092 The number of elements in selection on success, 0 on failure
1093 DESCRIPTION
1094 Returns the number of elements in current selection for dataspace.
1095 GLOBAL VARIABLES
1096 COMMENTS, BUGS, ASSUMPTIONS
1097 This routine participates in the "Inlining C function pointers"
1098 pattern, don't call it directly, use the appropriate macro
1099 defined in H5Sprivate.h.
1100 EXAMPLES
1101 REVISION LOG
1102 --------------------------------------------------------------------------*/
1103 hsize_t
H5S_select_iter_nelmts(const H5S_sel_iter_t * sel_iter)1104 H5S_select_iter_nelmts(const H5S_sel_iter_t *sel_iter)
1105 {
1106 hsize_t ret_value = 0; /* Return value */
1107
1108 FUNC_ENTER_NOAPI_NOINIT_NOERR
1109
1110 /* Check args */
1111 HDassert(sel_iter);
1112
1113 /* Call iter_nelmts routine for selection type */
1114 ret_value = (*sel_iter->type->iter_nelmts)(sel_iter);
1115
1116 FUNC_LEAVE_NOAPI(ret_value)
1117 } /* H5S_select_iter_nelmts() */
1118
1119 #ifdef LATER
1120
1121 /*--------------------------------------------------------------------------
1122 NAME
1123 H5S_select_iter_has_next_block
1124 PURPOSE
1125 Check if there is another block available in the selection iterator
1126 USAGE
1127 htri_t H5S_select_iter_has_next_block(sel_iter)
1128 const H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
1129 RETURNS
1130 Non-negative on success, negative on failure.
1131 DESCRIPTION
1132 Check if there is another block available to advance to in the selection
1133 iterator.
1134 GLOBAL VARIABLES
1135 COMMENTS, BUGS, ASSUMPTIONS
1136 This routine participates in the "Inlining C function pointers"
1137 pattern, don't call it directly, use the appropriate macro
1138 defined in H5Sprivate.h.
1139 EXAMPLES
1140 REVISION LOG
1141 --------------------------------------------------------------------------*/
1142 static htri_t
H5S_select_iter_has_next_block(const H5S_sel_iter_t * iter)1143 H5S_select_iter_has_next_block(const H5S_sel_iter_t *iter)
1144 {
1145 herr_t ret_value; /* return value */
1146
1147 FUNC_ENTER_NOAPI_NOINIT_NOINIT_NOERR
1148
1149 /* Check args */
1150 HDassert(iter);
1151
1152 /* Call iter_has_next_block routine for selection type */
1153 ret_value = (*iter->type->iter_has_next_block)(iter);
1154
1155 FUNC_LEAVE_NOAPI(ret_value)
1156 } /* H5S_select_iter_has_next_block() */
1157 #endif /* LATER */
1158
1159
1160 /*--------------------------------------------------------------------------
1161 NAME
1162 H5S_select_iter_next
1163 PURPOSE
1164 Advance selection iterator to next element
1165 USAGE
1166 herr_t H5S_select_iter_next(iter, nelem)
1167 H5S_sel_iter_t *iter; IN/OUT: Selection iterator to change
1168 size_t nelem; IN: Number of elements to advance by
1169 RETURNS
1170 Non-negative on success, negative on failure.
1171 DESCRIPTION
1172 Move the current element for the selection iterator to the NELEM'th next
1173 element in the selection.
1174 GLOBAL VARIABLES
1175 COMMENTS, BUGS, ASSUMPTIONS
1176 This routine participates in the "Inlining C function pointers"
1177 pattern, don't call it directly, use the appropriate macro
1178 defined in H5Sprivate.h.
1179 EXAMPLES
1180 REVISION LOG
1181 --------------------------------------------------------------------------*/
1182 herr_t
H5S_select_iter_next(H5S_sel_iter_t * iter,size_t nelem)1183 H5S_select_iter_next(H5S_sel_iter_t *iter, size_t nelem)
1184 {
1185 herr_t ret_value = FAIL; /* Return value */
1186
1187 FUNC_ENTER_NOAPI_NOINIT_NOERR
1188
1189 /* Check args */
1190 HDassert(iter);
1191 HDassert(nelem>0);
1192
1193 /* Call iter_next routine for selection type */
1194 ret_value = (*iter->type->iter_next)(iter,nelem);
1195
1196 /* Decrement the number of elements left in selection */
1197 iter->elmt_left-=nelem;
1198
1199 FUNC_LEAVE_NOAPI(ret_value)
1200 } /* H5S_select_iter_next() */
1201
1202 #ifdef LATER
1203
1204 /*--------------------------------------------------------------------------
1205 NAME
1206 H5S_select_iter_next_block
1207 PURPOSE
1208 Advance selection iterator to next block
1209 USAGE
1210 herr_t H5S_select_iter_next_block(iter)
1211 H5S_sel_iter_t *iter; IN/OUT: Selection iterator to change
1212 RETURNS
1213 Non-negative on success, negative on failure.
1214 DESCRIPTION
1215 Move the current element for the selection iterator to the next
1216 block in the selection.
1217 GLOBAL VARIABLES
1218 COMMENTS, BUGS, ASSUMPTIONS
1219 Doesn't maintain the 'elmt_left' field of the selection iterator.
1220
1221 This routine participates in the "Inlining C function pointers"
1222 pattern, don't call it directly, use the appropriate macro
1223 defined in H5Sprivate.h.
1224 EXAMPLES
1225 REVISION LOG
1226 --------------------------------------------------------------------------*/
1227 static herr_t
H5S_select_iter_next_block(H5S_sel_iter_t * iter)1228 H5S_select_iter_next_block(H5S_sel_iter_t *iter)
1229 {
1230 herr_t ret_value; /* return value */
1231
1232 FUNC_ENTER_NOAPI_NOINIT_NOERR
1233
1234 /* Check args */
1235 HDassert(iter);
1236
1237 /* Call iter_next_block routine for selection type */
1238 ret_value = (*iter->type->iter_next_block)(iter);
1239
1240 FUNC_LEAVE_NOAPI(ret_value)
1241 } /* H5S_select_iter_next_block() */
1242 #endif /* LATER */
1243
1244
1245 /*--------------------------------------------------------------------------
1246 NAME
1247 H5S_select_iter_release
1248 PURPOSE
1249 Release a selection iterator's resources.
1250 USAGE
1251 hssize_t H5S_select_iter_release(sel_iter)
1252 H5S_sel_iter_t *sel_iter; IN: Selection iterator to query
1253 RETURNS
1254 The number of elements in selection on success, 0 on failure
1255 DESCRIPTION
1256 Returns the number of elements in current selection for dataspace.
1257 GLOBAL VARIABLES
1258 COMMENTS, BUGS, ASSUMPTIONS
1259 This routine participates in the "Inlining C function pointers"
1260 pattern, don't call it directly, use the appropriate macro
1261 defined in H5Sprivate.h.
1262 EXAMPLES
1263 REVISION LOG
1264 --------------------------------------------------------------------------*/
1265 herr_t
H5S_select_iter_release(H5S_sel_iter_t * sel_iter)1266 H5S_select_iter_release(H5S_sel_iter_t *sel_iter)
1267 {
1268 herr_t ret_value = FAIL; /* Return value */
1269
1270 FUNC_ENTER_NOAPI_NOINIT_NOERR
1271
1272 /* Check args */
1273 HDassert(sel_iter);
1274
1275 /* Call selection type-specific release routine */
1276 ret_value = (*sel_iter->type->iter_release)(sel_iter);
1277
1278 FUNC_LEAVE_NOAPI(ret_value)
1279 } /* H5S_select_iter_release() */
1280
1281
1282 /*--------------------------------------------------------------------------
1283 NAME
1284 H5S_select_iterate
1285 PURPOSE
1286 Iterate over the selected elements in a memory buffer.
1287 USAGE
1288 herr_t H5S_select_iterate(buf, type, space, operator, operator_data)
1289 void *buf; IN/OUT: Buffer containing elements to iterate over
1290 H5T_t *type; IN: Datatype of BUF array.
1291 H5S_t *space; IN: Dataspace object containing selection to iterate over
1292 H5D_operator_t op; IN: Function pointer to the routine to be
1293 called for each element in BUF iterated over.
1294 void *operator_data; IN/OUT: Pointer to any user-defined data
1295 associated with the operation.
1296 RETURNS
1297 Returns the return value of the last operator if it was non-zero, or zero
1298 if all elements were processed. Otherwise returns a negative value.
1299 DESCRIPTION
1300 Iterates over the selected elements in a memory buffer, calling the user's
1301 callback function for each element. The selection in the dataspace is
1302 modified so that any elements already iterated over are removed from the
1303 selection if the iteration is interrupted (by the H5D_operator_t function
1304 returning non-zero) in the "middle" of the iteration and may be re-started
1305 by the user where it left off.
1306
1307 NOTE: Until "subtracting" elements from a selection is implemented,
1308 the selection is not modified.
1309 --------------------------------------------------------------------------*/
1310 herr_t
H5S_select_iterate(void * buf,const H5T_t * type,const H5S_t * space,const H5S_sel_iter_op_t * op,void * op_data)1311 H5S_select_iterate(void *buf, const H5T_t *type, const H5S_t *space,
1312 const H5S_sel_iter_op_t *op, void *op_data)
1313 {
1314 H5S_sel_iter_t *iter = NULL; /* Selection iteration info */
1315 hbool_t iter_init = FALSE; /* Selection iteration info has been initialized */
1316 hsize_t *off = NULL; /* Array to store sequence offsets */
1317 size_t *len = NULL; /* Array to store sequence lengths */
1318 hssize_t nelmts; /* Number of elements in selection */
1319 hsize_t space_size[H5O_LAYOUT_NDIMS]; /* Dataspace size */
1320 size_t max_elem; /* Maximum number of elements allowed in sequences */
1321 size_t elmt_size; /* Datatype size */
1322 unsigned ndims; /* Number of dimensions in dataspace */
1323 herr_t user_ret = 0; /* User's return value */
1324 herr_t ret_value = SUCCEED; /* Return value */
1325
1326 FUNC_ENTER_NOAPI(FAIL)
1327
1328 /* Check args */
1329 HDassert(buf);
1330 HDassert(type);
1331 HDassert(space);
1332 HDassert(op);
1333
1334 /* Get the datatype size */
1335 if(0 == (elmt_size = H5T_get_size(type)))
1336 HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid")
1337
1338 /* Allocate the selection iterator */
1339 if(NULL == (iter = H5FL_MALLOC(H5S_sel_iter_t)))
1340 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator")
1341
1342 /* Initialize iterator */
1343 if(H5S_select_iter_init(iter, space, elmt_size) < 0)
1344 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
1345 iter_init = TRUE; /* Selection iteration info has been initialized */
1346
1347 /* Get the number of elements in selection */
1348 if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0)
1349 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected")
1350
1351 /* Get the rank of the dataspace */
1352 ndims = space->extent.rank;
1353
1354 if(ndims > 0) {
1355 /* Copy the size of the space */
1356 HDassert(space->extent.size);
1357 HDmemcpy(space_size, space->extent.size, ndims * sizeof(hsize_t));
1358 } /* end if */
1359 space_size[ndims] = elmt_size;
1360
1361 /* Compute the maximum number of bytes required */
1362 H5_CHECKED_ASSIGN(max_elem, size_t, nelmts, hssize_t);
1363
1364 /* Allocate the offset & length arrays */
1365 if(NULL == (len = H5FL_SEQ_MALLOC(size_t, H5D_IO_VECTOR_SIZE)))
1366 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate length vector array")
1367 if(NULL == (off = H5FL_SEQ_MALLOC(hsize_t, H5D_IO_VECTOR_SIZE)))
1368 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate offset vector array")
1369
1370 /* Loop, while elements left in selection */
1371 while(max_elem > 0 && user_ret == 0) {
1372 size_t nelem; /* Number of elements used in sequences */
1373 size_t nseq; /* Number of sequences generated */
1374 size_t curr_seq; /* Current sequence being worked on */
1375
1376 /* Get the sequences of bytes */
1377 if(H5S_SELECT_GET_SEQ_LIST(space, 0, iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0)
1378 HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
1379
1380 /* Loop, while sequences left to process */
1381 for(curr_seq = 0; curr_seq < nseq && user_ret == 0; curr_seq++) {
1382 hsize_t curr_off; /* Current offset within sequence */
1383 size_t curr_len; /* Length of bytes left to process in sequence */
1384
1385 /* Get the current offset */
1386 curr_off = off[curr_seq];
1387
1388 /* Get the number of bytes in sequence */
1389 curr_len = len[curr_seq];
1390
1391 /* Loop, while bytes left in sequence */
1392 while(curr_len > 0 && user_ret == 0) {
1393 hsize_t coords[H5O_LAYOUT_NDIMS]; /* Coordinates of element in dataspace */
1394 hsize_t tmp_off; /* Temporary offset within sequence */
1395 uint8_t *loc; /* Current element location in buffer */
1396 int i; /* Local Index variable */
1397
1398 /* Compute the coordinate from the offset */
1399 for(i = (int)ndims, tmp_off = curr_off; i >= 0; i--) {
1400 coords[i] = tmp_off % space_size[i];
1401 tmp_off /= space_size[i];
1402 } /* end for */
1403
1404 /* Get the location within the user's buffer */
1405 loc = (unsigned char *)buf + curr_off;
1406
1407 /* Check which type of callback to make */
1408 switch(op->op_type) {
1409 case H5S_SEL_ITER_OP_APP:
1410 /* Make the application callback */
1411 user_ret = (op->u.app_op.op)(loc, op->u.app_op.type_id, ndims, coords, op_data);
1412 break;
1413 case H5S_SEL_ITER_OP_LIB:
1414 /* Call the library's callback */
1415 user_ret = (op->u.lib_op)(loc, type, ndims, coords, op_data);
1416 break;
1417 default:
1418 HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported op type")
1419 } /* end switch */
1420
1421 /* Increment offset in dataspace */
1422 curr_off += elmt_size;
1423
1424 /* Decrement number of bytes left in sequence */
1425 curr_len -= elmt_size;
1426 } /* end while */
1427 } /* end for */
1428
1429 /* Decrement number of elements left to process */
1430 max_elem -= nelem;
1431 } /* end while */
1432
1433 /* Set return value */
1434 ret_value = user_ret;
1435
1436 done:
1437 /* Release resources, if allocated */
1438 if(len)
1439 len = H5FL_SEQ_FREE(size_t, len);
1440 if(off)
1441 off = H5FL_SEQ_FREE(hsize_t, off);
1442
1443 /* Release selection iterator */
1444 if(iter_init && H5S_SELECT_ITER_RELEASE(iter) < 0)
1445 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
1446 if(iter)
1447 iter = H5FL_FREE(H5S_sel_iter_t, iter);
1448
1449 FUNC_LEAVE_NOAPI(ret_value)
1450 } /* end H5S_select_iterate() */
1451
1452
1453 /*--------------------------------------------------------------------------
1454 NAME
1455 H5Sget_select_type
1456 PURPOSE
1457 Retrieve the type of selection in a dataspace
1458 USAGE
1459 H5S_sel_type H5Sget_select_type(space_id)
1460 hid_t space_id; IN: Dataspace object to query
1461 RETURNS
1462 Non-negative on success/Negative on failure. Return value is from the
1463 set of values in the H5S_sel_type enumerated type.
1464 DESCRIPTION
1465 This function retrieves the type of selection currently defined for
1466 a dataspace.
1467 --------------------------------------------------------------------------*/
1468 H5S_sel_type
H5Sget_select_type(hid_t space_id)1469 H5Sget_select_type(hid_t space_id)
1470 {
1471 H5S_t *space; /* dataspace to modify */
1472 H5S_sel_type ret_value; /* Return value */
1473
1474 FUNC_ENTER_API(H5S_SEL_ERROR)
1475 H5TRACE1("St", "i", space_id);
1476
1477 /* Check args */
1478 if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
1479 HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, H5S_SEL_ERROR, "not a dataspace")
1480
1481 /* Set return value */
1482 ret_value = H5S_GET_SELECT_TYPE(space);
1483
1484 done:
1485 FUNC_LEAVE_API(ret_value)
1486 } /* end H5Sget_select_type() */
1487
1488
1489 /*--------------------------------------------------------------------------
1490 NAME
1491 H5S_get_select_type
1492 PURPOSE
1493 Retrieve the type of selection in a dataspace
1494 USAGE
1495 H5S_sel_type H5Sget_select_type(space)
1496 const H5S_t *space; IN: Dataspace object to query
1497 RETURNS
1498 Non-negative on success/Negative on failure. Return value is from the
1499 set of values in the H5S_sel_type enumerated type.
1500 DESCRIPTION
1501 This function retrieves the type of selection currently defined for
1502 a dataspace.
1503 COMMENTS
1504 This routine participates in the "Inlining C function pointers"
1505 pattern, don't call it directly, use the appropriate macro
1506 defined in H5Sprivate.h.
1507 --------------------------------------------------------------------------*/
1508 H5S_sel_type
H5S_get_select_type(const H5S_t * space)1509 H5S_get_select_type(const H5S_t *space)
1510 {
1511 H5S_sel_type ret_value = H5S_SEL_ERROR; /* Return value */
1512
1513 FUNC_ENTER_NOAPI_NOINIT_NOERR
1514
1515 /* Check args */
1516 HDassert(space);
1517
1518 /* Set return value */
1519 ret_value=H5S_GET_SELECT_TYPE(space);
1520
1521 FUNC_LEAVE_NOAPI(ret_value)
1522 } /* end H5S_get_select_type() */
1523
1524
1525 /*--------------------------------------------------------------------------
1526 NAME
1527 H5S_select_shape_same
1528 PURPOSE
1529 Check if two selections are the same shape
1530 USAGE
1531 htri_t H5S_select_shape_same(space1, space2)
1532 const H5S_t *space1; IN: 1st Dataspace pointer to compare
1533 const H5S_t *space2; IN: 2nd Dataspace pointer to compare
1534 RETURNS
1535 TRUE/FALSE/FAIL
1536 DESCRIPTION
1537 Checks to see if the current selection in the dataspaces are the same
1538 dimensionality and shape.
1539 This is primarily used for reading the entire selection in one swoop.
1540 GLOBAL VARIABLES
1541 COMMENTS, BUGS, ASSUMPTIONS
1542 Assumes that there is only a single "block" for hyperslab selections.
1543 EXAMPLES
1544 REVISION LOG
1545 Modified function to view identical shapes with different dimensions
1546 as being the same under some circumstances.
1547 --------------------------------------------------------------------------*/
1548 htri_t
H5S_select_shape_same(const H5S_t * space1,const H5S_t * space2)1549 H5S_select_shape_same(const H5S_t *space1, const H5S_t *space2)
1550 {
1551 H5S_sel_iter_t *iter_a = NULL; /* Selection a iteration info */
1552 H5S_sel_iter_t *iter_b = NULL; /* Selection b iteration info */
1553 hbool_t iter_a_init = FALSE; /* Selection a iteration info has been initialized */
1554 hbool_t iter_b_init = FALSE; /* Selection b iteration info has been initialized */
1555 htri_t ret_value = TRUE; /* Return value */
1556
1557 FUNC_ENTER_NOAPI(FAIL)
1558
1559 /* Check args */
1560 HDassert(space1);
1561 HDassert(space2);
1562
1563 /* Check for different number of elements selected */
1564 if(H5S_GET_SELECT_NPOINTS(space1) != H5S_GET_SELECT_NPOINTS(space2))
1565 HGOTO_DONE(FALSE)
1566
1567 /* Check special cases if both dataspaces aren't scalar */
1568 /* (If only one is, the number of selected points check is sufficient) */
1569 if(space1->extent.rank > 0 && space2->extent.rank > 0) {
1570 const H5S_t *space_a; /* Dataspace with larger rank */
1571 const H5S_t *space_b; /* Dataspace with smaller rank */
1572 unsigned space_a_rank; /* Number of dimensions of dataspace A */
1573 unsigned space_b_rank; /* Number of dimensions of dataspace B */
1574
1575 /* need to be able to handle spaces of different rank:
1576 *
1577 * To simplify logic, let space_a point to the element of the set
1578 * {space1, space2} with the largest rank or space1 if the ranks
1579 * are identical.
1580 *
1581 * Similarly, let space_b point to the element of {space1, space2}
1582 * with the smallest rank, or space2 if they are identical.
1583 *
1584 * Let: space_a_rank be the rank of space_a,
1585 * space_b_rank be the rank of space_b,
1586 * delta_rank = space_a_rank - space_b_rank.
1587 *
1588 * Set all this up below.
1589 */
1590 if(space1->extent.rank >= space2->extent.rank) {
1591 space_a = space1;
1592 space_a_rank = space_a->extent.rank;
1593
1594 space_b = space2;
1595 space_b_rank = space_b->extent.rank;
1596 } /* end if */
1597 else {
1598 space_a = space2;
1599 space_a_rank = space_a->extent.rank;
1600
1601 space_b = space1;
1602 space_b_rank = space_b->extent.rank;
1603 } /* end else */
1604 HDassert(space_a_rank >= space_b_rank);
1605 HDassert(space_b_rank > 0);
1606
1607 /* Check for different number of elements selected */
1608 if(H5S_GET_SELECT_NPOINTS(space_a) != H5S_GET_SELECT_NPOINTS(space_b))
1609 HGOTO_DONE(FALSE)
1610
1611 /* Check for "easy" cases before getting into generalized block iteration code */
1612 if((H5S_GET_SELECT_TYPE(space_a) == H5S_SEL_ALL) && (H5S_GET_SELECT_TYPE(space_b) == H5S_SEL_ALL)) {
1613 hsize_t dims1[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #1 */
1614 hsize_t dims2[H5O_LAYOUT_NDIMS]; /* End point of selection block in dataspace #2 */
1615 int space_a_dim; /* Current dimension in dataspace A */
1616 int space_b_dim; /* Current dimension in dataspace B */
1617
1618 if(H5S_get_simple_extent_dims(space_a, dims1, NULL) < 0)
1619 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality")
1620 if(H5S_get_simple_extent_dims(space_b, dims2, NULL) < 0)
1621 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality")
1622
1623 space_a_dim = (int)space_a_rank - 1;
1624 space_b_dim = (int)space_b_rank - 1;
1625
1626 /* recall that space_a_rank >= space_b_rank.
1627 *
1628 * In the following while loop, we test to see if space_a and space_b
1629 * have identical size in all dimensions they have in common.
1630 */
1631 while(space_b_dim >= 0) {
1632 if(dims1[space_a_dim] != dims2[space_b_dim])
1633 HGOTO_DONE(FALSE)
1634
1635 space_a_dim--;
1636 space_b_dim--;
1637 } /* end while */
1638
1639 /* Since we are selecting the entire space, we must also verify that space_a
1640 * has size 1 in all dimensions that it does not share with space_b.
1641 */
1642 while(space_a_dim >= 0) {
1643 if(dims1[space_a_dim] != 1)
1644 HGOTO_DONE(FALSE)
1645
1646 space_a_dim--;
1647 } /* end while */
1648 } /* end if */
1649 else if((H5S_GET_SELECT_TYPE(space1) == H5S_SEL_NONE) || (H5S_GET_SELECT_TYPE(space2) == H5S_SEL_NONE)) {
1650 /* (Both must be, at this point, if one is) */
1651 HGOTO_DONE(TRUE)
1652 } /* end if */
1653 else if((H5S_GET_SELECT_TYPE(space_a) == H5S_SEL_HYPERSLABS && space_a->select.sel_info.hslab->diminfo_valid)
1654 && (H5S_GET_SELECT_TYPE(space_b) == H5S_SEL_HYPERSLABS && space_b->select.sel_info.hslab->diminfo_valid)) {
1655 int space_a_dim; /* Current dimension in dataspace A */
1656 int space_b_dim; /* Current dimension in dataspace B */
1657
1658 space_a_dim = (int)space_a_rank - 1;
1659 space_b_dim = (int)space_b_rank - 1;
1660
1661 /* check that the shapes are the same in the common dimensions, and that
1662 * block == 1 in all dimensions that appear only in space_a.
1663 */
1664 while(space_b_dim >= 0) {
1665 if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].stride !=
1666 space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].stride)
1667 HGOTO_DONE(FALSE)
1668
1669 if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].count !=
1670 space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].count)
1671 HGOTO_DONE(FALSE)
1672
1673 if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].block !=
1674 space_b->select.sel_info.hslab->opt_diminfo[space_b_dim].block)
1675 HGOTO_DONE(FALSE)
1676
1677 space_a_dim--;
1678 space_b_dim--;
1679 } /* end while */
1680
1681 while(space_a_dim >= 0) {
1682 if(space_a->select.sel_info.hslab->opt_diminfo[space_a_dim].block != 1)
1683 HGOTO_DONE(FALSE)
1684
1685 space_a_dim--;
1686 } /* end while */
1687 } /* end if */
1688 /* Iterate through all the blocks in the selection */
1689 else {
1690 hsize_t start_a[H5S_MAX_RANK]; /* Start point of selection block in dataspace a */
1691 hsize_t start_b[H5S_MAX_RANK]; /* Start point of selection block in dataspace b */
1692 hsize_t end_a[H5S_MAX_RANK]; /* End point of selection block in dataspace a */
1693 hsize_t end_b[H5S_MAX_RANK]; /* End point of selection block in dataspace b */
1694 hsize_t off_a[H5S_MAX_RANK]; /* Offset of selection a blocks */
1695 hsize_t off_b[H5S_MAX_RANK]; /* Offset of selection b blocks */
1696 hbool_t first_block = TRUE; /* Flag to indicate the first block */
1697
1698 /* Allocate the selection iterators */
1699 if(NULL == (iter_a = H5FL_MALLOC(H5S_sel_iter_t)))
1700 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator")
1701 if(NULL == (iter_b = H5FL_MALLOC(H5S_sel_iter_t)))
1702 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator")
1703
1704 /* Initialize iterator for each dataspace selection
1705 * Use '0' for element size instead of actual element size to indicate
1706 * that the selection iterator shouldn't be "flattened", since we
1707 * aren't actually going to be doing I/O with the iterators.
1708 */
1709 if(H5S_select_iter_init(iter_a, space_a, (size_t)0) < 0)
1710 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator a")
1711 iter_a_init = TRUE;
1712 if(H5S_select_iter_init(iter_b, space_b, (size_t)0) < 0)
1713 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator b")
1714 iter_b_init = TRUE;
1715
1716 /* Iterate over all the blocks in each selection */
1717 while(1) {
1718 int space_a_dim; /* Current dimension in dataspace A */
1719 int space_b_dim; /* Current dimension in dataspace B */
1720 htri_t status_a, status_b; /* Status from next block checks */
1721
1722 /* Get the current block for each selection iterator */
1723 if(H5S_SELECT_ITER_BLOCK(iter_a, start_a, end_a) < 0)
1724 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator block a")
1725 if(H5S_SELECT_ITER_BLOCK(iter_b, start_b, end_b) < 0)
1726 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator block b")
1727
1728 space_a_dim = (int)space_a_rank - 1;
1729 space_b_dim = (int)space_b_rank - 1;
1730
1731 /* The first block only compares the sizes and sets the
1732 * relative offsets for later blocks
1733 */
1734 if(first_block) {
1735 /* If the block sizes in the common dimensions from
1736 * each selection don't match, get out
1737 */
1738 while(space_b_dim >= 0) {
1739 if((end_a[space_a_dim] - start_a[space_a_dim]) !=
1740 (end_b[space_b_dim] - start_b[space_b_dim]))
1741 HGOTO_DONE(FALSE)
1742
1743 /* Set the relative locations of the selections */
1744 off_a[space_a_dim] = start_a[space_a_dim];
1745 off_b[space_b_dim] = start_b[space_b_dim];
1746
1747 space_a_dim--;
1748 space_b_dim--;
1749 } /* end while */
1750
1751 /* similarly, if the block size in any dimension that appears only
1752 * in space_a is not equal to 1, get out.
1753 */
1754 while(space_a_dim >= 0) {
1755 if((end_a[space_a_dim] - start_a[space_a_dim]) != 0)
1756 HGOTO_DONE(FALSE)
1757
1758 /* Set the relative locations of the selections */
1759 off_a[space_a_dim] = start_a[space_a_dim];
1760
1761 space_a_dim--;
1762 } /* end while */
1763
1764 /* Reset "first block" flag */
1765 first_block = FALSE;
1766 } /* end if */
1767 /* Check over the blocks for each selection */
1768 else {
1769 /* for dimensions that space_a and space_b have in common: */
1770 while(space_b_dim >= 0) {
1771 /* Check if the blocks are in the same relative location */
1772 if((start_a[space_a_dim] - off_a[space_a_dim]) !=
1773 (start_b[space_b_dim] - off_b[space_b_dim]))
1774 HGOTO_DONE(FALSE)
1775
1776 /* If the block sizes from each selection doesn't match, get out */
1777 if((end_a[space_a_dim] - start_a[space_a_dim]) !=
1778 (end_b[space_b_dim] - start_b[space_b_dim]))
1779 HGOTO_DONE(FALSE)
1780
1781 space_a_dim--;
1782 space_b_dim--;
1783 } /* end while */
1784
1785 /* For dimensions that appear only in space_a: */
1786 while(space_a_dim >= 0) {
1787 /* If the block size isn't 1, get out */
1788 if((end_a[space_a_dim] - start_a[space_a_dim]) != 0)
1789 HGOTO_DONE(FALSE)
1790
1791 space_a_dim--;
1792 } /* end while */
1793 } /* end else */
1794
1795 /* Check if we are able to advance to the next selection block */
1796 if((status_a = H5S_SELECT_ITER_HAS_NEXT_BLOCK(iter_a)) < 0)
1797 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block a")
1798
1799 if((status_b = H5S_SELECT_ITER_HAS_NEXT_BLOCK(iter_b)) < 0)
1800 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block b")
1801
1802 /* Did we run out of blocks at the same time? */
1803 if((status_a == FALSE) && (status_b == FALSE))
1804 break;
1805 else if(status_a != status_b)
1806 HGOTO_DONE(FALSE)
1807 else {
1808 /* Advance to next block in selection iterators */
1809 if(H5S_SELECT_ITER_NEXT_BLOCK(iter_a) < 0)
1810 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to advance to next iterator block a")
1811
1812 if(H5S_SELECT_ITER_NEXT_BLOCK(iter_b) < 0)
1813 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to advance to next iterator block b")
1814 } /* end else */
1815 } /* end while */
1816 } /* end else */
1817 } /* end if */
1818
1819 done:
1820 if(iter_a_init && H5S_SELECT_ITER_RELEASE(iter_a) < 0)
1821 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator a")
1822 if(iter_a)
1823 iter_a = H5FL_FREE(H5S_sel_iter_t, iter_a);
1824 if(iter_b_init && H5S_SELECT_ITER_RELEASE(iter_b) < 0)
1825 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator b")
1826 if(iter_b)
1827 iter_b = H5FL_FREE(H5S_sel_iter_t, iter_b);
1828
1829 FUNC_LEAVE_NOAPI(ret_value)
1830 } /* H5S_select_shape_same() */
1831
1832
1833 /*--------------------------------------------------------------------------
1834 NAME
1835 H5S_select_construct_projection
1836
1837 PURPOSE
1838 Given a dataspace a of rank n with some selection, construct a new
1839 dataspace b of rank m (m != n), with the selection in a being
1840 topologically identical to that in b (as verified by
1841 H5S_select_shape_same().
1842
1843 This function exists, as some I/O code chokes on topologically
1844 identical selections with different ranks. At least to begin
1845 with, we will deal with the issue by constructing projections
1846 of the memory dataspace with ranks equaling those of the file
1847 dataspace.
1848
1849 Note that if m > n, it is possible that the starting point in the
1850 buffer associated with the memory dataspace will have to be
1851 adjusted to match the projected dataspace. If the buf parameter
1852 is not NULL, the function must return an adjusted buffer base
1853 address in *adj_buf_ptr.
1854
1855 USAGE
1856 htri_t H5S_select_construct_projection(base_space,
1857 new_space_ptr,
1858 new_space_rank,
1859 buf,
1860 adj_buf_ptr)
1861 const H5S_t *base_space; IN: Ptr to Dataspace to project
1862 H5S_t ** new_space_ptr; OUT: Ptr to location in which to return
1863 the address of the projected space
1864 int new_space_rank; IN: Rank of the projected space.
1865 const void * buf; IN: Base address of the buffer
1866 associated with the base space.
1867 May be NULL.
1868 void ** adj_buf_ptr; OUT: If buf != NULL, store the base
1869 address of the section of buf
1870 that is described by *new_space_ptr
1871 in *adj_buf_ptr.
1872
1873 RETURNS
1874 Non-negative on success/Negative on failure.
1875
1876 DESCRIPTION
1877 Construct a new dataspace and associated selection which is a
1878 projection of the supplied dataspace and associated selection into
1879 the specified rank. Return it in *new_space_ptr.
1880
1881 If buf is supplied, computes the base address of the projected
1882 selection in buf, and stores the base address in *adj_buf_ptr.
1883
1884 GLOBAL VARIABLES
1885 COMMENTS, BUGS, ASSUMPTIONS
1886 The selection in the supplied base_space has thickness 1 in all
1887 dimensions greater than new_space_rank. Note that here we count
1888 dimensions from the fastest changing coordinate to the slowest
1889 changing changing coordinate.
1890 EXAMPLES
1891 REVISION LOG
1892 --------------------------------------------------------------------------*/
1893 herr_t
H5S_select_construct_projection(const H5S_t * base_space,H5S_t ** new_space_ptr,unsigned new_space_rank,const void * buf,void const ** adj_buf_ptr,hsize_t element_size)1894 H5S_select_construct_projection(const H5S_t *base_space, H5S_t **new_space_ptr,
1895 unsigned new_space_rank, const void *buf, void const **adj_buf_ptr, hsize_t element_size)
1896 {
1897 H5S_t * new_space = NULL; /* New dataspace constructed */
1898 hsize_t base_space_dims[H5S_MAX_RANK]; /* Current dimensions of base dataspace */
1899 hsize_t base_space_maxdims[H5S_MAX_RANK]; /* Maximum dimensions of base dataspace */
1900 int sbase_space_rank; /* Signed # of dimensions of base dataspace */
1901 unsigned base_space_rank; /* # of dimensions of base dataspace */
1902 hsize_t projected_space_element_offset = 0; /* Offset of selected element in projected buffer */
1903 herr_t ret_value = SUCCEED; /* Return value */
1904
1905 FUNC_ENTER_NOAPI(FAIL)
1906
1907 /* Sanity checks */
1908 HDassert(base_space != NULL);
1909 HDassert((H5S_GET_EXTENT_TYPE(base_space) == H5S_SCALAR) || (H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE));
1910 HDassert(new_space_ptr != NULL);
1911 HDassert((new_space_rank != 0) || (H5S_GET_SELECT_NPOINTS(base_space) <= 1));
1912 HDassert(new_space_rank <= H5S_MAX_RANK);
1913 HDassert((buf == NULL) || (adj_buf_ptr != NULL));
1914 HDassert(element_size > 0 );
1915
1916 /* Get the extent info for the base dataspace */
1917 if((sbase_space_rank = H5S_get_simple_extent_dims(base_space, base_space_dims, base_space_maxdims)) < 0)
1918 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality of base space")
1919 base_space_rank = (unsigned)sbase_space_rank;
1920 HDassert(base_space_rank != new_space_rank);
1921
1922 /* Check if projected space is scalar */
1923 if(new_space_rank == 0) {
1924 hssize_t npoints; /* Number of points selected */
1925
1926 /* Retreve the number of elements selected */
1927 if((npoints = (hssize_t)H5S_GET_SELECT_NPOINTS(base_space)) < 0)
1928 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get number of points selected")
1929 HDassert(npoints <= 1);
1930
1931 /* Create new scalar dataspace */
1932 if(NULL == (new_space = H5S_create(H5S_SCALAR)))
1933 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create scalar dataspace")
1934
1935 /* No need to register the dataspace(i.e. get an ID) as
1936 * we will just be discarding it shortly.
1937 */
1938
1939 /* Selection for the new space will be either all or
1940 * none, depending on whether the base space has 0 or
1941 * 1 elements selected.
1942 *
1943 * Observe that the base space can't have more than
1944 * one selected element, since its selection has the
1945 * same shape as the file dataspace, and that data
1946 * space is scalar.
1947 */
1948 if(1 == npoints) {
1949 /* Assuming that the selection in the base dataspace is not
1950 * empty, we must compute the offset of the selected item in
1951 * the buffer associated with the base dataspace.
1952 *
1953 * Since the new space rank is zero, we know that the
1954 * the base space must have rank at least 1 -- and
1955 * hence it is a simple dataspace. However, the
1956 * selection, may be either point, hyperspace, or all.
1957 *
1958 */
1959 if(H5S_SELECT_PROJECT_SCALAR(base_space, &projected_space_element_offset) < 0)
1960 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to project scalar selection")
1961 } /* end if */
1962 else {
1963 HDassert(0 == npoints);
1964
1965 if(H5S_select_none(new_space) < 0)
1966 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't delete default selection")
1967 } /* end else */
1968 } /* end if */
1969 else { /* projected space must be simple */
1970 hsize_t new_space_dims[H5S_MAX_RANK]; /* Current dimensions for new dataspace */
1971 hsize_t new_space_maxdims[H5S_MAX_RANK];/* Maximum dimensions for new dataspace */
1972 unsigned rank_diff; /* Difference in ranks */
1973
1974 /* Set up the dimensions of the new, projected dataspace.
1975 *
1976 * How we do this depends on whether we are projecting up into
1977 * increased dimensions, or down into a reduced number of
1978 * dimensions.
1979 *
1980 * If we are projecting up (the first half of the following
1981 * if statement), we copy the dimensions of the base data
1982 * space into the fastest changing dimensions of the new
1983 * projected dataspace, and set the remaining dimensions to
1984 * one.
1985 *
1986 * If we are projecting down (the second half of the following
1987 * if statement), we just copy the dimensions with the most
1988 * quickly changing dimensions into the dims for the projected
1989 * data set.
1990 *
1991 * This works, because H5S_select_shape_same() will return
1992 * true on selections of different rank iff:
1993 *
1994 * 1) the selection in the lower rank dataspace matches that
1995 * in the dimensions with the fastest changing indicies in
1996 * the larger rank dataspace, and
1997 *
1998 * 2) the selection has thickness 1 in all ranks that appear
1999 * only in the higher rank dataspace (i.e. those with
2000 * more slowly changing indicies).
2001 */
2002 if(new_space_rank > base_space_rank) {
2003 hsize_t tmp_dim_size = 1; /* Temporary dimension value, for filling arrays */
2004
2005 /* we must copy the dimensions of the base space into
2006 * the fastest changing dimensions of the new space,
2007 * and set the remaining dimensions to 1
2008 */
2009 rank_diff = new_space_rank - base_space_rank;
2010 H5VM_array_fill(new_space_dims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff);
2011 H5VM_array_fill(new_space_maxdims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff);
2012 HDmemcpy(&new_space_dims[rank_diff], base_space_dims, sizeof(new_space_dims[0]) * base_space_rank);
2013 HDmemcpy(&new_space_maxdims[rank_diff], base_space_maxdims, sizeof(new_space_maxdims[0]) * base_space_rank);
2014 } /* end if */
2015 else { /* new_space_rank < base_space_rank */
2016 /* we must copy the fastest changing dimension of the
2017 * base space into the dimensions of the new space.
2018 */
2019 rank_diff = base_space_rank - new_space_rank;
2020 HDmemcpy(new_space_dims, &base_space_dims[rank_diff], sizeof(new_space_dims[0]) * new_space_rank);
2021 HDmemcpy(new_space_maxdims, &base_space_maxdims[rank_diff], sizeof(new_space_maxdims[0]) * new_space_rank);
2022 } /* end else */
2023
2024 /* now have the new space rank and dimensions set up --
2025 * so we can create the new simple dataspace.
2026 */
2027 if(NULL == (new_space = H5S_create_simple(new_space_rank, new_space_dims, new_space_maxdims)))
2028 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace")
2029
2030 /* No need to register the dataspace(i.e. get an ID) as
2031 * we will just be discarding it shortly.
2032 */
2033
2034 /* If we get this far, we have successfully created the projected
2035 * dataspace. We must now project the selection in the base
2036 * dataspace into the projected dataspace.
2037 */
2038 if(H5S_SELECT_PROJECT_SIMPLE(base_space, new_space, &projected_space_element_offset) < 0)
2039 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to project simple selection")
2040
2041 /* If we get this far, we have created the new dataspace, and projected
2042 * the selection in the base dataspace into the new dataspace.
2043 *
2044 * If the base dataspace is simple, check to see if the
2045 * offset_changed flag on the base selection has been set -- if so,
2046 * project the offset into the new dataspace and set the
2047 * offset_changed flag.
2048 */
2049 if(H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE && base_space->select.offset_changed) {
2050 if(new_space_rank > base_space_rank) {
2051 HDmemset(new_space->select.offset, 0, sizeof(new_space->select.offset[0]) * rank_diff);
2052 HDmemcpy(&new_space->select.offset[rank_diff], base_space->select.offset, sizeof(new_space->select.offset[0]) * base_space_rank);
2053 } /* end if */
2054 else
2055 HDmemcpy(new_space->select.offset, &base_space->select.offset[rank_diff], sizeof(new_space->select.offset[0]) * new_space_rank);
2056
2057 /* Propagate the offset changed flag into the new dataspace. */
2058 new_space->select.offset_changed = TRUE;
2059 } /* end if */
2060 } /* end else */
2061
2062 /* If we have done the projection correctly, the following assertion
2063 * should hold.
2064 */
2065 HDassert(TRUE == H5S_select_shape_same(base_space, new_space));
2066
2067 /* load the address of the new space into *new_space_ptr */
2068 *new_space_ptr = new_space;
2069
2070 /* now adjust the buffer if required */
2071 if(buf != NULL) {
2072 if(new_space_rank < base_space_rank) {
2073 /* a bit of pointer magic here:
2074 *
2075 * Since we can't do pointer arithmetic on void pointers, we first
2076 * cast buf to a pointer to byte -- i.e. uint8_t.
2077 *
2078 * We then multiply the projected space element offset we
2079 * calculated earlier by the supplied element size, add this
2080 * value to the type cast buf pointer, cast the result back
2081 * to a pointer to void, and assign the result to *adj_buf_ptr.
2082 */
2083 *adj_buf_ptr = (const void *)(((const uint8_t *)buf) +
2084 ((size_t)(projected_space_element_offset * element_size)));
2085 } /* end if */
2086 else
2087 /* No adjustment necessary */
2088 *adj_buf_ptr = buf;
2089 } /* end if */
2090
2091 done:
2092 /* Cleanup on error */
2093 if(ret_value < 0)
2094 if(new_space && H5S_close(new_space) < 0)
2095 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
2096
2097 FUNC_LEAVE_NOAPI(ret_value)
2098 } /* H5S_select_construct_projection() */
2099
2100
2101 /*--------------------------------------------------------------------------
2102 NAME
2103 H5S_select_fill
2104 PURPOSE
2105 Fill a selection in memory with a value
2106 USAGE
2107 herr_t H5S_select_fill(fill,fill_size,space,buf)
2108 const void *fill; IN: Pointer to fill value to use
2109 size_t fill_size; IN: Size of elements in memory buffer & size of
2110 fill value
2111 H5S_t *space; IN: Dataspace describing memory buffer &
2112 containing selection to use.
2113 void *buf; IN/OUT: Memory buffer to fill selection in
2114 RETURNS
2115 Non-negative on success/Negative on failure.
2116 DESCRIPTION
2117 Use the selection in the dataspace to fill elements in a memory buffer.
2118 GLOBAL VARIABLES
2119 COMMENTS, BUGS, ASSUMPTIONS
2120 The memory buffer elements are assumed to have the same datatype as the
2121 fill value being placed into them.
2122 EXAMPLES
2123 REVISION LOG
2124 --------------------------------------------------------------------------*/
2125 herr_t
H5S_select_fill(const void * fill,size_t fill_size,const H5S_t * space,void * _buf)2126 H5S_select_fill(const void *fill, size_t fill_size, const H5S_t *space, void *_buf)
2127 {
2128 H5S_sel_iter_t *iter = NULL; /* Selection iteration info */
2129 hbool_t iter_init = 0; /* Selection iteration info has been initialized */
2130 hsize_t *off = NULL; /* Array to store sequence offsets */
2131 size_t *len = NULL; /* Array to store sequence lengths */
2132 hssize_t nelmts; /* Number of elements in selection */
2133 size_t max_elem; /* Total number of elements in selection */
2134 herr_t ret_value = SUCCEED; /* Return value */
2135
2136 FUNC_ENTER_NOAPI(FAIL)
2137
2138 /* Check args */
2139 HDassert(fill);
2140 HDassert(fill_size > 0);
2141 HDassert(space);
2142 HDassert(_buf);
2143
2144 /* Allocate the selection iterator */
2145 if(NULL == (iter = H5FL_MALLOC(H5S_sel_iter_t)))
2146 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator")
2147
2148 /* Initialize iterator */
2149 if(H5S_select_iter_init(iter, space, fill_size) < 0)
2150 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator")
2151 iter_init = 1; /* Selection iteration info has been initialized */
2152
2153 /* Get the number of elements in selection */
2154 if((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0)
2155 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected")
2156
2157 /* Compute the number of bytes to process */
2158 H5_CHECKED_ASSIGN(max_elem, size_t, nelmts, hssize_t);
2159
2160 /* Allocate the offset & length arrays */
2161 if(NULL == (len = H5FL_SEQ_MALLOC(size_t, H5D_IO_VECTOR_SIZE)))
2162 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate length vector array")
2163 if(NULL == (off = H5FL_SEQ_MALLOC(hsize_t, H5D_IO_VECTOR_SIZE)))
2164 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate offset vector array")
2165
2166 /* Loop, while elements left in selection */
2167 while(max_elem > 0) {
2168 size_t nseq; /* Number of sequences generated */
2169 size_t curr_seq; /* Current sequnce being worked on */
2170 size_t nelem; /* Number of elements used in sequences */
2171
2172 /* Get the sequences of bytes */
2173 if(H5S_SELECT_GET_SEQ_LIST(space, 0, iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, len) < 0)
2174 HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed")
2175
2176 /* Loop over sequences */
2177 for(curr_seq = 0; curr_seq < nseq; curr_seq++) {
2178 uint8_t *buf; /* Current location in buffer */
2179
2180 /* Get offset in memory buffer */
2181 buf = (uint8_t *)_buf + off[curr_seq];
2182
2183 /* Fill each sequence in memory with fill value */
2184 HDassert((len[curr_seq] % fill_size) == 0);
2185 H5VM_array_fill(buf, fill, fill_size, (len[curr_seq] / fill_size));
2186 } /* end for */
2187
2188 /* Decrement number of elements left to process */
2189 max_elem -= nelem;
2190 } /* end while */
2191
2192 done:
2193 /* Release resources, if allocated */
2194 if(len)
2195 len = H5FL_SEQ_FREE(size_t, len);
2196 if(off)
2197 off = H5FL_SEQ_FREE(hsize_t, off);
2198
2199 /* Release selection iterator */
2200 if(iter_init && H5S_SELECT_ITER_RELEASE(iter) < 0)
2201 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator")
2202 if(iter)
2203 iter = H5FL_FREE(H5S_sel_iter_t, iter);
2204
2205 FUNC_LEAVE_NOAPI(ret_value)
2206 } /* H5S_select_fill() */
2207
2208
2209 /*--------------------------------------------------------------------------
2210 NAME
2211 H5S_select_project_intersection
2212
2213 PURPOSE
2214 Projects the intersection of of the selections of src_space and
2215 src_intersect_space within the selection of src_space as a selection
2216 within the selection of dst_space
2217
2218 USAGE
2219 herr_t H5S_select_project_intersection(src_space,dst_space,src_intersect_space,proj_space)
2220 H5S_t *src_space; IN: Selection that is mapped to dst_space, and intersected with src_intersect_space
2221 H5S_t *dst_space; IN: Selection that is mapped to src_space, and which contains the result
2222 H5S_t *src_intersect_space; IN: Selection whose intersection with src_space is projected to dst_space to obtain the result
2223 H5S_t **new_space_ptr; OUT: Will contain the result (intersection of src_intersect_space and src_space projected from src_space to dst_space) after the operation
2224
2225 RETURNS
2226 Non-negative on success/Negative on failure.
2227
2228 DESCRIPTION
2229 Projects the intersection of of the selections of src_space and
2230 src_intersect_space within the selection of src_space as a selection
2231 within the selection of dst_space. The result is placed in the
2232 selection of new_space_ptr.
2233
2234 GLOBAL VARIABLES
2235 COMMENTS, BUGS, ASSUMPTIONS
2236 EXAMPLES
2237 REVISION LOG
2238 --------------------------------------------------------------------------*/
2239 herr_t
H5S_select_project_intersection(const H5S_t * src_space,const H5S_t * dst_space,const H5S_t * src_intersect_space,H5S_t ** new_space_ptr)2240 H5S_select_project_intersection(const H5S_t *src_space, const H5S_t *dst_space,
2241 const H5S_t *src_intersect_space, H5S_t **new_space_ptr)
2242 {
2243 H5S_t *new_space = NULL; /* New dataspace constructed */
2244 herr_t ret_value = SUCCEED; /* Return value */
2245
2246 FUNC_ENTER_NOAPI(FAIL)
2247
2248 /* Sanity checks */
2249 HDassert(src_space);
2250 HDassert(dst_space);
2251 HDassert(src_intersect_space);
2252 HDassert(new_space_ptr);
2253
2254 /* Create new space, using dst extent. Start with "all" selection. */
2255 if(NULL == (new_space = H5S_create(H5S_SIMPLE)))
2256 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create output dataspace")
2257 if(H5S_extent_copy_real(&new_space->extent, &dst_space->extent, TRUE) < 0)
2258 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy destination space extent")
2259
2260 /* If the intersecting space is "all", the intersection must be equal to the
2261 * source space and the projection must be equal to the destination space */
2262 if(src_intersect_space->select.type->type == H5S_SEL_ALL) {
2263 /* Copy the destination selection. */
2264 if(H5S_select_copy(new_space, dst_space, FALSE) < 0)
2265 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy destination space selection")
2266 } /* end if */
2267 /* If any of the spaces are "none", the projection must also be "none" */
2268 else if((src_intersect_space->select.type->type == H5S_SEL_NONE)
2269 || (src_space->select.type->type == H5S_SEL_NONE)
2270 || (dst_space->select.type->type == H5S_SEL_NONE)) {
2271 /* Change to "none" selection */
2272 if(H5S_select_none(new_space) < 0)
2273 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
2274 } /* end if */
2275 /* If any of the spaces use point selection, fall back to general algorithm
2276 */
2277 else if((src_intersect_space->select.type->type == H5S_SEL_POINTS)
2278 || (src_space->select.type->type == H5S_SEL_POINTS)
2279 || (dst_space->select.type->type == H5S_SEL_POINTS))
2280 HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported")
2281 else {
2282 HDassert(src_intersect_space->select.type->type == H5S_SEL_HYPERSLABS);
2283 /* Intersecting space is hyperslab selection. Call the hyperslab
2284 * routine to project to another hyperslab selection. */
2285 if(H5S__hyper_project_intersection(src_space, dst_space, src_intersect_space, new_space) < 0)
2286 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't project hyperslab ondot destination selection")
2287 } /* end else */
2288
2289 /* load the address of the new space into *new_space_ptr */
2290 *new_space_ptr = new_space;
2291
2292 done:
2293 /* Cleanup on error */
2294 if(ret_value < 0)
2295 if(new_space && H5S_close(new_space) < 0)
2296 HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
2297
2298 FUNC_LEAVE_NOAPI(ret_value)
2299 } /* H5S_select_project_intersection() */
2300
2301
2302 /*--------------------------------------------------------------------------
2303 NAME
2304 H5S_select_subtract
2305
2306 PURPOSE
2307 Subtract one selection from another
2308
2309 USAGE
2310 herr_t H5S_select_subtract(space,subtract_space)
2311 H5S_t *space; IN/OUT: Selection to be operated on
2312 H5S_t *subtract_space; IN: Selection that will be subtracted from space
2313
2314 RETURNS
2315 Non-negative on success/Negative on failure.
2316
2317 DESCRIPTION
2318 Removes any and all portions of space that are also present in
2319 subtract_space. In essence, performs an A_NOT_B operation with the
2320 two selections.
2321
2322 GLOBAL VARIABLES
2323 COMMENTS, BUGS, ASSUMPTIONS
2324 EXAMPLES
2325 REVISION LOG
2326 --------------------------------------------------------------------------*/
2327 herr_t
H5S_select_subtract(H5S_t * space,H5S_t * subtract_space)2328 H5S_select_subtract(H5S_t *space, H5S_t *subtract_space)
2329 {
2330 herr_t ret_value = SUCCEED; /* Return value */
2331
2332 FUNC_ENTER_NOAPI(FAIL)
2333
2334 /* Sanity checks */
2335 HDassert(space);
2336 HDassert(subtract_space);
2337
2338 /* If either space is using the none selection, then we do not need to do
2339 * anything */
2340 if((space->select.type->type != H5S_SEL_NONE)
2341 && (subtract_space->select.type->type != H5S_SEL_NONE)) {
2342 /* If subtract_space is using the all selection, set space to none */
2343 if(subtract_space->select.type->type == H5S_SEL_ALL) {
2344 /* Change to "none" selection */
2345 if(H5S_select_none(space) < 0)
2346 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection")
2347 } /* end if */
2348 else {
2349 /* Check for point selection in subtract_space, convert to hyperslab */
2350 if(subtract_space->select.type->type == H5S_SEL_POINTS)
2351 HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported")
2352
2353 /* Check for point or all selection in space, convert to hyperslab */
2354 if(space->select.type->type == H5S_SEL_ALL) {
2355 /* Convert current "all" selection to "real" hyperslab selection */
2356 /* Then allow operation to proceed */
2357 hsize_t tmp_start[H5S_MAX_RANK]; /* Temporary start information */
2358 hsize_t tmp_stride[H5S_MAX_RANK]; /* Temporary stride information */
2359 hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary count information */
2360 hsize_t tmp_block[H5S_MAX_RANK]; /* Temporary block information */
2361 unsigned u; /* Local index variable */
2362
2363 /* Fill in temporary information for the dimensions */
2364 for(u = 0; u < space->extent.rank; u++) {
2365 tmp_start[u] = 0;
2366 tmp_stride[u] = 1;
2367 tmp_count[u] = 1;
2368 tmp_block[u] = space->extent.size[u];
2369 } /* end for */
2370
2371 /* Convert to hyperslab selection */
2372 if(H5S_select_hyperslab(space, H5S_SELECT_SET, tmp_start, tmp_stride, tmp_count, tmp_block) < 0)
2373 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection")
2374 } /* end if */
2375 else if(space->select.type->type == H5S_SEL_POINTS)
2376 HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported")
2377
2378 HDassert(space->select.type->type == H5S_SEL_HYPERSLABS);
2379 HDassert(subtract_space->select.type->type == H5S_SEL_HYPERSLABS);
2380
2381 /* Both spaces are now hyperslabs, perform the operation */
2382 if(H5S__hyper_subtract(space, subtract_space) < 0)
2383 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't subtract hyperslab")
2384 } /* end else */
2385 } /* end if */
2386
2387 done:
2388 FUNC_LEAVE_NOAPI(ret_value)
2389 } /* H5S_select_subtract() */
2390
2391