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