/src/hdf5/src/H5Sselect.c
Line | Count | Source |
1 | | /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * |
2 | | * Copyright by The HDF Group. * |
3 | | * All rights reserved. * |
4 | | * * |
5 | | * This file is part of HDF5. The full HDF5 copyright notice, including * |
6 | | * terms governing use, modification, and redistribution, is contained in * |
7 | | * the LICENSE file, which can be found at the root of the source code * |
8 | | * distribution tree, or in https://www.hdfgroup.org/licenses. * |
9 | | * If you do not have access to either file, you may request a copy from * |
10 | | * help@hdfgroup.org. * |
11 | | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
12 | | |
13 | | /* |
14 | | * Purpose: Dataspace selection functions. |
15 | | */ |
16 | | |
17 | | /****************/ |
18 | | /* Module Setup */ |
19 | | /****************/ |
20 | | |
21 | | #include "H5Smodule.h" /* This source code file is part of the H5S module */ |
22 | | |
23 | | /***********/ |
24 | | /* Headers */ |
25 | | /***********/ |
26 | | #include "H5private.h" /* Generic Functions */ |
27 | | #include "H5Dprivate.h" /* Datasets */ |
28 | | #include "H5Eprivate.h" /* Error handling */ |
29 | | #include "H5FLprivate.h" /* Free Lists */ |
30 | | #include "H5Iprivate.h" /* IDs */ |
31 | | #include "H5MMprivate.h" /* Memory management */ |
32 | | #include "H5Spkg.h" /* Dataspaces */ |
33 | | #include "H5VMprivate.h" /* Vector and array functions */ |
34 | | |
35 | | /****************/ |
36 | | /* Local Macros */ |
37 | | /****************/ |
38 | | |
39 | | /* All the valid public flags to H5Ssel_iter_create() */ |
40 | 0 | #define H5S_SEL_ITER_ALL_PUBLIC_FLAGS (H5S_SEL_ITER_GET_SEQ_LIST_SORTED | H5S_SEL_ITER_SHARE_WITH_DATASPACE) |
41 | | |
42 | | /******************/ |
43 | | /* Local Typedefs */ |
44 | | /******************/ |
45 | | |
46 | | /********************/ |
47 | | /* Local Prototypes */ |
48 | | /********************/ |
49 | | |
50 | | /*****************************/ |
51 | | /* Library Private Variables */ |
52 | | /*****************************/ |
53 | | |
54 | | /*********************/ |
55 | | /* Package Variables */ |
56 | | /*********************/ |
57 | | |
58 | | /* Declare a free list to manage the H5S_sel_iter_t struct */ |
59 | | H5FL_DEFINE(H5S_sel_iter_t); |
60 | | |
61 | | /* Declare extern free list to manage sequences of size_t */ |
62 | | H5FL_SEQ_EXTERN(size_t); |
63 | | |
64 | | /* Declare extern free list to manage sequences of hsize_t */ |
65 | | H5FL_SEQ_EXTERN(hsize_t); |
66 | | |
67 | | /*******************/ |
68 | | /* Local Variables */ |
69 | | /*******************/ |
70 | | |
71 | | /*-------------------------------------------------------------------------- |
72 | | NAME |
73 | | H5S_select_offset |
74 | | PURPOSE |
75 | | Set the selection offset for a datapace |
76 | | USAGE |
77 | | herr_t H5S_select_offset(space, offset) |
78 | | H5S_t *space; IN/OUT: Dataspace object to set selection offset |
79 | | const hssize_t *offset; IN: Offset to position the selection at |
80 | | RETURNS |
81 | | Non-negative on success/Negative on failure |
82 | | DESCRIPTION |
83 | | Sets the selection offset for the dataspace |
84 | | --------------------------------------------------------------------------*/ |
85 | | herr_t |
86 | | H5S_select_offset(H5S_t *space, const hssize_t *offset) |
87 | 0 | { |
88 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
89 | | |
90 | | /* Check args */ |
91 | 0 | assert(space); |
92 | 0 | assert(0 < space->extent.rank && space->extent.rank <= H5S_MAX_RANK); |
93 | | |
94 | | /* Copy the offset over. As a special case, when offset is NULL, we |
95 | | * reset all dimensions to zero. |
96 | | */ |
97 | 0 | if (offset) |
98 | 0 | H5MM_memcpy(space->select.offset, offset, sizeof(hssize_t) * space->extent.rank); |
99 | 0 | else |
100 | 0 | memset(space->select.offset, 0, sizeof(hssize_t) * space->extent.rank); |
101 | | |
102 | | /* Indicate that the offset was changed */ |
103 | 0 | space->select.offset_changed = true; |
104 | |
|
105 | 0 | FUNC_LEAVE_NOAPI(SUCCEED) |
106 | 0 | } /* end H5S_select_offset() */ |
107 | | |
108 | | /*-------------------------------------------------------------------------- |
109 | | NAME |
110 | | H5Soffset_simple |
111 | | PURPOSE |
112 | | Changes the offset of a selection within a simple dataspace extent |
113 | | USAGE |
114 | | herr_t H5Soffset_simple(space_id, offset) |
115 | | hid_t space_id; IN: Dataspace object to reset |
116 | | const hssize_t *offset; IN: Offset to position the selection at |
117 | | RETURNS |
118 | | Non-negative on success/Negative on failure |
119 | | DESCRIPTION |
120 | | This function creates an offset for the selection within an extent, allowing |
121 | | the same shaped selection to be moved to different locations within a |
122 | | dataspace without requiring it to be re-defined. |
123 | | --------------------------------------------------------------------------*/ |
124 | | herr_t |
125 | | H5Soffset_simple(hid_t space_id, const hssize_t *offset) |
126 | 0 | { |
127 | 0 | H5S_t *space; /* Dataspace to modify */ |
128 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
129 | |
|
130 | 0 | FUNC_ENTER_API(FAIL) |
131 | | |
132 | | /* Check args */ |
133 | 0 | if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) |
134 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADID, FAIL, "not a dataspace"); |
135 | 0 | if (space->extent.rank == 0 || |
136 | 0 | (H5S_GET_EXTENT_TYPE(space) == H5S_SCALAR || H5S_GET_EXTENT_TYPE(space) == H5S_NULL)) |
137 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "can't set offset on scalar or null dataspace"); |
138 | | |
139 | | /* offset can be NULL (resets all dims to zero) */ |
140 | | |
141 | | /* Set the selection offset */ |
142 | 0 | if (H5S_select_offset(space, offset) < 0) |
143 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't set offset"); |
144 | | |
145 | 0 | done: |
146 | 0 | FUNC_LEAVE_API(ret_value) |
147 | 0 | } /* end H5Soffset_simple() */ |
148 | | |
149 | | /*-------------------------------------------------------------------------- |
150 | | NAME |
151 | | H5Sselect_copy |
152 | | PURPOSE |
153 | | Copy a selection from one dataspace to another |
154 | | USAGE |
155 | | herr_t H5Sselect_copy(dst, src) |
156 | | hid_t dst; OUT: ID of the destination dataspace |
157 | | hid_t src; IN: ID of the source dataspace |
158 | | |
159 | | RETURNS |
160 | | Non-negative on success/Negative on failure |
161 | | DESCRIPTION |
162 | | Copies all the selection information (including offset) from the source |
163 | | dataspace to the destination dataspace. |
164 | | |
165 | | GLOBAL VARIABLES |
166 | | COMMENTS, BUGS, ASSUMPTIONS |
167 | | EXAMPLES |
168 | | REVISION LOG |
169 | | --------------------------------------------------------------------------*/ |
170 | | herr_t |
171 | | H5Sselect_copy(hid_t dst_id, hid_t src_id) |
172 | 0 | { |
173 | 0 | H5S_t *src; |
174 | 0 | H5S_t *dst; |
175 | 0 | herr_t ret_value = SUCCEED; |
176 | |
|
177 | 0 | FUNC_ENTER_API(FAIL) |
178 | | |
179 | | /* Check args */ |
180 | 0 | if (NULL == (src = (H5S_t *)H5I_object_verify(src_id, H5I_DATASPACE))) |
181 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace"); |
182 | 0 | if (NULL == (dst = (H5S_t *)H5I_object_verify(dst_id, H5I_DATASPACE))) |
183 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace"); |
184 | | |
185 | | /* Copy */ |
186 | 0 | if (H5S_select_copy(dst, src, false) < 0) |
187 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy selection"); |
188 | | |
189 | 0 | done: |
190 | 0 | FUNC_LEAVE_API(ret_value) |
191 | 0 | } /* end H5Sselect_copy() */ |
192 | | |
193 | | /*-------------------------------------------------------------------------- |
194 | | NAME |
195 | | H5S_select_copy |
196 | | PURPOSE |
197 | | Copy a selection from one dataspace to another |
198 | | USAGE |
199 | | herr_t H5S_select_copy(dst, src, share_selection) |
200 | | H5S_t *dst; OUT: Pointer to the destination dataspace |
201 | | H5S_t *src; IN: Pointer to the source dataspace |
202 | | bool; IN: Whether to share the selection between the dataspaces |
203 | | RETURNS |
204 | | Non-negative on success/Negative on failure |
205 | | DESCRIPTION |
206 | | Copies all the selection information (include offset) from the source |
207 | | dataspace to the destination dataspace. |
208 | | |
209 | | If the SHARE_SELECTION flag is set, then the selection can be shared |
210 | | between the source and destination dataspaces. (This should only occur in |
211 | | situations where the destination dataspace will immediately change to a new |
212 | | selection) |
213 | | GLOBAL VARIABLES |
214 | | COMMENTS, BUGS, ASSUMPTIONS |
215 | | EXAMPLES |
216 | | REVISION LOG |
217 | | --------------------------------------------------------------------------*/ |
218 | | herr_t |
219 | | H5S_select_copy(H5S_t *dst, const H5S_t *src, bool share_selection) |
220 | 237k | { |
221 | 237k | H5S_t tmp_space; |
222 | 237k | bool copied_space = false; |
223 | 237k | herr_t ret_value = FAIL; /* Return value */ |
224 | | |
225 | 237k | FUNC_ENTER_NOAPI(FAIL) |
226 | | |
227 | | /* Check args */ |
228 | 237k | assert(dst); |
229 | 237k | assert(src); |
230 | | |
231 | 237k | tmp_space = *dst; |
232 | | |
233 | | /* Copy regular fields */ |
234 | 237k | tmp_space.select = src->select; |
235 | | |
236 | | /* Perform correct type of copy based on the type of selection */ |
237 | 237k | if ((ret_value = (*src->select.type->copy)(&tmp_space, src, share_selection)) < 0) |
238 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy selection specific information"); |
239 | 237k | copied_space = true; |
240 | | |
241 | | /* Release the current selection */ |
242 | 237k | if (H5S_SELECT_RELEASE(dst) < 0) |
243 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection"); |
244 | | |
245 | 237k | *dst = tmp_space; |
246 | | |
247 | 237k | done: |
248 | | |
249 | 237k | if (ret_value < 0) { |
250 | 0 | if (copied_space && H5S_SELECT_RELEASE(&tmp_space) < 0) |
251 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection"); |
252 | 0 | } |
253 | | |
254 | 237k | FUNC_LEAVE_NOAPI(ret_value) |
255 | 237k | } /* end H5S_select_copy() */ |
256 | | |
257 | | /*------------------------------------------------------------------------- |
258 | | * Function: H5S_select_release |
259 | | * |
260 | | * Purpose: Releases all memory associated with a dataspace selection. |
261 | | * |
262 | | * Return: Non-negative on success/Negative on failure |
263 | | * |
264 | | * Note: This routine participates in the "Inlining C function pointers" |
265 | | * pattern, don't call it directly, use the appropriate macro |
266 | | * defined in H5Sprivate.h. |
267 | | * |
268 | | *------------------------------------------------------------------------- |
269 | | */ |
270 | | herr_t |
271 | | H5S_select_release(H5S_t *ds) |
272 | 707k | { |
273 | 707k | herr_t ret_value = SUCCEED; /* Return value */ |
274 | | |
275 | 707k | FUNC_ENTER_NOAPI_NOINIT |
276 | | |
277 | 707k | assert(ds); |
278 | | |
279 | | /* Call the selection type's release function */ |
280 | 707k | if ((ds->select.type) && ((ret_value = (*ds->select.type->release)(ds)) < 0)) |
281 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection"); |
282 | | |
283 | 707k | done: |
284 | 707k | FUNC_LEAVE_NOAPI(ret_value) |
285 | 707k | } /* end H5S_select_release() */ |
286 | | |
287 | | /*------------------------------------------------------------------------- |
288 | | * Function: H5S_select_serial_size |
289 | | * |
290 | | * Purpose: Determines the number of bytes required to store the current |
291 | | * selection |
292 | | * |
293 | | * Return: Non-negative on success/Negative on failure |
294 | | * |
295 | | * Note: This routine participates in the "Inlining C function pointers" |
296 | | * pattern, don't call it directly, use the appropriate macro |
297 | | * defined in H5Sprivate.h. |
298 | | * |
299 | | *------------------------------------------------------------------------- |
300 | | */ |
301 | | hssize_t |
302 | | H5S_select_serial_size(H5S_t *space) |
303 | 0 | { |
304 | 0 | hssize_t ret_value = -1; /* Return value */ |
305 | |
|
306 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
307 | |
|
308 | 0 | assert(space); |
309 | | |
310 | | /* Call the selection type's serial_size function */ |
311 | 0 | ret_value = (*space->select.type->serial_size)(space); |
312 | |
|
313 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
314 | 0 | } /* end H5S_select_serial_size() */ |
315 | | |
316 | | /*-------------------------------------------------------------------------- |
317 | | NAME |
318 | | H5S_select_serialize |
319 | | PURPOSE |
320 | | Serialize the selection for a dataspace into a buffer |
321 | | USAGE |
322 | | herr_t H5S_select_serialize(space, p) |
323 | | const H5S_t *space; IN: Dataspace with selection to serialize |
324 | | uint8_t **p; OUT: Pointer to buffer to put serialized |
325 | | selection. Will be advanced to end of |
326 | | serialized selection. |
327 | | RETURNS |
328 | | Non-negative on success/Negative on failure |
329 | | DESCRIPTION |
330 | | Calls the appropriate dataspace selection callback to serialize the |
331 | | current selection into a buffer. |
332 | | GLOBAL VARIABLES |
333 | | COMMENTS, BUGS, ASSUMPTIONS |
334 | | This routine participates in the "Inlining C function pointers" |
335 | | pattern, don't call it directly, use the appropriate macro |
336 | | defined in H5Sprivate.h. |
337 | | EXAMPLES |
338 | | REVISION LOG |
339 | | --------------------------------------------------------------------------*/ |
340 | | herr_t |
341 | | H5S_select_serialize(H5S_t *space, uint8_t **p) |
342 | 0 | { |
343 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
344 | |
|
345 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
346 | |
|
347 | 0 | assert(space); |
348 | 0 | assert(p); |
349 | | |
350 | | /* Call the selection type's serialize function */ |
351 | 0 | ret_value = (*space->select.type->serialize)(space, p); |
352 | |
|
353 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
354 | 0 | } /* end H5S_select_serialize() */ |
355 | | |
356 | | /*-------------------------------------------------------------------------- |
357 | | NAME |
358 | | H5Sget_select_npoints |
359 | | PURPOSE |
360 | | Get the number of elements in current selection |
361 | | USAGE |
362 | | hssize_t H5Sget_select_npoints(dsid) |
363 | | hid_t dsid; IN: Dataspace ID of selection to query |
364 | | RETURNS |
365 | | Non-negative on success/Negative on failure |
366 | | DESCRIPTION |
367 | | Returns the number of elements in current selection for dataspace. |
368 | | GLOBAL VARIABLES |
369 | | COMMENTS, BUGS, ASSUMPTIONS |
370 | | EXAMPLES |
371 | | REVISION LOG |
372 | | --------------------------------------------------------------------------*/ |
373 | | hssize_t |
374 | | H5Sget_select_npoints(hid_t spaceid) |
375 | 0 | { |
376 | 0 | H5S_t *space; /* Dataspace to modify selection of */ |
377 | 0 | hssize_t ret_value; /* return value */ |
378 | |
|
379 | 0 | FUNC_ENTER_API(FAIL) |
380 | | |
381 | | /* Check args */ |
382 | 0 | if (NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE))) |
383 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace"); |
384 | | |
385 | 0 | ret_value = (hssize_t)H5S_GET_SELECT_NPOINTS(space); |
386 | |
|
387 | 0 | done: |
388 | 0 | FUNC_LEAVE_API(ret_value) |
389 | 0 | } /* H5Sget_select_npoints() */ |
390 | | |
391 | | /*-------------------------------------------------------------------------- |
392 | | NAME |
393 | | H5S_get_select_npoints |
394 | | PURPOSE |
395 | | Get the number of elements in current selection |
396 | | USAGE |
397 | | hsize_t H5Sget_select_npoints(space) |
398 | | H5S_t *space; IN: Dataspace of selection to query |
399 | | RETURNS |
400 | | The number of elements in selection on success, 0 on failure |
401 | | DESCRIPTION |
402 | | Returns the number of elements in current selection for dataspace. |
403 | | GLOBAL VARIABLES |
404 | | COMMENTS, BUGS, ASSUMPTIONS |
405 | | This routine participates in the "Inlining C function pointers" |
406 | | pattern, don't call it directly, use the appropriate macro |
407 | | defined in H5Sprivate.h. |
408 | | EXAMPLES |
409 | | REVISION LOG |
410 | | --------------------------------------------------------------------------*/ |
411 | | H5_ATTR_PURE hsize_t |
412 | | H5S_get_select_npoints(const H5S_t *space) |
413 | 103k | { |
414 | 103k | FUNC_ENTER_NOAPI_NOINIT_NOERR |
415 | | |
416 | | /* Check args */ |
417 | 103k | assert(space); |
418 | | |
419 | 103k | FUNC_LEAVE_NOAPI(space->select.num_elem) |
420 | 103k | } /* end H5S_get_select_npoints() */ |
421 | | |
422 | | /*-------------------------------------------------------------------------- |
423 | | NAME |
424 | | H5Sselect_valid |
425 | | PURPOSE |
426 | | Check whether the selection fits within the extent, with the current |
427 | | offset defined. |
428 | | USAGE |
429 | | htri_t H5Sselect_valid(dsid) |
430 | | hid_t dsid; IN: Dataspace ID to query |
431 | | RETURNS |
432 | | true if the selection fits within the extent, false if it does not and |
433 | | Negative on an error. |
434 | | DESCRIPTION |
435 | | Determines if the current selection at the current offset fits within the |
436 | | extent for the dataspace. |
437 | | GLOBAL VARIABLES |
438 | | COMMENTS, BUGS, ASSUMPTIONS |
439 | | EXAMPLES |
440 | | REVISION LOG |
441 | | --------------------------------------------------------------------------*/ |
442 | | htri_t |
443 | | H5Sselect_valid(hid_t spaceid) |
444 | 0 | { |
445 | 0 | H5S_t *space; /* Dataspace to modify selection of */ |
446 | 0 | htri_t ret_value; /* return value */ |
447 | |
|
448 | 0 | FUNC_ENTER_API(FAIL) |
449 | | |
450 | | /* Check args */ |
451 | 0 | if (NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE))) |
452 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace"); |
453 | | |
454 | 0 | ret_value = H5S_SELECT_VALID(space); |
455 | |
|
456 | 0 | done: |
457 | 0 | FUNC_LEAVE_API(ret_value) |
458 | 0 | } /* end H5Sselect_valid() */ |
459 | | |
460 | | /*-------------------------------------------------------------------------- |
461 | | NAME |
462 | | H5S_select_valid |
463 | | PURPOSE |
464 | | Check whether the selection fits within the extent, with the current |
465 | | offset defined. |
466 | | USAGE |
467 | | htri_t H5S_select_valid(space) |
468 | | H5S_t *space; IN: Dataspace to query |
469 | | RETURNS |
470 | | true if the selection fits within the extent, false if it does not and |
471 | | Negative on an error. |
472 | | DESCRIPTION |
473 | | Determines if the current selection at the current offset fits within the |
474 | | extent for the dataspace. |
475 | | GLOBAL VARIABLES |
476 | | COMMENTS, BUGS, ASSUMPTIONS |
477 | | This routine participates in the "Inlining C function pointers" |
478 | | pattern, don't call it directly, use the appropriate macro |
479 | | defined in H5Sprivate.h. |
480 | | EXAMPLES |
481 | | REVISION LOG |
482 | | --------------------------------------------------------------------------*/ |
483 | | htri_t |
484 | | H5S_select_valid(const H5S_t *space) |
485 | 103k | { |
486 | 103k | htri_t ret_value = FAIL; /* Return value */ |
487 | | |
488 | 103k | FUNC_ENTER_NOAPI_NOINIT_NOERR |
489 | | |
490 | 103k | assert(space); |
491 | | |
492 | 103k | ret_value = (*space->select.type->is_valid)(space); |
493 | | |
494 | 103k | FUNC_LEAVE_NOAPI(ret_value) |
495 | 103k | } /* end H5S_select_valid() */ |
496 | | |
497 | | /*-------------------------------------------------------------------------- |
498 | | NAME |
499 | | H5S_select_deserialize |
500 | | PURPOSE |
501 | | Deserialize the current selection from a user-provided buffer into a real |
502 | | selection in the dataspace. |
503 | | USAGE |
504 | | herr_t H5S_select_deserialize(space, p) |
505 | | H5S_t **space; IN/OUT: Dataspace pointer to place |
506 | | selection into. Will be allocated if not |
507 | | provided. |
508 | | uint8 **p; OUT: Pointer to buffer holding serialized |
509 | | selection. Will be advanced to end of |
510 | | serialized selection. |
511 | | RETURNS |
512 | | Non-negative on success/Negative on failure |
513 | | DESCRIPTION |
514 | | Deserializes the current selection into a buffer. (Primarily for retrieving |
515 | | from disk). This routine just hands off to the appropriate routine for each |
516 | | type of selection. The format of the serialized information is shown in |
517 | | the H5S_select_serialize() header. |
518 | | GLOBAL VARIABLES |
519 | | COMMENTS, BUGS, ASSUMPTIONS |
520 | | EXAMPLES |
521 | | REVISION LOG |
522 | | --------------------------------------------------------------------------*/ |
523 | | herr_t |
524 | | H5S_select_deserialize(H5S_t **space, const uint8_t **p, const size_t p_size) |
525 | 0 | { |
526 | 0 | uint32_t sel_type; /* Pointer to the selection type */ |
527 | 0 | herr_t ret_value = FAIL; /* Return value */ |
528 | 0 | const uint8_t *p_end = NULL; /* Pointer to last valid byte in buffer */ |
529 | 0 | size_t sel_info_size; /* Size of selection-type-specific information */ |
530 | 0 | bool skip = false; |
531 | |
|
532 | 0 | FUNC_ENTER_NOAPI(FAIL) |
533 | |
|
534 | 0 | assert(space); |
535 | | |
536 | | /* If p_size is unknown, skip buffer checks */ |
537 | 0 | skip = (p_size == SIZE_MAX ? true : false); |
538 | 0 | if (skip) |
539 | 0 | p_end = *p; |
540 | 0 | else if (p_size < sizeof(uint32_t)) |
541 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_OVERFLOW, FAIL, "selection buffer too small"); |
542 | 0 | else |
543 | 0 | p_end = *p + p_size - 1; |
544 | | |
545 | | /* Selection-type specific coding is moved to the callbacks. */ |
546 | | |
547 | | /* Decode selection type */ |
548 | 0 | if (H5_IS_KNOWN_BUFFER_OVERFLOW(skip, *p, sizeof(uint32_t), p_end)) |
549 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_OVERFLOW, FAIL, "buffer overflow while decoding selection type"); |
550 | 0 | UINT32DECODE(*p, sel_type); |
551 | 0 | sel_info_size = (skip ? SIZE_MAX : p_size - sizeof(uint32_t)); |
552 | | |
553 | | /* Make routine for selection type */ |
554 | 0 | switch (sel_type) { |
555 | 0 | case H5S_SEL_POINTS: /* Sequence of points selected */ |
556 | 0 | ret_value = (*H5S_sel_point->deserialize)(space, p, sel_info_size, skip); |
557 | 0 | break; |
558 | | |
559 | 0 | case H5S_SEL_HYPERSLABS: /* Hyperslab selection defined */ |
560 | 0 | ret_value = (*H5S_sel_hyper->deserialize)(space, p, sel_info_size, skip); |
561 | 0 | break; |
562 | | |
563 | 0 | case H5S_SEL_ALL: /* Entire extent selected */ |
564 | 0 | ret_value = (*H5S_sel_all->deserialize)(space, p, sel_info_size, skip); |
565 | 0 | break; |
566 | | |
567 | 0 | case H5S_SEL_NONE: /* Nothing selected */ |
568 | 0 | ret_value = (*H5S_sel_none->deserialize)(space, p, sel_info_size, skip); |
569 | 0 | break; |
570 | | |
571 | 0 | default: |
572 | 0 | break; |
573 | 0 | } |
574 | | |
575 | 0 | if (ret_value < 0) |
576 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTLOAD, FAIL, "can't deserialize selection"); |
577 | | |
578 | 0 | done: |
579 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
580 | 0 | } /* end H5S_select_deserialize() */ |
581 | | |
582 | | /*-------------------------------------------------------------------------- |
583 | | NAME |
584 | | H5Sget_select_bounds |
585 | | PURPOSE |
586 | | Gets the bounding box containing the selection. |
587 | | USAGE |
588 | | herr_t H5S_get_select_bounds(space, start, end) |
589 | | hid_t dsid; IN: Dataspace ID of selection to query |
590 | | hsize_t start[]; OUT: Starting coordinate of bounding box |
591 | | hsize_t end[]; OUT: Opposite coordinate of bounding box |
592 | | RETURNS |
593 | | Non-negative on success, negative on failure |
594 | | DESCRIPTION |
595 | | Retrieves the bounding box containing the current selection and places |
596 | | it into the user's buffers. The start and end buffers must be large |
597 | | enough to hold the dataspace rank number of coordinates. The bounding box |
598 | | exactly contains the selection, ie. if a 2-D element selection is currently |
599 | | defined with the following points: (4,5), (6,8) (10,7), the bounding box |
600 | | with be (4, 5), (10, 8). Calling this function on a "none" selection |
601 | | returns fail. |
602 | | The bounding box calculations _does_ include the current offset of the |
603 | | selection within the dataspace extent. |
604 | | GLOBAL VARIABLES |
605 | | COMMENTS, BUGS, ASSUMPTIONS |
606 | | This routine participates in the "Inlining C function pointers" |
607 | | pattern, don't call it directly, use the appropriate macro |
608 | | defined in H5Sprivate.h. |
609 | | EXAMPLES |
610 | | REVISION LOG |
611 | | --------------------------------------------------------------------------*/ |
612 | | herr_t |
613 | | H5Sget_select_bounds(hid_t spaceid, hsize_t start[] /*out*/, hsize_t end[] /*out*/) |
614 | 0 | { |
615 | 0 | H5S_t *space; /* Dataspace to modify selection of */ |
616 | 0 | herr_t ret_value; /* return value */ |
617 | |
|
618 | 0 | FUNC_ENTER_API(FAIL) |
619 | | |
620 | | /* Check args */ |
621 | 0 | if (start == NULL || end == NULL) |
622 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer"); |
623 | 0 | if (NULL == (space = (H5S_t *)H5I_object_verify(spaceid, H5I_DATASPACE))) |
624 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace"); |
625 | | |
626 | 0 | ret_value = H5S_SELECT_BOUNDS(space, start, end); |
627 | |
|
628 | 0 | done: |
629 | 0 | FUNC_LEAVE_API(ret_value) |
630 | 0 | } /* end H5Sget_select_bounds() */ |
631 | | |
632 | | /*-------------------------------------------------------------------------- |
633 | | NAME |
634 | | H5S_get_select_bounds |
635 | | PURPOSE |
636 | | Gets the bounding box containing the selection. |
637 | | USAGE |
638 | | herr_t H5S_get_select_bounds(space, start, end) |
639 | | H5S_t *space; IN: Dataspace ID of selection to query |
640 | | hsize_t *start; OUT: Starting coordinate of bounding box |
641 | | hsize_t *end; OUT: Opposite coordinate of bounding box |
642 | | RETURNS |
643 | | Non-negative on success, negative on failure |
644 | | DESCRIPTION |
645 | | Retrieves the bounding box containing the current selection and places |
646 | | it into the user's buffers. The start and end buffers must be large |
647 | | enough to hold the dataspace rank number of coordinates. The bounding box |
648 | | exactly contains the selection, ie. if a 2-D element selection is currently |
649 | | defined with the following points: (4,5), (6,8) (10,7), the bounding box |
650 | | with be (4, 5), (10, 8). Calling this function on a "none" selection |
651 | | returns fail. |
652 | | The bounding box calculations _does_ include the current offset of the |
653 | | selection within the dataspace extent. |
654 | | GLOBAL VARIABLES |
655 | | COMMENTS, BUGS, ASSUMPTIONS |
656 | | EXAMPLES |
657 | | REVISION LOG |
658 | | --------------------------------------------------------------------------*/ |
659 | | herr_t |
660 | | H5S_get_select_bounds(const H5S_t *space, hsize_t *start, hsize_t *end) |
661 | 0 | { |
662 | 0 | herr_t ret_value = FAIL; /* Return value */ |
663 | |
|
664 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
665 | | |
666 | | /* Check args */ |
667 | 0 | assert(space); |
668 | 0 | assert(start); |
669 | 0 | assert(end); |
670 | |
|
671 | 0 | ret_value = (*space->select.type->bounds)(space, start, end); |
672 | |
|
673 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
674 | 0 | } /* end H5S_get_select_bounds() */ |
675 | | |
676 | | /*-------------------------------------------------------------------------- |
677 | | NAME |
678 | | H5S_get_select_offset |
679 | | PURPOSE |
680 | | Gets the linear offset of the first element for the selection. |
681 | | USAGE |
682 | | herr_t H5S_get_select_offset(space, offset) |
683 | | const H5S_t *space; IN: Dataspace pointer of selection to query |
684 | | hsize_t *offset; OUT: Linear offset of first element in selection |
685 | | RETURNS |
686 | | Non-negative on success, negative on failure |
687 | | DESCRIPTION |
688 | | Retrieves the linear offset (in "units" of elements) of the first element |
689 | | selected within the dataspace. |
690 | | GLOBAL VARIABLES |
691 | | COMMENTS, BUGS, ASSUMPTIONS |
692 | | The offset calculation _does_ include the current offset of the |
693 | | selection within the dataspace extent. |
694 | | |
695 | | Calling this function on a "none" selection returns fail. |
696 | | EXAMPLES |
697 | | REVISION LOG |
698 | | --------------------------------------------------------------------------*/ |
699 | | herr_t |
700 | | H5S_get_select_offset(const H5S_t *space, hsize_t *offset) |
701 | 706 | { |
702 | 706 | herr_t ret_value = FAIL; /* Return value */ |
703 | | |
704 | 706 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
705 | | |
706 | | /* Check args */ |
707 | 706 | assert(space); |
708 | 706 | assert(offset); |
709 | | |
710 | 706 | ret_value = (*space->select.type->offset)(space, offset); |
711 | | |
712 | 706 | FUNC_LEAVE_NOAPI(ret_value) |
713 | 706 | } /* end H5S_get_select_offset() */ |
714 | | |
715 | | /*-------------------------------------------------------------------------- |
716 | | NAME |
717 | | H5S_get_select_unlim_dim |
718 | | PURPOSE |
719 | | Gets the unlimited dimension in the selection, or -1 if there is no |
720 | | unlimited dimension. |
721 | | USAGE |
722 | | int H5S_get_select_unlim_dim(space) |
723 | | const H5S_t *space; IN: Dataspace pointer of selection to query |
724 | | RETURNS |
725 | | Unlimited dimension in the selection, or -1 if there is no unlimited |
726 | | dimension (never fails) |
727 | | DESCRIPTION |
728 | | Gets the unlimited dimension in the selection, or -1 if there is no |
729 | | unlimited dimension. |
730 | | GLOBAL VARIABLES |
731 | | COMMENTS, BUGS, ASSUMPTIONS |
732 | | Currently only implemented for hyperslab selections, all others |
733 | | simply return -1. |
734 | | EXAMPLES |
735 | | REVISION LOG |
736 | | --------------------------------------------------------------------------*/ |
737 | | int |
738 | | H5S_get_select_unlim_dim(const H5S_t *space) |
739 | 0 | { |
740 | 0 | herr_t ret_value = FAIL; /* Return value */ |
741 | |
|
742 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
743 | | |
744 | | /* Check args */ |
745 | 0 | assert(space); |
746 | |
|
747 | 0 | ret_value = (*space->select.type->unlim_dim)(space); |
748 | |
|
749 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
750 | 0 | } /* end H5S_get_select_unlim_dim() */ |
751 | | |
752 | | /*-------------------------------------------------------------------------- |
753 | | NAME |
754 | | H5S_get_select_num_elem_non_unlim |
755 | | PURPOSE |
756 | | Gets the number of elements in the non-unlimited dimensions |
757 | | USAGE |
758 | | herr_t H5S_get_select_num_elem_non_unlim(space,num_elem_non_unlim) |
759 | | H5S_t *space; IN: Dataspace pointer to check |
760 | | hsize_t *num_elem_non_unlim; OUT: Number of elements in the non-unlimited dimensions |
761 | | RETURNS |
762 | | Non-negative on success/Negative on failure |
763 | | DESCRIPTION |
764 | | Returns the number of elements in a slice through the non-unlimited |
765 | | dimensions of the selection. Fails if the selection has no unlimited |
766 | | dimension. |
767 | | GLOBAL VARIABLES |
768 | | COMMENTS, BUGS, ASSUMPTIONS |
769 | | EXAMPLES |
770 | | REVISION LOG |
771 | | --------------------------------------------------------------------------*/ |
772 | | herr_t |
773 | | H5S_get_select_num_elem_non_unlim(const H5S_t *space, hsize_t *num_elem_non_unlim) |
774 | 0 | { |
775 | 0 | herr_t ret_value = SUCCEED; /* return value */ |
776 | |
|
777 | 0 | FUNC_ENTER_NOAPI(FAIL) |
778 | | |
779 | | /* Check args */ |
780 | 0 | assert(space); |
781 | 0 | assert(num_elem_non_unlim); |
782 | | |
783 | | /* Check for selection callback */ |
784 | 0 | if (!space->select.type->num_elem_non_unlim) |
785 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, |
786 | 0 | "selection type has no num_elem_non_unlim callback"); |
787 | | |
788 | | /* Make selection callback */ |
789 | 0 | if ((*space->select.type->num_elem_non_unlim)(space, num_elem_non_unlim) < 0) |
790 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, |
791 | 0 | "can't get number of elements in non-unlimited dimension"); |
792 | | |
793 | 0 | done: |
794 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
795 | 0 | } /* end H5S_get_select_unlim_dim() */ |
796 | | |
797 | | /*-------------------------------------------------------------------------- |
798 | | NAME |
799 | | H5S_select_is_contiguous |
800 | | PURPOSE |
801 | | Determines if a selection is contiguous in the dataspace |
802 | | USAGE |
803 | | htri_t H5S_select_is_contiguous(space) |
804 | | const H5S_t *space; IN: Dataspace of selection to query |
805 | | RETURNS |
806 | | Non-negative (true/false) on success, negative on failure |
807 | | DESCRIPTION |
808 | | Checks the selection to determine if the points to iterated over will be |
809 | | contiguous in the particular dataspace. |
810 | | GLOBAL VARIABLES |
811 | | COMMENTS, BUGS, ASSUMPTIONS |
812 | | This routine participates in the "Inlining C function pointers" |
813 | | pattern, don't call it directly, use the appropriate macro |
814 | | defined in H5Sprivate.h. |
815 | | EXAMPLES |
816 | | REVISION LOG |
817 | | --------------------------------------------------------------------------*/ |
818 | | htri_t |
819 | | H5S_select_is_contiguous(const H5S_t *space) |
820 | 0 | { |
821 | 0 | herr_t ret_value = FAIL; /* Return value */ |
822 | |
|
823 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
824 | | |
825 | | /* Check args */ |
826 | 0 | assert(space); |
827 | |
|
828 | 0 | ret_value = (*space->select.type->is_contiguous)(space); |
829 | |
|
830 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
831 | 0 | } /* end H5S_select_is_contiguous() */ |
832 | | |
833 | | /*-------------------------------------------------------------------------- |
834 | | NAME |
835 | | H5S_select_is_single |
836 | | PURPOSE |
837 | | Determines if a selection is a single block in the dataspace |
838 | | USAGE |
839 | | htri_t H5S_select_is_single(space) |
840 | | const H5S_t *space; IN: Dataspace of selection to query |
841 | | RETURNS |
842 | | Non-negative (true/false) on success, negative on failure |
843 | | DESCRIPTION |
844 | | Checks the selection to determine if it occupies a single block in the |
845 | | particular dataspace. |
846 | | GLOBAL VARIABLES |
847 | | COMMENTS, BUGS, ASSUMPTIONS |
848 | | This routine participates in the "Inlining C function pointers" |
849 | | pattern, don't call it directly, use the appropriate macro |
850 | | defined in H5Sprivate.h. |
851 | | EXAMPLES |
852 | | REVISION LOG |
853 | | --------------------------------------------------------------------------*/ |
854 | | htri_t |
855 | | H5S_select_is_single(const H5S_t *space) |
856 | 0 | { |
857 | 0 | herr_t ret_value = FAIL; /* Return value */ |
858 | |
|
859 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
860 | | |
861 | | /* Check args */ |
862 | 0 | assert(space); |
863 | |
|
864 | 0 | ret_value = (*space->select.type->is_single)(space); |
865 | |
|
866 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
867 | 0 | } /* end H5S_select_is_single() */ |
868 | | |
869 | | /*-------------------------------------------------------------------------- |
870 | | NAME |
871 | | H5S_select_is_regular |
872 | | PURPOSE |
873 | | Determines if a selection is "regular" in the dataspace |
874 | | USAGE |
875 | | htri_t H5S_select_is_regular(space) |
876 | | const H5S_t *space; IN: Dataspace of selection to query |
877 | | RETURNS |
878 | | Non-negative (true/false) on success, negative on failure |
879 | | DESCRIPTION |
880 | | Checks the selection to determine if it is "regular" (i.e. a single |
881 | | block or a strided pattern) in the particular dataspace. |
882 | | GLOBAL VARIABLES |
883 | | COMMENTS, BUGS, ASSUMPTIONS |
884 | | This routine participates in the "Inlining C function pointers" |
885 | | pattern, don't call it directly, use the appropriate macro |
886 | | defined in H5Sprivate.h. |
887 | | EXAMPLES |
888 | | REVISION LOG |
889 | | --------------------------------------------------------------------------*/ |
890 | | htri_t |
891 | | H5S_select_is_regular(H5S_t *space) |
892 | 0 | { |
893 | 0 | herr_t ret_value = FAIL; /* Return value */ |
894 | |
|
895 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
896 | | |
897 | | /* Check args */ |
898 | 0 | assert(space); |
899 | |
|
900 | 0 | ret_value = (*space->select.type->is_regular)(space); |
901 | |
|
902 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
903 | 0 | } /* end H5S_select_is_regular() */ |
904 | | |
905 | | /*-------------------------------------------------------------------------- |
906 | | NAME |
907 | | H5S_select_adjust_u |
908 | | PURPOSE |
909 | | Adjust a selection by subtracting an offset |
910 | | USAGE |
911 | | herr_t H5S_select_adjust_u(space, offset) |
912 | | H5S_t *space; IN/OUT: Pointer to dataspace to adjust |
913 | | const hsize_t *offset; IN: Offset to subtract |
914 | | RETURNS |
915 | | Non-negative on success, negative on failure |
916 | | DESCRIPTION |
917 | | Moves a selection by subtracting an offset from it. |
918 | | GLOBAL VARIABLES |
919 | | COMMENTS, BUGS, ASSUMPTIONS |
920 | | This routine participates in the "Inlining C function pointers" |
921 | | pattern, don't call it directly, use the appropriate macro |
922 | | defined in H5Sprivate.h. |
923 | | EXAMPLES |
924 | | REVISION LOG |
925 | | --------------------------------------------------------------------------*/ |
926 | | herr_t |
927 | | H5S_select_adjust_u(H5S_t *space, const hsize_t *offset) |
928 | 0 | { |
929 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
930 | |
|
931 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
932 | | |
933 | | /* Check args */ |
934 | 0 | assert(space); |
935 | 0 | assert(offset); |
936 | | |
937 | | /* Perform operation */ |
938 | 0 | ret_value = (*space->select.type->adjust_u)(space, offset); |
939 | |
|
940 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
941 | 0 | } /* end H5S_select_adjust_u() */ |
942 | | |
943 | | /*-------------------------------------------------------------------------- |
944 | | NAME |
945 | | H5S_select_adjust_s |
946 | | PURPOSE |
947 | | Adjust a selection by subtracting an offset |
948 | | USAGE |
949 | | herr_t H5S_select_adjust_s(space, offset) |
950 | | H5S_t *space; IN/OUT: Pointer to dataspace to adjust |
951 | | const hssize_t *offset; IN: Offset to subtract |
952 | | RETURNS |
953 | | Non-negative on success, negative on failure |
954 | | DESCRIPTION |
955 | | Moves a selection by subtracting an offset from it. |
956 | | GLOBAL VARIABLES |
957 | | COMMENTS, BUGS, ASSUMPTIONS |
958 | | This routine participates in the "Inlining C function pointers" |
959 | | pattern, don't call it directly, use the appropriate macro |
960 | | defined in H5Sprivate.h. |
961 | | EXAMPLES |
962 | | REVISION LOG |
963 | | --------------------------------------------------------------------------*/ |
964 | | herr_t |
965 | | H5S_select_adjust_s(H5S_t *space, const hssize_t *offset) |
966 | 0 | { |
967 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
968 | |
|
969 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
970 | | |
971 | | /* Check args */ |
972 | 0 | assert(space); |
973 | 0 | assert(offset); |
974 | | |
975 | | /* Perform operation */ |
976 | 0 | ret_value = (*space->select.type->adjust_s)(space, offset); |
977 | |
|
978 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
979 | 0 | } /* end H5S_select_adjust_s() */ |
980 | | |
981 | | /*-------------------------------------------------------------------------- |
982 | | NAME |
983 | | H5Sselect_adjust |
984 | | PURPOSE |
985 | | Adjust a selection by subtracting an offset |
986 | | USAGE |
987 | | herr_t H5Sselect_adjust_u(space_id, offset) |
988 | | hid_t space_id; IN: ID of dataspace to adjust |
989 | | const hsize_t *offset; IN: Offset to subtract |
990 | | RETURNS |
991 | | Non-negative on success, negative on failure |
992 | | DESCRIPTION |
993 | | Moves a selection by subtracting an offset from it. |
994 | | GLOBAL VARIABLES |
995 | | COMMENTS, BUGS, ASSUMPTIONS |
996 | | EXAMPLES |
997 | | REVISION LOG |
998 | | --------------------------------------------------------------------------*/ |
999 | | herr_t |
1000 | | H5Sselect_adjust(hid_t space_id, const hssize_t *offset) |
1001 | 0 | { |
1002 | 0 | H5S_t *space; |
1003 | 0 | hsize_t low_bounds[H5S_MAX_RANK]; |
1004 | 0 | hsize_t high_bounds[H5S_MAX_RANK]; |
1005 | 0 | unsigned u; |
1006 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
1007 | |
|
1008 | 0 | FUNC_ENTER_API(FAIL) |
1009 | |
|
1010 | 0 | if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) |
1011 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace"); |
1012 | 0 | if (NULL == offset) |
1013 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "NULL offset pointer"); |
1014 | | |
1015 | | /* Check bounds */ |
1016 | 0 | if (H5S_SELECT_BOUNDS(space, low_bounds, high_bounds) < 0) |
1017 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds"); |
1018 | 0 | for (u = 0; u < space->extent.rank; u++) |
1019 | 0 | if (offset[u] > (hssize_t)low_bounds[u]) |
1020 | 0 | HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "adjustment would move selection below zero offset"); |
1021 | | |
1022 | 0 | if (H5S_select_adjust_s(space, offset) < 0) |
1023 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't adjust selection"); |
1024 | | |
1025 | 0 | done: |
1026 | 0 | FUNC_LEAVE_API(ret_value) |
1027 | 0 | } /* end H5Sselect_adjust() */ |
1028 | | |
1029 | | /*-------------------------------------------------------------------------- |
1030 | | NAME |
1031 | | H5S_select_project_scalar |
1032 | | PURPOSE |
1033 | | Project a single element selection for a scalar dataspace |
1034 | | USAGE |
1035 | | herr_t H5S_select_project_scalar(space, offset) |
1036 | | const H5S_t *space; IN: Pointer to dataspace to project |
1037 | | hsize_t *offset; IN/OUT: Offset of projected point |
1038 | | RETURNS |
1039 | | Non-negative on success, negative on failure |
1040 | | DESCRIPTION |
1041 | | Projects a selection of a single element into a scalar dataspace, computing |
1042 | | the offset of the element in the original selection. |
1043 | | GLOBAL VARIABLES |
1044 | | COMMENTS, BUGS, ASSUMPTIONS |
1045 | | This routine participates in the "Inlining C function pointers" |
1046 | | pattern, don't call it directly, use the appropriate macro |
1047 | | defined in H5Sprivate.h. |
1048 | | EXAMPLES |
1049 | | REVISION LOG |
1050 | | --------------------------------------------------------------------------*/ |
1051 | | herr_t |
1052 | | H5S_select_project_scalar(const H5S_t *space, hsize_t *offset) |
1053 | 0 | { |
1054 | 0 | herr_t ret_value = FAIL; /* Return value */ |
1055 | |
|
1056 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
1057 | | |
1058 | | /* Check args */ |
1059 | 0 | assert(space); |
1060 | 0 | assert(offset); |
1061 | |
|
1062 | 0 | ret_value = (*space->select.type->project_scalar)(space, offset); |
1063 | |
|
1064 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1065 | 0 | } /* end H5S_select_project_scalar() */ |
1066 | | |
1067 | | /*-------------------------------------------------------------------------- |
1068 | | NAME |
1069 | | H5S_select_project_simple |
1070 | | PURPOSE |
1071 | | Project a selection onto/into a dataspace of different rank |
1072 | | USAGE |
1073 | | herr_t H5S_select_project_simple(space, new_space, offset) |
1074 | | const H5S_t *space; IN: Pointer to dataspace to project |
1075 | | H5S_t *new_space; IN/OUT: Pointer to dataspace projected onto |
1076 | | hsize_t *offset; IN/OUT: Offset of projected point |
1077 | | RETURNS |
1078 | | Non-negative on success, negative on failure |
1079 | | DESCRIPTION |
1080 | | Projects a selection onto/into a simple dataspace, computing |
1081 | | the offset of the first element in the original selection. |
1082 | | GLOBAL VARIABLES |
1083 | | COMMENTS, BUGS, ASSUMPTIONS |
1084 | | This routine participates in the "Inlining C function pointers" |
1085 | | pattern, don't call it directly, use the appropriate macro |
1086 | | defined in H5Sprivate.h. |
1087 | | EXAMPLES |
1088 | | REVISION LOG |
1089 | | --------------------------------------------------------------------------*/ |
1090 | | herr_t |
1091 | | H5S_select_project_simple(const H5S_t *space, H5S_t *new_space, hsize_t *offset) |
1092 | 0 | { |
1093 | 0 | herr_t ret_value = FAIL; /* Return value */ |
1094 | |
|
1095 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
1096 | | |
1097 | | /* Check args */ |
1098 | 0 | assert(space); |
1099 | 0 | assert(new_space); |
1100 | 0 | assert(offset); |
1101 | |
|
1102 | 0 | ret_value = (*space->select.type->project_simple)(space, new_space, offset); |
1103 | |
|
1104 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1105 | 0 | } /* end H5S_select_project_simple() */ |
1106 | | |
1107 | | /*-------------------------------------------------------------------------- |
1108 | | NAME |
1109 | | H5S_select_iter_init |
1110 | | PURPOSE |
1111 | | Initializes iteration information for a selection. |
1112 | | USAGE |
1113 | | herr_t H5S_select_iter_init(sel_iter, space, elmt_size, flags) |
1114 | | H5S_sel_iter_t *sel_iter; OUT: Selection iterator to initialize. |
1115 | | H5S_t *space; IN: Dataspace object containing selection to |
1116 | | iterate over |
1117 | | size_t elmt_size; IN: Size of elements in the selection |
1118 | | unsigned flags; IN: Flags to control iteration behavior |
1119 | | RETURNS |
1120 | | Non-negative on success, negative on failure. |
1121 | | DESCRIPTION |
1122 | | Initialize the selection iterator object to point to the first element |
1123 | | in the dataspace's selection. |
1124 | | --------------------------------------------------------------------------*/ |
1125 | | herr_t |
1126 | | H5S_select_iter_init(H5S_sel_iter_t *sel_iter, H5S_t *space, size_t elmt_size, unsigned flags) |
1127 | 125k | { |
1128 | 125k | herr_t ret_value = FAIL; /* Return value */ |
1129 | | |
1130 | 125k | FUNC_ENTER_NOAPI_NOINIT_NOERR |
1131 | | |
1132 | | /* Check args */ |
1133 | 125k | assert(sel_iter); |
1134 | 125k | assert(space); |
1135 | | |
1136 | | /* Initialize common information */ |
1137 | | |
1138 | | /* Save the dataspace's rank */ |
1139 | 125k | sel_iter->rank = space->extent.rank; |
1140 | | |
1141 | | /* If dims > 0, copy the dataspace dimensions & selection offset */ |
1142 | 125k | if (sel_iter->rank > 0) { |
1143 | 125k | H5MM_memcpy(sel_iter->dims, space->extent.size, sizeof(hsize_t) * space->extent.rank); |
1144 | 125k | H5MM_memcpy(sel_iter->sel_off, space->select.offset, sizeof(hsize_t) * space->extent.rank); |
1145 | 125k | } |
1146 | | |
1147 | | /* Save the element size */ |
1148 | 125k | sel_iter->elmt_size = elmt_size; |
1149 | | |
1150 | | /* Initialize the number of elements to iterate over */ |
1151 | 125k | sel_iter->elmt_left = space->select.num_elem; |
1152 | | |
1153 | | /* Set the flags for the iterator */ |
1154 | 125k | sel_iter->flags = flags; |
1155 | | |
1156 | | /* Call initialization routine for selection type */ |
1157 | 125k | ret_value = (*space->select.type->iter_init)(space, sel_iter); |
1158 | 125k | assert(sel_iter->type); |
1159 | | |
1160 | 125k | FUNC_LEAVE_NOAPI(ret_value) |
1161 | 125k | } /* end H5S_select_iter_init() */ |
1162 | | |
1163 | | /*-------------------------------------------------------------------------- |
1164 | | NAME |
1165 | | H5S_select_iter_coords |
1166 | | PURPOSE |
1167 | | Get the coordinates of the current iterator position |
1168 | | USAGE |
1169 | | herr_t H5S_select_iter_coords(sel_iter,coords) |
1170 | | H5S_sel_iter_t *sel_iter; IN: Selection iterator to query |
1171 | | hsize_t *coords; OUT: Array to place iterator coordinates in |
1172 | | RETURNS |
1173 | | Non-negative on success, negative on failure. |
1174 | | DESCRIPTION |
1175 | | The current location of the iterator within the selection is placed in |
1176 | | the COORDS array. |
1177 | | GLOBAL VARIABLES |
1178 | | COMMENTS, BUGS, ASSUMPTIONS |
1179 | | This routine participates in the "Inlining C function pointers" |
1180 | | pattern, don't call it directly, use the appropriate macro |
1181 | | defined in H5Sprivate.h. |
1182 | | EXAMPLES |
1183 | | REVISION LOG |
1184 | | --------------------------------------------------------------------------*/ |
1185 | | herr_t |
1186 | | H5S_select_iter_coords(const H5S_sel_iter_t *sel_iter, hsize_t *coords) |
1187 | 0 | { |
1188 | 0 | herr_t ret_value = FAIL; /* Return value */ |
1189 | |
|
1190 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
1191 | | |
1192 | | /* Check args */ |
1193 | 0 | assert(sel_iter); |
1194 | 0 | assert(coords); |
1195 | | |
1196 | | /* Call iter_coords routine for selection type */ |
1197 | 0 | ret_value = (*sel_iter->type->iter_coords)(sel_iter, coords); |
1198 | |
|
1199 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1200 | 0 | } /* end H5S_select_iter_coords() */ |
1201 | | |
1202 | | /*-------------------------------------------------------------------------- |
1203 | | NAME |
1204 | | H5S_select_iter_nelmts |
1205 | | PURPOSE |
1206 | | Get the number of elements left to iterate over in selection |
1207 | | USAGE |
1208 | | hssize_t H5S_select_iter_nelmts(sel_iter) |
1209 | | H5S_sel_iter_t *sel_iter; IN: Selection iterator to query |
1210 | | RETURNS |
1211 | | The number of elements in selection on success, 0 on failure |
1212 | | DESCRIPTION |
1213 | | Returns the number of elements in current selection for dataspace. |
1214 | | GLOBAL VARIABLES |
1215 | | COMMENTS, BUGS, ASSUMPTIONS |
1216 | | This routine participates in the "Inlining C function pointers" |
1217 | | pattern, don't call it directly, use the appropriate macro |
1218 | | defined in H5Sprivate.h. |
1219 | | EXAMPLES |
1220 | | REVISION LOG |
1221 | | --------------------------------------------------------------------------*/ |
1222 | | hsize_t |
1223 | | H5S_select_iter_nelmts(const H5S_sel_iter_t *sel_iter) |
1224 | 0 | { |
1225 | 0 | hsize_t ret_value = 0; /* Return value */ |
1226 | |
|
1227 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
1228 | | |
1229 | | /* Check args */ |
1230 | 0 | assert(sel_iter); |
1231 | | |
1232 | | /* Call iter_nelmts routine for selection type */ |
1233 | 0 | ret_value = (*sel_iter->type->iter_nelmts)(sel_iter); |
1234 | |
|
1235 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1236 | 0 | } /* end H5S_select_iter_nelmts() */ |
1237 | | |
1238 | | /*-------------------------------------------------------------------------- |
1239 | | NAME |
1240 | | H5S_select_iter_next |
1241 | | PURPOSE |
1242 | | Advance selection iterator to next element |
1243 | | USAGE |
1244 | | herr_t H5S_select_iter_next(iter, nelem) |
1245 | | H5S_sel_iter_t *iter; IN/OUT: Selection iterator to change |
1246 | | size_t nelem; IN: Number of elements to advance by |
1247 | | RETURNS |
1248 | | Non-negative on success, negative on failure. |
1249 | | DESCRIPTION |
1250 | | Move the current element for the selection iterator to the NELEM'th next |
1251 | | element in the selection. |
1252 | | GLOBAL VARIABLES |
1253 | | COMMENTS, BUGS, ASSUMPTIONS |
1254 | | This routine participates in the "Inlining C function pointers" |
1255 | | pattern, don't call it directly, use the appropriate macro |
1256 | | defined in H5Sprivate.h. |
1257 | | EXAMPLES |
1258 | | REVISION LOG |
1259 | | --------------------------------------------------------------------------*/ |
1260 | | herr_t |
1261 | | H5S_select_iter_next(H5S_sel_iter_t *iter, size_t nelem) |
1262 | 0 | { |
1263 | 0 | herr_t ret_value = FAIL; /* Return value */ |
1264 | |
|
1265 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
1266 | | |
1267 | | /* Check args */ |
1268 | 0 | assert(iter); |
1269 | 0 | assert(nelem > 0); |
1270 | | |
1271 | | /* Call iter_next routine for selection type */ |
1272 | 0 | ret_value = (*iter->type->iter_next)(iter, nelem); |
1273 | | |
1274 | | /* Decrement the number of elements left in selection */ |
1275 | 0 | iter->elmt_left -= nelem; |
1276 | |
|
1277 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1278 | 0 | } /* end H5S_select_iter_next() */ |
1279 | | |
1280 | | /*------------------------------------------------------------------------- |
1281 | | * Function: H5S_select_iter_get_seq_list |
1282 | | * |
1283 | | * Purpose: Retrieves the next sequence of offset/length pairs for an |
1284 | | * iterator on a dataspace |
1285 | | * |
1286 | | * Return: Non-negative on success/Negative on failure |
1287 | | * |
1288 | | * Note: This routine participates in the "Inlining C function pointers" |
1289 | | * pattern, don't call it directly, use the appropriate macro |
1290 | | * defined in H5Sprivate.h. |
1291 | | * |
1292 | | *------------------------------------------------------------------------- |
1293 | | */ |
1294 | | herr_t |
1295 | | H5S_select_iter_get_seq_list(H5S_sel_iter_t *iter, size_t maxseq, size_t maxelmts, size_t *nseq, |
1296 | | size_t *nelmts, hsize_t *off, size_t *len) |
1297 | 84.7k | { |
1298 | 84.7k | herr_t ret_value = FAIL; /* Return value */ |
1299 | | |
1300 | 84.7k | FUNC_ENTER_NOAPI_NOINIT |
1301 | | |
1302 | | /* Sanity check */ |
1303 | 84.7k | assert(iter); |
1304 | | |
1305 | | /* Call the selection type's get_seq_list function */ |
1306 | 84.7k | if ((ret_value = (*iter->type->iter_get_seq_list)(iter, maxseq, maxelmts, nseq, nelmts, off, len)) < 0) |
1307 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get selection sequence list"); |
1308 | | |
1309 | 84.7k | done: |
1310 | 84.7k | FUNC_LEAVE_NOAPI(ret_value) |
1311 | 84.7k | } /* end H5S_select_iter_get_seq_list() */ |
1312 | | |
1313 | | /*-------------------------------------------------------------------------- |
1314 | | NAME |
1315 | | H5S_select_iter_release |
1316 | | PURPOSE |
1317 | | Release a selection iterator's resources. |
1318 | | USAGE |
1319 | | herr_t H5S_select_iter_release(sel_iter) |
1320 | | H5S_sel_iter_t *sel_iter; IN: Selection iterator to query |
1321 | | RETURNS |
1322 | | The number of elements in selection on success, 0 on failure |
1323 | | DESCRIPTION |
1324 | | Returns the number of elements in current selection for dataspace. |
1325 | | GLOBAL VARIABLES |
1326 | | COMMENTS, BUGS, ASSUMPTIONS |
1327 | | This routine participates in the "Inlining C function pointers" |
1328 | | pattern, don't call it directly, use the appropriate macro |
1329 | | defined in H5Sprivate.h. |
1330 | | EXAMPLES |
1331 | | REVISION LOG |
1332 | | --------------------------------------------------------------------------*/ |
1333 | | herr_t |
1334 | | H5S_select_iter_release(H5S_sel_iter_t *sel_iter) |
1335 | 116k | { |
1336 | 116k | herr_t ret_value = FAIL; /* Return value */ |
1337 | | |
1338 | 116k | FUNC_ENTER_NOAPI_NOINIT_NOERR |
1339 | | |
1340 | | /* Check args */ |
1341 | 116k | assert(sel_iter); |
1342 | | |
1343 | | /* Call selection type-specific release routine */ |
1344 | 116k | ret_value = (*sel_iter->type->iter_release)(sel_iter); |
1345 | | |
1346 | 116k | FUNC_LEAVE_NOAPI(ret_value) |
1347 | 116k | } /* end H5S_select_iter_release() */ |
1348 | | |
1349 | | /*-------------------------------------------------------------------------- |
1350 | | NAME |
1351 | | H5S_select_iterate |
1352 | | PURPOSE |
1353 | | Iterate over the selected elements in a memory buffer. |
1354 | | USAGE |
1355 | | herr_t H5S_select_iterate(buf, type, space, operator, operator_data) |
1356 | | void *buf; IN/OUT: Buffer containing elements to iterate over |
1357 | | H5T_t *type; IN: Datatype of BUF array. |
1358 | | H5S_t *space; IN: Dataspace object containing selection to iterate over |
1359 | | H5D_operator_t op; IN: Function pointer to the routine to be |
1360 | | called for each element in BUF iterated over. |
1361 | | void *operator_data; IN/OUT: Pointer to any user-defined data |
1362 | | associated with the operation. |
1363 | | RETURNS |
1364 | | Returns the return value of the last operator if it was non-zero, or zero |
1365 | | if all elements were processed. Otherwise returns a negative value. |
1366 | | DESCRIPTION |
1367 | | Iterates over the selected elements in a memory buffer, calling the user's |
1368 | | callback function for each element. The selection in the dataspace is |
1369 | | modified so that any elements already iterated over are removed from the |
1370 | | selection if the iteration is interrupted (by the H5D_operator_t function |
1371 | | returning non-zero) in the "middle" of the iteration and may be re-started |
1372 | | by the user where it left off. |
1373 | | |
1374 | | NOTE: Until "subtracting" elements from a selection is implemented, |
1375 | | the selection is not modified. |
1376 | | --------------------------------------------------------------------------*/ |
1377 | | herr_t |
1378 | | H5S_select_iterate(void *buf, const H5T_t *type, H5S_t *space, const H5S_sel_iter_op_t *op, void *op_data) |
1379 | 7.72k | { |
1380 | 7.72k | H5S_sel_iter_t *iter = NULL; /* Selection iteration info */ |
1381 | 7.72k | bool iter_init = false; /* Selection iteration info has been initialized */ |
1382 | 7.72k | hsize_t *off = NULL; /* Array to store sequence offsets */ |
1383 | 7.72k | size_t *len = NULL; /* Array to store sequence lengths */ |
1384 | 7.72k | hssize_t nelmts; /* Number of elements in selection */ |
1385 | 7.72k | hsize_t space_size[H5S_MAX_RANK]; /* Dataspace size */ |
1386 | 7.72k | size_t max_elem; /* Maximum number of elements allowed in sequences */ |
1387 | 7.72k | size_t elmt_size; /* Datatype size */ |
1388 | 7.72k | unsigned ndims; /* Number of dimensions in dataspace */ |
1389 | 7.72k | herr_t user_ret = 0; /* User's return value */ |
1390 | 7.72k | herr_t ret_value = SUCCEED; /* Return value */ |
1391 | | |
1392 | 7.72k | FUNC_ENTER_NOAPI(FAIL) |
1393 | | |
1394 | | /* Check args */ |
1395 | 7.72k | assert(buf); |
1396 | 7.72k | assert(type); |
1397 | 7.72k | assert(space); |
1398 | 7.72k | assert(op); |
1399 | | |
1400 | | /* Get the datatype size */ |
1401 | 7.72k | if (0 == (elmt_size = H5T_get_size(type))) |
1402 | 0 | HGOTO_ERROR(H5E_DATATYPE, H5E_BADSIZE, FAIL, "datatype size invalid"); |
1403 | | |
1404 | | /* Allocate the selection iterator */ |
1405 | 7.72k | if (NULL == (iter = H5FL_MALLOC(H5S_sel_iter_t))) |
1406 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator"); |
1407 | | |
1408 | | /* Initialize iterator */ |
1409 | 7.72k | if (H5S_select_iter_init(iter, space, elmt_size, 0) < 0) |
1410 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator"); |
1411 | 7.72k | iter_init = true; /* Selection iteration info has been initialized */ |
1412 | | |
1413 | | /* Get the number of elements in selection */ |
1414 | 7.72k | if ((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0) |
1415 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected"); |
1416 | | |
1417 | | /* Get the rank of the dataspace */ |
1418 | 7.72k | ndims = space->extent.rank; |
1419 | | |
1420 | 7.72k | if (ndims > 0) { |
1421 | | /* Copy the size of the space */ |
1422 | 7.72k | assert(space->extent.size); |
1423 | 7.72k | H5MM_memcpy(space_size, space->extent.size, ndims * sizeof(hsize_t)); |
1424 | 7.72k | } /* end if */ |
1425 | 7.72k | space_size[ndims] = elmt_size; |
1426 | | |
1427 | | /* Compute the maximum number of bytes required */ |
1428 | 7.72k | H5_CHECKED_ASSIGN(max_elem, size_t, nelmts, hssize_t); |
1429 | | |
1430 | | /* Allocate the offset & length arrays */ |
1431 | 7.72k | if (NULL == (len = H5FL_SEQ_MALLOC(size_t, H5D_IO_VECTOR_SIZE))) |
1432 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate length vector array"); |
1433 | 7.72k | if (NULL == (off = H5FL_SEQ_MALLOC(hsize_t, H5D_IO_VECTOR_SIZE))) |
1434 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate offset vector array"); |
1435 | | |
1436 | | /* Loop, while elements left in selection */ |
1437 | 15.4k | while (max_elem > 0 && user_ret == 0) { |
1438 | 7.72k | size_t nelem; /* Number of elements used in sequences */ |
1439 | 7.72k | size_t nseq; /* Number of sequences generated */ |
1440 | 7.72k | size_t curr_seq; /* Current sequence being worked on */ |
1441 | | |
1442 | | /* Get the sequences of bytes */ |
1443 | 7.72k | if (H5S_SELECT_ITER_GET_SEQ_LIST(iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, |
1444 | 7.72k | len) < 0) |
1445 | 0 | HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed"); |
1446 | | |
1447 | | /* Loop, while sequences left to process */ |
1448 | 15.4k | for (curr_seq = 0; curr_seq < nseq && user_ret == 0; curr_seq++) { |
1449 | 7.72k | hsize_t curr_off; /* Current offset within sequence */ |
1450 | 7.72k | size_t curr_len; /* Length of bytes left to process in sequence */ |
1451 | | |
1452 | | /* Get the current offset */ |
1453 | 7.72k | curr_off = off[curr_seq]; |
1454 | | |
1455 | | /* Get the number of bytes in sequence */ |
1456 | 7.72k | curr_len = len[curr_seq]; |
1457 | | |
1458 | | /* Loop, while bytes left in sequence */ |
1459 | 46.6k | while (curr_len > 0 && user_ret == 0) { |
1460 | 38.9k | hsize_t coords[H5S_MAX_RANK]; /* Coordinates of element in dataspace */ |
1461 | 38.9k | hsize_t tmp_off; /* Temporary offset within sequence */ |
1462 | 38.9k | uint8_t *loc; /* Current element location in buffer */ |
1463 | 38.9k | int i; /* Local Index variable */ |
1464 | | |
1465 | | /* Compute the coordinate from the offset */ |
1466 | 116k | for (i = (int)ndims, tmp_off = curr_off; i >= 0; i--) { |
1467 | 77.9k | coords[i] = tmp_off % space_size[i]; |
1468 | 77.9k | tmp_off /= space_size[i]; |
1469 | 77.9k | } /* end for */ |
1470 | | |
1471 | | /* Get the location within the user's buffer */ |
1472 | 38.9k | loc = (unsigned char *)buf + curr_off; |
1473 | | |
1474 | | /* Check which type of callback to make */ |
1475 | 38.9k | switch (op->op_type) { |
1476 | 0 | case H5S_SEL_ITER_OP_APP: |
1477 | | /* Prepare & restore library for user callback */ |
1478 | 0 | H5_BEFORE_USER_CB(H5_ITER_ERROR) |
1479 | 0 | { |
1480 | | /* Make the application callback */ |
1481 | 0 | user_ret = |
1482 | 0 | (op->u.app_op.op)(loc, op->u.app_op.type_id, ndims, coords, op_data); |
1483 | 0 | } |
1484 | 0 | H5_AFTER_USER_CB(H5_ITER_ERROR) |
1485 | 0 | break; |
1486 | | |
1487 | 38.9k | case H5S_SEL_ITER_OP_LIB: |
1488 | | /* Call the library's callback */ |
1489 | 38.9k | user_ret = (op->u.lib_op)(loc, type, ndims, coords, op_data); |
1490 | 38.9k | break; |
1491 | | |
1492 | 0 | default: |
1493 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "unsupported op type"); |
1494 | 38.9k | } /* end switch */ |
1495 | | |
1496 | | /* Check for error return from iterator */ |
1497 | 38.9k | if (user_ret < 0) |
1498 | 0 | HERROR(H5E_DATASPACE, H5E_CANTNEXT, "iteration operator failed"); |
1499 | | |
1500 | | /* Increment offset in dataspace */ |
1501 | 38.9k | curr_off += elmt_size; |
1502 | | |
1503 | | /* Decrement number of bytes left in sequence */ |
1504 | 38.9k | curr_len -= elmt_size; |
1505 | 38.9k | } /* end while */ |
1506 | 7.72k | } /* end for */ |
1507 | | |
1508 | | /* Decrement number of elements left to process */ |
1509 | 7.72k | max_elem -= nelem; |
1510 | 7.72k | } /* end while */ |
1511 | | |
1512 | | /* Set return value */ |
1513 | 7.72k | ret_value = user_ret; |
1514 | | |
1515 | 7.72k | done: |
1516 | | /* Release resources, if allocated */ |
1517 | 7.72k | if (len) |
1518 | 7.72k | len = H5FL_SEQ_FREE(size_t, len); |
1519 | 7.72k | if (off) |
1520 | 7.72k | off = H5FL_SEQ_FREE(hsize_t, off); |
1521 | | |
1522 | | /* Release selection iterator */ |
1523 | 7.72k | if (iter_init && H5S_SELECT_ITER_RELEASE(iter) < 0) |
1524 | 0 | HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator"); |
1525 | 7.72k | if (iter) |
1526 | 7.72k | iter = H5FL_FREE(H5S_sel_iter_t, iter); |
1527 | | |
1528 | 7.72k | FUNC_LEAVE_NOAPI(ret_value) |
1529 | 7.72k | } /* end H5S_select_iterate() */ |
1530 | | |
1531 | | /*-------------------------------------------------------------------------- |
1532 | | NAME |
1533 | | H5Sget_select_type |
1534 | | PURPOSE |
1535 | | Retrieve the type of selection in a dataspace |
1536 | | USAGE |
1537 | | H5S_sel_type H5Sget_select_type(space_id) |
1538 | | hid_t space_id; IN: Dataspace object to query |
1539 | | RETURNS |
1540 | | Non-negative on success/Negative on failure. Return value is from the |
1541 | | set of values in the H5S_sel_type enumerated type. |
1542 | | DESCRIPTION |
1543 | | This function retrieves the type of selection currently defined for |
1544 | | a dataspace. |
1545 | | --------------------------------------------------------------------------*/ |
1546 | | H5S_sel_type |
1547 | | H5Sget_select_type(hid_t space_id) |
1548 | 0 | { |
1549 | 0 | H5S_t *space; /* dataspace to modify */ |
1550 | 0 | H5S_sel_type ret_value; /* Return value */ |
1551 | |
|
1552 | 0 | FUNC_ENTER_API(H5S_SEL_ERROR) |
1553 | | |
1554 | | /* Check args */ |
1555 | 0 | if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) |
1556 | 0 | HGOTO_ERROR(H5E_ID, H5E_BADID, H5S_SEL_ERROR, "not a dataspace"); |
1557 | | |
1558 | | /* Set return value */ |
1559 | 0 | ret_value = H5S_GET_SELECT_TYPE(space); |
1560 | |
|
1561 | 0 | done: |
1562 | 0 | FUNC_LEAVE_API(ret_value) |
1563 | 0 | } /* end H5Sget_select_type() */ |
1564 | | |
1565 | | /*-------------------------------------------------------------------------- |
1566 | | NAME |
1567 | | H5S_get_select_type |
1568 | | PURPOSE |
1569 | | Retrieve the type of selection in a dataspace |
1570 | | USAGE |
1571 | | H5S_sel_type H5Sget_select_type(space) |
1572 | | const H5S_t *space; IN: Dataspace object to query |
1573 | | RETURNS |
1574 | | Non-negative on success/Negative on failure. Return value is from the |
1575 | | set of values in the H5S_sel_type enumerated type. |
1576 | | DESCRIPTION |
1577 | | This function retrieves the type of selection currently defined for |
1578 | | a dataspace. |
1579 | | COMMENTS |
1580 | | This routine participates in the "Inlining C function pointers" |
1581 | | pattern, don't call it directly, use the appropriate macro |
1582 | | defined in H5Sprivate.h. |
1583 | | --------------------------------------------------------------------------*/ |
1584 | | H5_ATTR_PURE H5S_sel_type |
1585 | | H5S_get_select_type(const H5S_t *space) |
1586 | 0 | { |
1587 | 0 | H5S_sel_type ret_value = H5S_SEL_ERROR; /* Return value */ |
1588 | |
|
1589 | 0 | FUNC_ENTER_NOAPI_NOINIT_NOERR |
1590 | | |
1591 | | /* Check args */ |
1592 | 0 | assert(space); |
1593 | | |
1594 | | /* Set return value */ |
1595 | 0 | ret_value = H5S_GET_SELECT_TYPE(space); |
1596 | |
|
1597 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1598 | 0 | } /* end H5S_get_select_type() */ |
1599 | | |
1600 | | /*-------------------------------------------------------------------------- |
1601 | | NAME |
1602 | | H5S_select_shape_same |
1603 | | PURPOSE |
1604 | | Check if two selections are the same shape |
1605 | | USAGE |
1606 | | htri_t H5S_select_shape_same(space1, space2) |
1607 | | const H5S_t *space1; IN: 1st Dataspace pointer to compare |
1608 | | const H5S_t *space2; IN: 2nd Dataspace pointer to compare |
1609 | | RETURNS |
1610 | | true/false/FAIL |
1611 | | DESCRIPTION |
1612 | | Checks to see if the current selection in the dataspaces are the same |
1613 | | dimensionality and shape. |
1614 | | |
1615 | | This is primarily used for reading the entire selection in one swoop. |
1616 | | GLOBAL VARIABLES |
1617 | | COMMENTS, BUGS, ASSUMPTIONS |
1618 | | This routine participates in the "Inlining C function pointers" pattern, |
1619 | | don't call it directly, use the appropriate macro defined in H5Sprivate.h. |
1620 | | EXAMPLES |
1621 | | REVISION LOG |
1622 | | --------------------------------------------------------------------------*/ |
1623 | | htri_t |
1624 | | H5S_select_shape_same(H5S_t *space1, H5S_t *space2) |
1625 | 43.0k | { |
1626 | 43.0k | H5S_sel_iter_t *iter_a = NULL; /* Selection a iteration info */ |
1627 | 43.0k | H5S_sel_iter_t *iter_b = NULL; /* Selection b iteration info */ |
1628 | 43.0k | bool iter_a_init = false; /* Selection a iteration info has been initialized */ |
1629 | 43.0k | bool iter_b_init = false; /* Selection b iteration info has been initialized */ |
1630 | 43.0k | htri_t ret_value = true; /* Return value */ |
1631 | | |
1632 | 43.0k | FUNC_ENTER_NOAPI(FAIL) |
1633 | | |
1634 | | /* Check args */ |
1635 | 43.0k | assert(space1); |
1636 | 43.0k | assert(space2); |
1637 | | |
1638 | | /* Check for different number of elements selected */ |
1639 | 43.0k | if (H5S_GET_SELECT_NPOINTS(space1) != H5S_GET_SELECT_NPOINTS(space2)) |
1640 | 0 | HGOTO_DONE(false); |
1641 | | |
1642 | | /* Check special cases if both dataspaces aren't scalar */ |
1643 | | /* (If only one is, the number of selected points check is sufficient) */ |
1644 | 43.0k | if (space1->extent.rank > 0 && space2->extent.rank > 0) { |
1645 | 43.0k | H5S_t *space_a; /* Dataspace with larger rank */ |
1646 | 43.0k | H5S_t *space_b; /* Dataspace with smaller rank */ |
1647 | 43.0k | unsigned space_a_rank; /* Number of dimensions of dataspace A */ |
1648 | 43.0k | unsigned space_b_rank; /* Number of dimensions of dataspace B */ |
1649 | 43.0k | int space_a_dim; /* Current dimension in dataspace A */ |
1650 | 43.0k | int space_b_dim; /* Current dimension in dataspace B */ |
1651 | 43.0k | H5S_sel_type sel_a_type; /* Selection type for dataspace A */ |
1652 | 43.0k | H5S_sel_type sel_b_type; /* Selection type for dataspace B */ |
1653 | | |
1654 | | /* Need to be able to handle spaces of different rank: |
1655 | | * |
1656 | | * To simplify logic, let space_a point to the element of the set |
1657 | | * {space1, space2} with the largest rank or space1 if the ranks |
1658 | | * are identical. |
1659 | | * |
1660 | | * Similarly, let space_b point to the element of {space1, space2} |
1661 | | * with the smallest rank, or space2 if they are identical. |
1662 | | * |
1663 | | * Let: space_a_rank be the rank of space_a, |
1664 | | * space_b_rank be the rank of space_b, |
1665 | | * |
1666 | | * Set all this up here. |
1667 | | */ |
1668 | 43.0k | if (space1->extent.rank >= space2->extent.rank) { |
1669 | 28.4k | space_a = space1; |
1670 | 28.4k | space_b = space2; |
1671 | 28.4k | } /* end if */ |
1672 | 14.6k | else { |
1673 | 14.6k | space_a = space2; |
1674 | 14.6k | space_b = space1; |
1675 | 14.6k | } /* end else */ |
1676 | 43.0k | space_a_rank = space_a->extent.rank; |
1677 | 43.0k | space_b_rank = space_b->extent.rank; |
1678 | 43.0k | assert(space_a_rank >= space_b_rank); |
1679 | 43.0k | assert(space_b_rank > 0); |
1680 | | |
1681 | | /* Get selection type for both dataspaces */ |
1682 | 43.0k | sel_a_type = H5S_GET_SELECT_TYPE(space_a); |
1683 | 43.0k | sel_b_type = H5S_GET_SELECT_TYPE(space_b); |
1684 | | |
1685 | | /* If selections aren't "none", compare their bounds */ |
1686 | 43.0k | if (sel_a_type != H5S_SEL_NONE && sel_b_type != H5S_SEL_NONE) { |
1687 | 43.0k | hsize_t low_a[H5S_MAX_RANK]; /* Low bound of selection in dataspace a */ |
1688 | 43.0k | hsize_t low_b[H5S_MAX_RANK]; /* Low bound of selection in dataspace b */ |
1689 | 43.0k | hsize_t high_a[H5S_MAX_RANK]; /* High bound of selection in dataspace a */ |
1690 | 43.0k | hsize_t high_b[H5S_MAX_RANK]; /* High bound of selection in dataspace b */ |
1691 | | |
1692 | | /* Get low & high bounds for both dataspaces */ |
1693 | 43.0k | if (H5S_SELECT_BOUNDS(space_a, low_a, high_a) < 0) |
1694 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, |
1695 | 43.0k | "can't get selection bounds for first dataspace"); |
1696 | 43.0k | if (H5S_SELECT_BOUNDS(space_b, low_b, high_b) < 0) |
1697 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, |
1698 | 43.0k | "can't get selection bounds for second dataspace"); |
1699 | | |
1700 | | /* Check that the range between the low & high bounds are the same */ |
1701 | 43.0k | space_a_dim = (int)space_a_rank - 1; |
1702 | 43.0k | space_b_dim = (int)space_b_rank - 1; |
1703 | 48.6k | while (space_b_dim >= 0) { |
1704 | | /* Sanity check */ |
1705 | 44.3k | assert(low_a[space_a_dim] <= high_a[space_a_dim]); |
1706 | 44.3k | assert(low_a[space_b_dim] <= high_a[space_b_dim]); |
1707 | | |
1708 | | /* Verify that the ranges are the same */ |
1709 | 44.3k | if ((high_a[space_a_dim] - low_a[space_a_dim]) != (high_b[space_b_dim] - low_b[space_b_dim])) |
1710 | 38.7k | HGOTO_DONE(false); |
1711 | | |
1712 | | /* Go to next dimension */ |
1713 | 5.59k | space_a_dim--; |
1714 | 5.59k | space_b_dim--; |
1715 | 5.59k | } /* end while */ |
1716 | | |
1717 | | /* Check that the rest of the ranges in space a are "flat" */ |
1718 | 5.02k | while (space_a_dim >= 0) { |
1719 | | /* Sanity check */ |
1720 | 780 | assert(low_a[space_a_dim] <= high_a[space_a_dim]); |
1721 | | |
1722 | | /* This range should be flat to be the same in a lower dimension */ |
1723 | 780 | if (low_a[space_a_dim] != high_a[space_a_dim]) |
1724 | 85 | HGOTO_DONE(false); |
1725 | | |
1726 | 695 | space_a_dim--; |
1727 | 695 | } /* end while */ |
1728 | | |
1729 | | /* Check for a single block in each selection */ |
1730 | 4.24k | if (H5S_SELECT_IS_SINGLE(space_a) && H5S_SELECT_IS_SINGLE(space_b)) { |
1731 | | /* If both selections are a single block and their bounds are |
1732 | | * the same, then the selections are the same, even if the |
1733 | | * selection types are different. |
1734 | | */ |
1735 | 3.91k | HGOTO_DONE(true); |
1736 | 3.91k | } /* end if */ |
1737 | 4.24k | } /* end if */ |
1738 | | |
1739 | | /* If the dataspaces have the same selection type, use the selection's |
1740 | | * shape_same operator. |
1741 | | */ |
1742 | 324 | if (sel_a_type == sel_b_type) |
1743 | 0 | ret_value = (*space_a->select.type->shape_same)(space_a, space_b); |
1744 | | /* Otherwise, iterate through all the blocks in the selection */ |
1745 | 324 | else { |
1746 | 324 | hsize_t start_a[H5S_MAX_RANK]; /* Start point of selection block in dataspace a */ |
1747 | 324 | hsize_t start_b[H5S_MAX_RANK]; /* Start point of selection block in dataspace b */ |
1748 | 324 | hsize_t end_a[H5S_MAX_RANK]; /* End point of selection block in dataspace a */ |
1749 | 324 | hsize_t end_b[H5S_MAX_RANK]; /* End point of selection block in dataspace b */ |
1750 | 324 | hssize_t offset[H5S_MAX_RANK]; /* Offset of selection b blocks relative to selection a blocks */ |
1751 | 324 | bool first_block = true; /* Flag to indicate the first block */ |
1752 | | |
1753 | | /* Allocate the selection iterators */ |
1754 | 324 | if (NULL == (iter_a = H5FL_MALLOC(H5S_sel_iter_t))) |
1755 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator"); |
1756 | 324 | if (NULL == (iter_b = H5FL_MALLOC(H5S_sel_iter_t))) |
1757 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator"); |
1758 | | |
1759 | | /* Initialize iterator for each dataspace selection |
1760 | | * Use '0' for element size instead of actual element size to indicate |
1761 | | * that the selection iterator shouldn't be "flattened", since we |
1762 | | * aren't actually going to be doing I/O with the iterators. |
1763 | | */ |
1764 | 324 | if (H5S_select_iter_init(iter_a, space_a, (size_t)0, 0) < 0) |
1765 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator a"); |
1766 | 324 | iter_a_init = true; |
1767 | 324 | if (H5S_select_iter_init(iter_b, space_b, (size_t)0, 0) < 0) |
1768 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator b"); |
1769 | 324 | iter_b_init = true; |
1770 | | |
1771 | | /* Iterate over all the blocks in each selection */ |
1772 | 324 | while (1) { |
1773 | 324 | htri_t status_a, status_b; /* Status from next block checks */ |
1774 | | |
1775 | | /* Get the current block for each selection iterator */ |
1776 | 324 | if (H5S_SELECT_ITER_BLOCK(iter_a, start_a, end_a) < 0) |
1777 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator block a"); |
1778 | 324 | if (H5S_SELECT_ITER_BLOCK(iter_b, start_b, end_b) < 0) |
1779 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get iterator block b"); |
1780 | | |
1781 | 324 | space_a_dim = (int)space_a_rank - 1; |
1782 | 324 | space_b_dim = (int)space_b_rank - 1; |
1783 | | |
1784 | | /* The first block only compares the sizes and sets the |
1785 | | * relative offsets for later blocks |
1786 | | */ |
1787 | 324 | if (first_block) { |
1788 | | /* If the block sizes in the common dimensions from |
1789 | | * each selection don't match, get out |
1790 | | */ |
1791 | 324 | while (space_b_dim >= 0) { |
1792 | 324 | if ((end_a[space_a_dim] - start_a[space_a_dim]) != |
1793 | 324 | (end_b[space_b_dim] - start_b[space_b_dim])) |
1794 | 324 | HGOTO_DONE(false); |
1795 | | |
1796 | | /* Set the relative locations of the selections */ |
1797 | 0 | offset[space_a_dim] = (hssize_t)start_b[space_b_dim] - (hssize_t)start_a[space_a_dim]; |
1798 | |
|
1799 | 0 | space_a_dim--; |
1800 | 0 | space_b_dim--; |
1801 | 0 | } /* end while */ |
1802 | | |
1803 | | /* Similarly, if the block size in any dimension that appears only |
1804 | | * in space_a is not equal to 1, get out. |
1805 | | */ |
1806 | 0 | while (space_a_dim >= 0) { |
1807 | 0 | if (start_a[space_a_dim] != end_a[space_a_dim]) |
1808 | 0 | HGOTO_DONE(false); |
1809 | | |
1810 | 0 | space_a_dim--; |
1811 | 0 | } /* end while */ |
1812 | | |
1813 | | /* Reset "first block" flag */ |
1814 | 0 | first_block = false; |
1815 | 0 | } /* end if */ |
1816 | | /* Check over the blocks for each selection */ |
1817 | 0 | else { |
1818 | | /* For dimensions that space_a and space_b have in common: */ |
1819 | 0 | while (space_b_dim >= 0) { |
1820 | | /* Check if the blocks are in the same relative location */ |
1821 | 0 | if ((hsize_t)((hssize_t)start_a[space_a_dim] + offset[space_a_dim]) != |
1822 | 0 | start_b[space_b_dim]) |
1823 | 0 | HGOTO_DONE(false); |
1824 | | |
1825 | | /* If the block sizes from each selection doesn't match, get out */ |
1826 | 0 | if ((end_a[space_a_dim] - start_a[space_a_dim]) != |
1827 | 0 | (end_b[space_b_dim] - start_b[space_b_dim])) |
1828 | 0 | HGOTO_DONE(false); |
1829 | | |
1830 | 0 | space_a_dim--; |
1831 | 0 | space_b_dim--; |
1832 | 0 | } /* end while */ |
1833 | | |
1834 | | /* For dimensions that appear only in space_a: */ |
1835 | 0 | while (space_a_dim >= 0) { |
1836 | | /* If the block size isn't 1, get out */ |
1837 | 0 | if (start_a[space_a_dim] != end_a[space_a_dim]) |
1838 | 0 | HGOTO_DONE(false); |
1839 | | |
1840 | 0 | space_a_dim--; |
1841 | 0 | } /* end while */ |
1842 | 0 | } /* end else */ |
1843 | | |
1844 | | /* Check if we are able to advance to the next selection block */ |
1845 | 0 | if ((status_a = H5S_SELECT_ITER_HAS_NEXT_BLOCK(iter_a)) < 0) |
1846 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block a"); |
1847 | | |
1848 | 0 | if ((status_b = H5S_SELECT_ITER_HAS_NEXT_BLOCK(iter_b)) < 0) |
1849 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "unable to check iterator block b"); |
1850 | | |
1851 | | /* Did we run out of blocks at the same time? */ |
1852 | 0 | if ((status_a == false) && (status_b == false)) |
1853 | 0 | break; |
1854 | 0 | else if (status_a != status_b) |
1855 | 0 | HGOTO_DONE(false); |
1856 | 0 | else { |
1857 | | /* Advance to next block in selection iterators */ |
1858 | 0 | if (H5S_SELECT_ITER_NEXT_BLOCK(iter_a) < 0) |
1859 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, |
1860 | 0 | "unable to advance to next iterator block a"); |
1861 | | |
1862 | 0 | if (H5S_SELECT_ITER_NEXT_BLOCK(iter_b) < 0) |
1863 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, |
1864 | 0 | "unable to advance to next iterator block b"); |
1865 | 0 | } /* end else */ |
1866 | 0 | } /* end while */ |
1867 | 324 | } /* end else */ |
1868 | 324 | } /* end if */ |
1869 | | |
1870 | 43.0k | done: |
1871 | 43.0k | if (iter_a_init && H5S_SELECT_ITER_RELEASE(iter_a) < 0) |
1872 | 0 | HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator a"); |
1873 | 43.0k | if (iter_a) |
1874 | 324 | iter_a = H5FL_FREE(H5S_sel_iter_t, iter_a); |
1875 | 43.0k | if (iter_b_init && H5S_SELECT_ITER_RELEASE(iter_b) < 0) |
1876 | 0 | HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator b"); |
1877 | 43.0k | if (iter_b) |
1878 | 324 | iter_b = H5FL_FREE(H5S_sel_iter_t, iter_b); |
1879 | | |
1880 | 43.0k | FUNC_LEAVE_NOAPI(ret_value) |
1881 | 43.0k | } /* end H5S_select_shape_same() */ |
1882 | | |
1883 | | /*-------------------------------------------------------------------------- |
1884 | | NAME |
1885 | | H5Sselect_shape_same |
1886 | | PURPOSE |
1887 | | Check if two selections are the same shape |
1888 | | USAGE |
1889 | | htri_t H5Sselect_shape_same(space1_id, space2_id) |
1890 | | hid_t space1_id; IN: ID of 1st Dataspace pointer to compare |
1891 | | hid_t space2_id; IN: ID of 2nd Dataspace pointer to compare |
1892 | | RETURNS |
1893 | | true/false/FAIL |
1894 | | DESCRIPTION |
1895 | | Checks to see if the current selection in the dataspaces are the same |
1896 | | dimensionality and shape. |
1897 | | This is primarily used for reading the entire selection in one swoop. |
1898 | | GLOBAL VARIABLES |
1899 | | COMMENTS, BUGS, ASSUMPTIONS |
1900 | | EXAMPLES |
1901 | | REVISION LOG |
1902 | | --------------------------------------------------------------------------*/ |
1903 | | htri_t |
1904 | | H5Sselect_shape_same(hid_t space1_id, hid_t space2_id) |
1905 | 0 | { |
1906 | 0 | H5S_t *space1, *space2; /* Dataspaces to compare */ |
1907 | 0 | htri_t ret_value; /* Return value */ |
1908 | |
|
1909 | 0 | FUNC_ENTER_API(FAIL) |
1910 | |
|
1911 | 0 | if (NULL == (space1 = (H5S_t *)H5I_object_verify(space1_id, H5I_DATASPACE))) |
1912 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace"); |
1913 | 0 | if (NULL == (space2 = (H5S_t *)H5I_object_verify(space2_id, H5I_DATASPACE))) |
1914 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace"); |
1915 | | |
1916 | 0 | if ((ret_value = H5S_select_shape_same(space1, space2)) < 0) |
1917 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't compare selections"); |
1918 | | |
1919 | 0 | done: |
1920 | 0 | FUNC_LEAVE_API(ret_value) |
1921 | 0 | } /* end H5Sselect_shape_same() */ |
1922 | | |
1923 | | /*-------------------------------------------------------------------------- |
1924 | | NAME |
1925 | | H5S_select_intersect_block |
1926 | | PURPOSE |
1927 | | Check if current selection intersects with a block |
1928 | | USAGE |
1929 | | htri_t H5S_select_intersect_block(space, start, end) |
1930 | | const H5S_t *space; IN: Dataspace to compare |
1931 | | const hsize_t *start; IN: Starting coordinate of block |
1932 | | const hsize_t *end; IN: Opposite ("ending") coordinate of block |
1933 | | RETURNS |
1934 | | true / false / FAIL |
1935 | | DESCRIPTION |
1936 | | Checks to see if the current selection in the dataspace intersects with |
1937 | | the block given. |
1938 | | GLOBAL VARIABLES |
1939 | | COMMENTS, BUGS, ASSUMPTIONS |
1940 | | Assumes that start & end block bounds are _inclusive_, so start == end |
1941 | | value OK. |
1942 | | |
1943 | | This routine participates in the "Inlining C function pointers" pattern, |
1944 | | don't call it directly, use the appropriate macro defined in H5Sprivate.h. |
1945 | | --------------------------------------------------------------------------*/ |
1946 | | htri_t |
1947 | | H5S_select_intersect_block(H5S_t *space, const hsize_t *start, const hsize_t *end) |
1948 | 0 | { |
1949 | 0 | htri_t ret_value = true; /* Return value */ |
1950 | |
|
1951 | 0 | FUNC_ENTER_NOAPI(FAIL) |
1952 | | |
1953 | | /* Check args */ |
1954 | 0 | assert(space); |
1955 | 0 | assert(start); |
1956 | 0 | assert(end); |
1957 | | |
1958 | | /* If selections aren't "none", compare their bounds */ |
1959 | 0 | if (H5S_SEL_NONE != H5S_GET_SELECT_TYPE(space)) { |
1960 | 0 | hsize_t low[H5S_MAX_RANK]; /* Low bound of selection in dataspace */ |
1961 | 0 | hsize_t high[H5S_MAX_RANK]; /* High bound of selection in dataspace */ |
1962 | 0 | unsigned u; /* Local index variable */ |
1963 | | |
1964 | | /* Get low & high bounds for dataspace selection */ |
1965 | 0 | if (H5S_SELECT_BOUNDS(space, low, high) < 0) |
1966 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get selection bounds for dataspace"); |
1967 | | |
1968 | | /* Loop over selection bounds and block, checking for overlap */ |
1969 | 0 | for (u = 0; u < space->extent.rank; u++) |
1970 | | /* If selection bounds & block don't overlap, can leave now */ |
1971 | 0 | if (!H5_RANGE_OVERLAP(low[u], high[u], start[u], end[u])) |
1972 | 0 | HGOTO_DONE(false); |
1973 | 0 | } /* end if */ |
1974 | | |
1975 | | /* Call selection type's intersect routine */ |
1976 | 0 | if ((ret_value = (*space->select.type->intersect_block)(space, start, end)) < 0) |
1977 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't intersect block with selection"); |
1978 | | |
1979 | 0 | done: |
1980 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
1981 | 0 | } /* end H5S_select_intersect_block() */ |
1982 | | |
1983 | | /*-------------------------------------------------------------------------- |
1984 | | NAME |
1985 | | H5Sselect_intersect_block |
1986 | | PURPOSE |
1987 | | Check if current selection intersects with a block |
1988 | | USAGE |
1989 | | htri_t H5Sselect_intersect_block(space_id, start, end) |
1990 | | hid_t space1_id; IN: ID of dataspace pointer to compare |
1991 | | const hsize_t *start; IN: Starting coordinate of block |
1992 | | const hsize_t *end; IN: Opposite ("ending") coordinate of block |
1993 | | RETURNS |
1994 | | true / false / FAIL |
1995 | | DESCRIPTION |
1996 | | Checks to see if the current selection in the dataspace intersects with |
1997 | | the block given. |
1998 | | GLOBAL VARIABLES |
1999 | | COMMENTS, BUGS, ASSUMPTIONS |
2000 | | Assumes that start & end block bounds are _inclusive_, so start == end |
2001 | | value OK. |
2002 | | EXAMPLES |
2003 | | REVISION LOG |
2004 | | --------------------------------------------------------------------------*/ |
2005 | | htri_t |
2006 | | H5Sselect_intersect_block(hid_t space_id, const hsize_t *start, const hsize_t *end) |
2007 | 0 | { |
2008 | 0 | H5S_t *space; /* Dataspace to query */ |
2009 | 0 | unsigned u; /* Local index value */ |
2010 | 0 | htri_t ret_value = FAIL; /* Return value */ |
2011 | |
|
2012 | 0 | FUNC_ENTER_API(FAIL) |
2013 | | |
2014 | | /* Check arguments */ |
2015 | 0 | if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) |
2016 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace"); |
2017 | 0 | if (NULL == start) |
2018 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "block start array pointer is NULL"); |
2019 | 0 | if (NULL == end) |
2020 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "block end array pointer is NULL"); |
2021 | | |
2022 | | /* Range check start & end values */ |
2023 | 0 | for (u = 0; u < space->extent.rank; u++) |
2024 | 0 | if (start[u] > end[u]) |
2025 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "block start[%u] (%llu) > end[%u] (%llu)", u, |
2026 | 0 | (unsigned long long)start[u], u, (unsigned long long)end[u]); |
2027 | | |
2028 | | /* Call internal routine to do comparison */ |
2029 | 0 | if ((ret_value = H5S_select_intersect_block(space, start, end)) < 0) |
2030 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't compare selection and block"); |
2031 | | |
2032 | 0 | done: |
2033 | 0 | FUNC_LEAVE_API(ret_value) |
2034 | 0 | } /* end H5Sselect_intersect_block() */ |
2035 | | |
2036 | | /*-------------------------------------------------------------------------- |
2037 | | NAME |
2038 | | H5S_select_construct_projection |
2039 | | |
2040 | | PURPOSE |
2041 | | Given a dataspace a of rank n with some selection, construct a new |
2042 | | dataspace b of rank m (m != n), with the selection in a being |
2043 | | topologically identical to that in b (as verified by |
2044 | | H5S_select_shape_same(). |
2045 | | |
2046 | | This function exists, as some I/O code chokes on topologically |
2047 | | identical selections with different ranks. At least to begin |
2048 | | with, we will deal with the issue by constructing projections |
2049 | | of the memory dataspace with ranks equaling those of the file |
2050 | | dataspace. |
2051 | | |
2052 | | Note that if m > n, it is possible that the starting point in the |
2053 | | buffer associated with the memory dataspace will have to be |
2054 | | adjusted to match the projected dataspace. In this case, the amount |
2055 | | of adjustment to be applied to the buffer will be returned via the |
2056 | | buf_adj parameter, if supplied. |
2057 | | |
2058 | | USAGE |
2059 | | htri_t H5S_select_construct_projection(base_space, |
2060 | | new_space_ptr, |
2061 | | new_space_rank, |
2062 | | element_size, |
2063 | | buf_adj) |
2064 | | const H5S_t *base_space; IN: Ptr to Dataspace to project |
2065 | | H5S_t ** new_space_ptr; OUT: Ptr to location in which to return |
2066 | | the address of the projected space |
2067 | | int new_space_rank; IN: Rank of the projected space. |
2068 | | hsize_t element_size; IN: size of each element in the selection |
2069 | | ptrdiff_t buf_adj; OUT: amount of adjustment to be applied |
2070 | | to buffer associated with memory |
2071 | | dataspace |
2072 | | |
2073 | | RETURNS |
2074 | | Non-negative on success/Negative on failure. |
2075 | | |
2076 | | DESCRIPTION |
2077 | | Construct a new dataspace and associated selection which is a |
2078 | | projection of the supplied dataspace and associated selection into |
2079 | | the specified rank. Return it in *new_space_ptr. |
2080 | | |
2081 | | GLOBAL VARIABLES |
2082 | | COMMENTS, BUGS, ASSUMPTIONS |
2083 | | The selection in the supplied base_space has thickness 1 in all |
2084 | | dimensions greater than new_space_rank. Note that here we count |
2085 | | dimensions from the fastest changing coordinate to the slowest |
2086 | | changing changing coordinate. |
2087 | | EXAMPLES |
2088 | | REVISION LOG |
2089 | | --------------------------------------------------------------------------*/ |
2090 | | herr_t |
2091 | | H5S_select_construct_projection(H5S_t *base_space, H5S_t **new_space_ptr, unsigned new_space_rank, |
2092 | | hsize_t element_size, ptrdiff_t *buf_adj) |
2093 | 398 | { |
2094 | 398 | H5S_t *new_space = NULL; /* New dataspace constructed */ |
2095 | 398 | hsize_t base_space_dims[H5S_MAX_RANK]; /* Current dimensions of base dataspace */ |
2096 | 398 | hsize_t base_space_maxdims[H5S_MAX_RANK]; /* Maximum dimensions of base dataspace */ |
2097 | 398 | int sbase_space_rank; /* Signed # of dimensions of base dataspace */ |
2098 | 398 | unsigned base_space_rank; /* # of dimensions of base dataspace */ |
2099 | 398 | hsize_t projected_space_element_offset = 0; /* Offset of selected element in projected buffer */ |
2100 | 398 | herr_t ret_value = SUCCEED; /* Return value */ |
2101 | | |
2102 | 398 | FUNC_ENTER_NOAPI(FAIL) |
2103 | | |
2104 | | /* Sanity checks */ |
2105 | 398 | assert(base_space != NULL); |
2106 | 398 | assert((H5S_GET_EXTENT_TYPE(base_space) == H5S_SCALAR) || |
2107 | 398 | (H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE)); |
2108 | 398 | assert(new_space_ptr != NULL); |
2109 | 398 | assert((new_space_rank != 0) || (H5S_GET_SELECT_NPOINTS(base_space) <= 1)); |
2110 | 398 | assert(new_space_rank <= H5S_MAX_RANK); |
2111 | 398 | assert(element_size > 0); |
2112 | | |
2113 | | /* Get the extent info for the base dataspace */ |
2114 | 398 | if ((sbase_space_rank = H5S_get_simple_extent_dims(base_space, base_space_dims, base_space_maxdims)) < 0) |
2115 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get dimensionality of base space"); |
2116 | 398 | base_space_rank = (unsigned)sbase_space_rank; |
2117 | 398 | assert(base_space_rank != new_space_rank); |
2118 | | |
2119 | | /* Check if projected space is scalar */ |
2120 | 398 | if (new_space_rank == 0) { |
2121 | 24 | hssize_t npoints; /* Number of points selected */ |
2122 | | |
2123 | | /* Retrieve the number of elements selected */ |
2124 | 24 | if ((npoints = (hssize_t)H5S_GET_SELECT_NPOINTS(base_space)) < 0) |
2125 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "unable to get number of points selected"); |
2126 | 24 | assert(npoints <= 1); |
2127 | | |
2128 | | /* Create new scalar dataspace */ |
2129 | 24 | if (NULL == (new_space = H5S_create(H5S_SCALAR))) |
2130 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create scalar dataspace"); |
2131 | | |
2132 | | /* No need to register the dataspace(i.e. get an ID) as |
2133 | | * we will just be discarding it shortly. |
2134 | | */ |
2135 | | |
2136 | | /* Selection for the new space will be either all or |
2137 | | * none, depending on whether the base space has 0 or |
2138 | | * 1 elements selected. |
2139 | | * |
2140 | | * Observe that the base space can't have more than |
2141 | | * one selected element, since its selection has the |
2142 | | * same shape as the file dataspace, and that data |
2143 | | * space is scalar. |
2144 | | */ |
2145 | 24 | if (1 == npoints) { |
2146 | | /* Assuming that the selection in the base dataspace is not |
2147 | | * empty, we must compute the offset of the selected item in |
2148 | | * the buffer associated with the base dataspace. |
2149 | | * |
2150 | | * Since the new space rank is zero, we know that the |
2151 | | * the base space must have rank at least 1 -- and |
2152 | | * hence it is a simple dataspace. However, the |
2153 | | * selection, may be either point, hyperspace, or all. |
2154 | | * |
2155 | | */ |
2156 | 24 | if (H5S_SELECT_PROJECT_SCALAR(base_space, &projected_space_element_offset) < 0) |
2157 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to project scalar selection"); |
2158 | 24 | } /* end if */ |
2159 | 0 | else { |
2160 | 0 | assert(0 == npoints); |
2161 | |
|
2162 | 0 | if (H5S_select_none(new_space) < 0) |
2163 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't delete default selection"); |
2164 | 0 | } /* end else */ |
2165 | 24 | } /* end if */ |
2166 | 374 | else { /* projected space must be simple */ |
2167 | 374 | hsize_t new_space_dims[H5S_MAX_RANK]; /* Current dimensions for new dataspace */ |
2168 | 374 | hsize_t new_space_maxdims[H5S_MAX_RANK]; /* Maximum dimensions for new dataspace */ |
2169 | 374 | unsigned rank_diff; /* Difference in ranks */ |
2170 | | |
2171 | | /* Set up the dimensions of the new, projected dataspace. |
2172 | | * |
2173 | | * How we do this depends on whether we are projecting up into |
2174 | | * increased dimensions, or down into a reduced number of |
2175 | | * dimensions. |
2176 | | * |
2177 | | * If we are projecting up (the first half of the following |
2178 | | * if statement), we copy the dimensions of the base data |
2179 | | * space into the fastest changing dimensions of the new |
2180 | | * projected dataspace, and set the remaining dimensions to |
2181 | | * one. |
2182 | | * |
2183 | | * If we are projecting down (the second half of the following |
2184 | | * if statement), we just copy the dimensions with the most |
2185 | | * quickly changing dimensions into the dims for the projected |
2186 | | * data set. |
2187 | | * |
2188 | | * This works, because H5S_select_shape_same() will return |
2189 | | * true on selections of different rank iff: |
2190 | | * |
2191 | | * 1) the selection in the lower rank dataspace matches that |
2192 | | * in the dimensions with the fastest changing indices in |
2193 | | * the larger rank dataspace, and |
2194 | | * |
2195 | | * 2) the selection has thickness 1 in all ranks that appear |
2196 | | * only in the higher rank dataspace (i.e. those with |
2197 | | * more slowly changing indices). |
2198 | | */ |
2199 | 374 | if (new_space_rank > base_space_rank) { |
2200 | 374 | hsize_t tmp_dim_size = 1; /* Temporary dimension value, for filling arrays */ |
2201 | | |
2202 | | /* we must copy the dimensions of the base space into |
2203 | | * the fastest changing dimensions of the new space, |
2204 | | * and set the remaining dimensions to 1 |
2205 | | */ |
2206 | 374 | rank_diff = new_space_rank - base_space_rank; |
2207 | 374 | H5VM_array_fill(new_space_dims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff); |
2208 | 374 | H5VM_array_fill(new_space_maxdims, &tmp_dim_size, sizeof(tmp_dim_size), rank_diff); |
2209 | 374 | H5MM_memcpy(&new_space_dims[rank_diff], base_space_dims, |
2210 | 374 | sizeof(new_space_dims[0]) * base_space_rank); |
2211 | 374 | H5MM_memcpy(&new_space_maxdims[rank_diff], base_space_maxdims, |
2212 | 374 | sizeof(new_space_maxdims[0]) * base_space_rank); |
2213 | 374 | } /* end if */ |
2214 | 0 | else { /* new_space_rank < base_space_rank */ |
2215 | | /* we must copy the fastest changing dimension of the |
2216 | | * base space into the dimensions of the new space. |
2217 | | */ |
2218 | 0 | rank_diff = base_space_rank - new_space_rank; |
2219 | 0 | H5MM_memcpy(new_space_dims, &base_space_dims[rank_diff], |
2220 | 0 | sizeof(new_space_dims[0]) * new_space_rank); |
2221 | 0 | H5MM_memcpy(new_space_maxdims, &base_space_maxdims[rank_diff], |
2222 | 0 | sizeof(new_space_maxdims[0]) * new_space_rank); |
2223 | 0 | } /* end else */ |
2224 | | |
2225 | | /* now have the new space rank and dimensions set up -- |
2226 | | * so we can create the new simple dataspace. |
2227 | | */ |
2228 | 374 | if (NULL == (new_space = H5S_create_simple(new_space_rank, new_space_dims, new_space_maxdims))) |
2229 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace"); |
2230 | | |
2231 | | /* No need to register the dataspace(i.e. get an ID) as |
2232 | | * we will just be discarding it shortly. |
2233 | | */ |
2234 | | |
2235 | | /* If we get this far, we have successfully created the projected |
2236 | | * dataspace. We must now project the selection in the base |
2237 | | * dataspace into the projected dataspace. |
2238 | | */ |
2239 | 374 | if (H5S_SELECT_PROJECT_SIMPLE(base_space, new_space, &projected_space_element_offset) < 0) |
2240 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to project simple selection"); |
2241 | | |
2242 | | /* If we get this far, we have created the new dataspace, and projected |
2243 | | * the selection in the base dataspace into the new dataspace. |
2244 | | * |
2245 | | * If the base dataspace is simple, check to see if the |
2246 | | * offset_changed flag on the base selection has been set -- if so, |
2247 | | * project the offset into the new dataspace and set the |
2248 | | * offset_changed flag. |
2249 | | */ |
2250 | 374 | if (H5S_GET_EXTENT_TYPE(base_space) == H5S_SIMPLE && base_space->select.offset_changed) { |
2251 | 0 | if (new_space_rank > base_space_rank) { |
2252 | 0 | memset(new_space->select.offset, 0, sizeof(new_space->select.offset[0]) * rank_diff); |
2253 | 0 | H5MM_memcpy(&new_space->select.offset[rank_diff], base_space->select.offset, |
2254 | 0 | sizeof(new_space->select.offset[0]) * base_space_rank); |
2255 | 0 | } /* end if */ |
2256 | 0 | else |
2257 | 0 | H5MM_memcpy(new_space->select.offset, &base_space->select.offset[rank_diff], |
2258 | 0 | sizeof(new_space->select.offset[0]) * new_space_rank); |
2259 | | |
2260 | | /* Propagate the offset changed flag into the new dataspace. */ |
2261 | 0 | new_space->select.offset_changed = true; |
2262 | 0 | } /* end if */ |
2263 | 374 | } /* end else */ |
2264 | | |
2265 | | /* If we have done the projection correctly, the following assertion |
2266 | | * should hold. |
2267 | | */ |
2268 | 398 | assert(true == H5S_select_shape_same(base_space, new_space)); |
2269 | | |
2270 | | /* load the address of the new space into *new_space_ptr */ |
2271 | 398 | *new_space_ptr = new_space; |
2272 | | |
2273 | | /* return the buffer adjustment amount if required */ |
2274 | 398 | if (buf_adj != NULL) { |
2275 | 398 | if (new_space_rank < base_space_rank) { |
2276 | 24 | *buf_adj = (ptrdiff_t)(projected_space_element_offset * element_size); |
2277 | 24 | } |
2278 | 374 | else |
2279 | | /* No adjustment necessary */ |
2280 | 374 | *buf_adj = 0; |
2281 | 398 | } |
2282 | | |
2283 | 398 | done: |
2284 | | /* Cleanup on error */ |
2285 | 398 | if (ret_value < 0) |
2286 | 0 | if (new_space && H5S_close(new_space) < 0) |
2287 | 0 | HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace"); |
2288 | | |
2289 | 398 | FUNC_LEAVE_NOAPI(ret_value) |
2290 | 398 | } /* end H5S_select_construct_projection() */ |
2291 | | |
2292 | | /*-------------------------------------------------------------------------- |
2293 | | NAME |
2294 | | H5S_select_fill |
2295 | | PURPOSE |
2296 | | Fill a selection in memory with a value |
2297 | | USAGE |
2298 | | herr_t H5S_select_fill(fill,fill_size,space,buf) |
2299 | | const void *fill; IN: Pointer to fill value to use |
2300 | | size_t fill_size; IN: Size of elements in memory buffer & size of |
2301 | | fill value |
2302 | | H5S_t *space; IN: Dataspace describing memory buffer & |
2303 | | containing selection to use. |
2304 | | void *buf; IN/OUT: Memory buffer to fill selection in |
2305 | | RETURNS |
2306 | | Non-negative on success/Negative on failure. |
2307 | | DESCRIPTION |
2308 | | Use the selection in the dataspace to fill elements in a memory buffer. |
2309 | | GLOBAL VARIABLES |
2310 | | COMMENTS, BUGS, ASSUMPTIONS |
2311 | | The memory buffer elements are assumed to have the same datatype as the |
2312 | | fill value being placed into them. |
2313 | | EXAMPLES |
2314 | | REVISION LOG |
2315 | | --------------------------------------------------------------------------*/ |
2316 | | herr_t |
2317 | | H5S_select_fill(const void *fill, size_t fill_size, H5S_t *space, void *_buf) |
2318 | 0 | { |
2319 | 0 | H5S_sel_iter_t *iter = NULL; /* Selection iteration info */ |
2320 | 0 | bool iter_init = false; /* Selection iteration info has been initialized */ |
2321 | 0 | hsize_t *off = NULL; /* Array to store sequence offsets */ |
2322 | 0 | size_t *len = NULL; /* Array to store sequence lengths */ |
2323 | 0 | hssize_t nelmts; /* Number of elements in selection */ |
2324 | 0 | size_t max_elem; /* Total number of elements in selection */ |
2325 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
2326 | |
|
2327 | 0 | FUNC_ENTER_NOAPI(FAIL) |
2328 | | |
2329 | | /* Check args */ |
2330 | 0 | assert(fill); |
2331 | 0 | assert(fill_size > 0); |
2332 | 0 | assert(space); |
2333 | 0 | assert(_buf); |
2334 | | |
2335 | | /* Allocate the selection iterator */ |
2336 | 0 | if (NULL == (iter = H5FL_MALLOC(H5S_sel_iter_t))) |
2337 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator"); |
2338 | | |
2339 | | /* Initialize iterator */ |
2340 | 0 | if (H5S_select_iter_init(iter, space, fill_size, 0) < 0) |
2341 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize selection iterator"); |
2342 | 0 | iter_init = true; /* Selection iteration info has been initialized */ |
2343 | | |
2344 | | /* Get the number of elements in selection */ |
2345 | 0 | if ((nelmts = (hssize_t)H5S_GET_SELECT_NPOINTS(space)) < 0) |
2346 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOUNT, FAIL, "can't get number of elements selected"); |
2347 | | |
2348 | | /* Compute the number of bytes to process */ |
2349 | 0 | H5_CHECKED_ASSIGN(max_elem, size_t, nelmts, hssize_t); |
2350 | | |
2351 | | /* Allocate the offset & length arrays */ |
2352 | 0 | if (NULL == (len = H5FL_SEQ_MALLOC(size_t, H5D_IO_VECTOR_SIZE))) |
2353 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate length vector array"); |
2354 | 0 | if (NULL == (off = H5FL_SEQ_MALLOC(hsize_t, H5D_IO_VECTOR_SIZE))) |
2355 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate offset vector array"); |
2356 | | |
2357 | | /* Loop, while elements left in selection */ |
2358 | 0 | while (max_elem > 0) { |
2359 | 0 | size_t nseq; /* Number of sequences generated */ |
2360 | 0 | size_t curr_seq; /* Current sequence being worked on */ |
2361 | 0 | size_t nelem; /* Number of elements used in sequences */ |
2362 | | |
2363 | | /* Get the sequences of bytes */ |
2364 | 0 | if (H5S_SELECT_ITER_GET_SEQ_LIST(iter, (size_t)H5D_IO_VECTOR_SIZE, max_elem, &nseq, &nelem, off, |
2365 | 0 | len) < 0) |
2366 | 0 | HGOTO_ERROR(H5E_INTERNAL, H5E_UNSUPPORTED, FAIL, "sequence length generation failed"); |
2367 | | |
2368 | | /* Loop over sequences */ |
2369 | 0 | for (curr_seq = 0; curr_seq < nseq; curr_seq++) { |
2370 | 0 | uint8_t *buf; /* Current location in buffer */ |
2371 | | |
2372 | | /* Get offset in memory buffer */ |
2373 | 0 | buf = (uint8_t *)_buf + off[curr_seq]; |
2374 | | |
2375 | | /* Fill each sequence in memory with fill value */ |
2376 | 0 | assert((len[curr_seq] % fill_size) == 0); |
2377 | 0 | H5VM_array_fill(buf, fill, fill_size, (len[curr_seq] / fill_size)); |
2378 | 0 | } /* end for */ |
2379 | | |
2380 | | /* Decrement number of elements left to process */ |
2381 | 0 | max_elem -= nelem; |
2382 | 0 | } /* end while */ |
2383 | | |
2384 | 0 | done: |
2385 | | /* Release resources, if allocated */ |
2386 | 0 | if (len) |
2387 | 0 | len = H5FL_SEQ_FREE(size_t, len); |
2388 | 0 | if (off) |
2389 | 0 | off = H5FL_SEQ_FREE(hsize_t, off); |
2390 | | |
2391 | | /* Release selection iterator */ |
2392 | 0 | if (iter_init && H5S_SELECT_ITER_RELEASE(iter) < 0) |
2393 | 0 | HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release selection iterator"); |
2394 | 0 | if (iter) |
2395 | 0 | iter = H5FL_FREE(H5S_sel_iter_t, iter); |
2396 | |
|
2397 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
2398 | 0 | } /* end H5S_select_fill() */ |
2399 | | |
2400 | | /*-------------------------------------------------------------------------- |
2401 | | NAME |
2402 | | H5S_select_project_intersection |
2403 | | |
2404 | | PURPOSE |
2405 | | Projects the intersection of of the selections of src_space and |
2406 | | src_intersect_space within the selection of src_space as a selection |
2407 | | within the selection of dst_space |
2408 | | |
2409 | | USAGE |
2410 | | herr_t H5S_select_project_intersection(src_space,dst_space,src_intersect_space,proj_space,share_selection) |
2411 | | H5S_t *src_space; IN: Selection that is mapped to dst_space, and intersected with |
2412 | | src_intersect_space H5S_t *dst_space; IN: Selection that is mapped to src_space H5S_t |
2413 | | *src_intersect_space; IN: Selection whose intersection with src_space is projected to dst_space to obtain the |
2414 | | result H5S_t **new_space_ptr; OUT: Will contain the result (intersection of src_intersect_space and src_space |
2415 | | projected from src_space to dst_space) after the operation bool share_selection; IN: Whether we are allowed |
2416 | | to share structures inside dst_space with proj_space |
2417 | | |
2418 | | RETURNS |
2419 | | Non-negative on success/Negative on failure. |
2420 | | |
2421 | | DESCRIPTION |
2422 | | Projects the intersection of of the selections of src_space and |
2423 | | src_intersect_space within the selection of src_space as a selection |
2424 | | within the selection of dst_space. The result is placed in the |
2425 | | selection of new_space_ptr. |
2426 | | |
2427 | | GLOBAL VARIABLES |
2428 | | COMMENTS, BUGS, ASSUMPTIONS |
2429 | | EXAMPLES |
2430 | | REVISION LOG |
2431 | | --------------------------------------------------------------------------*/ |
2432 | | herr_t |
2433 | | H5S_select_project_intersection(H5S_t *src_space, H5S_t *dst_space, H5S_t *src_intersect_space, |
2434 | | H5S_t **new_space_ptr, bool share_selection) |
2435 | 0 | { |
2436 | 0 | H5S_t *new_space = NULL; /* New dataspace constructed */ |
2437 | 0 | H5S_t *tmp_src_intersect_space = NULL; /* Temporary SIS converted from points->hyperslabs */ |
2438 | 0 | H5S_sel_iter_t *ss_iter = NULL; /* Selection iterator for src_space */ |
2439 | 0 | bool ss_iter_init = false; /* Whether ss_iter has been initialized */ |
2440 | 0 | H5S_sel_iter_t *ds_iter = NULL; /* Selection iterator for dst_space */ |
2441 | 0 | bool ds_iter_init = false; /* Whether ds_iter has been initialized */ |
2442 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
2443 | |
|
2444 | 0 | FUNC_ENTER_NOAPI(FAIL) |
2445 | | |
2446 | | /* Sanity checks */ |
2447 | 0 | assert(src_space); |
2448 | 0 | assert(dst_space); |
2449 | 0 | assert(src_intersect_space); |
2450 | 0 | assert(new_space_ptr); |
2451 | 0 | assert(H5S_GET_SELECT_NPOINTS(src_space) == H5S_GET_SELECT_NPOINTS(dst_space)); |
2452 | 0 | assert(H5S_GET_EXTENT_NDIMS(src_space) == H5S_GET_EXTENT_NDIMS(src_intersect_space)); |
2453 | |
|
2454 | 0 | if (NULL == (ss_iter = H5FL_CALLOC(H5S_sel_iter_t))) |
2455 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator"); |
2456 | 0 | if (NULL == (ds_iter = H5FL_CALLOC(H5S_sel_iter_t))) |
2457 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate selection iterator"); |
2458 | | |
2459 | | /* Create new space, using dst extent. Start with "all" selection. */ |
2460 | 0 | if (NULL == (new_space = H5S_create(H5S_SIMPLE))) |
2461 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "unable to create output dataspace"); |
2462 | 0 | if (H5S__extent_copy_real(&new_space->extent, &dst_space->extent, true) < 0) |
2463 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "unable to copy destination space extent"); |
2464 | | |
2465 | | /* If the intersecting space is "all", the intersection must be equal to the |
2466 | | * source space and the projection must be equal to the destination space */ |
2467 | 0 | if (H5S_GET_SELECT_TYPE(src_intersect_space) == H5S_SEL_ALL) { |
2468 | | /* Copy the destination selection. */ |
2469 | 0 | if (H5S_select_copy(new_space, dst_space, false) < 0) |
2470 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, "can't copy destination space selection"); |
2471 | 0 | } /* end if */ |
2472 | | /* If any of the selections contain no elements, the projection must be |
2473 | | * "none" */ |
2474 | 0 | else if ((H5S_GET_SELECT_NPOINTS(src_intersect_space) == 0) || (H5S_GET_SELECT_NPOINTS(src_space) == 0) || |
2475 | 0 | (H5S_GET_SELECT_NPOINTS(dst_space) == 0)) { |
2476 | | /* Change to "none" selection */ |
2477 | 0 | if (H5S_select_none(new_space) < 0) |
2478 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection"); |
2479 | 0 | } /* end if */ |
2480 | 0 | else { |
2481 | | /* Handle scalar dataspaces. It should not be possible for the source |
2482 | | * intersect space or the source space to be scalar since scalar spaces |
2483 | | * only support all or none selections, and both of those cases are |
2484 | | * covered above, and the source intersect space must have the same |
2485 | | * rank, so it also cannot be scalar, as scalar dataspaces have a rank |
2486 | | * of 0. */ |
2487 | 0 | assert(H5S_GET_EXTENT_TYPE(src_space) != H5S_SCALAR); |
2488 | 0 | assert(H5S_GET_EXTENT_TYPE(src_intersect_space) != H5S_SCALAR); |
2489 | | |
2490 | | /* Check for scalar dst_space. In this case we simply check if the |
2491 | | * (single) point selected in src_space intersects src_intersect_space, |
2492 | | * if so select all in new_space, otherwise select none. */ |
2493 | 0 | if (H5S_GET_EXTENT_TYPE(dst_space) == H5S_SCALAR) { |
2494 | 0 | hsize_t coords_start[H5S_MAX_RANK]; |
2495 | 0 | hsize_t coords_end[H5S_MAX_RANK]; |
2496 | 0 | htri_t intersect; |
2497 | | |
2498 | | /* Get source space bounds. Should be a single point. */ |
2499 | 0 | if (H5S_SELECT_BOUNDS(src_space, coords_start, coords_end) < 0) |
2500 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't get source space bounds"); |
2501 | 0 | assert(0 == memcmp(coords_start, coords_end, |
2502 | 0 | H5S_GET_EXTENT_NDIMS(src_space) * sizeof(coords_start[0]))); |
2503 | | |
2504 | | /* Check for intersection */ |
2505 | 0 | if ((intersect = H5S_SELECT_INTERSECT_BLOCK(src_intersect_space, coords_start, coords_end)) < 0) |
2506 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't check for intersection"); |
2507 | | |
2508 | | /* Select all or none as appropriate */ |
2509 | 0 | if (intersect) { |
2510 | 0 | if (H5S_select_all(new_space, true) < 0) |
2511 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "can't select all"); |
2512 | 0 | } /* end if */ |
2513 | 0 | else if (H5S_select_none(new_space) < 0) |
2514 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection"); |
2515 | 0 | } /* end if */ |
2516 | 0 | else { |
2517 | | /* If the source intersect space is a point selection, convert it to a |
2518 | | * hyperslab (discarding ordering). We can get away with this because |
2519 | | * the order does not matter for the source intersect space */ |
2520 | | /* Maybe we should just leave it as a point selection for the point by |
2521 | | * point algorithm? The search through the selection in |
2522 | | * H5S_SELECT_INTERSECT_BLOCK will likely be O(N) either way. -NAF */ |
2523 | 0 | if (H5S_GET_SELECT_TYPE(src_intersect_space) == H5S_SEL_POINTS) { |
2524 | 0 | H5S_pnt_node_t *curr_pnt = src_intersect_space->select.sel_info.pnt_lst->head; |
2525 | | |
2526 | | /* Create dataspace and copy extent */ |
2527 | 0 | if (NULL == (tmp_src_intersect_space = H5S_create(H5S_SIMPLE))) |
2528 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, |
2529 | 0 | "unable to create temporary source intersect dataspace"); |
2530 | 0 | if (H5S__extent_copy_real(&tmp_src_intersect_space->extent, &src_intersect_space->extent, |
2531 | 0 | false) < 0) |
2532 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOPY, FAIL, |
2533 | 0 | "unable to copy source intersect space extent"); |
2534 | | |
2535 | | /* Iterate over points */ |
2536 | 0 | for (curr_pnt = src_intersect_space->select.sel_info.pnt_lst->head; curr_pnt; |
2537 | 0 | curr_pnt = curr_pnt->next) |
2538 | | /* Add point to hyperslab selection */ |
2539 | 0 | if (H5S_hyper_add_span_element(tmp_src_intersect_space, src_intersect_space->extent.rank, |
2540 | 0 | curr_pnt->pnt) < 0) |
2541 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, |
2542 | 0 | "can't add point to temporary dataspace selection"); |
2543 | | |
2544 | | /* Redirect local src_intersect_space pointer (will not affect |
2545 | | * calling function) */ |
2546 | 0 | src_intersect_space = tmp_src_intersect_space; |
2547 | 0 | } /* end for */ |
2548 | | |
2549 | | /* By this point, src_intersect_space must be a hyperslab selection */ |
2550 | 0 | assert(H5S_GET_SELECT_TYPE(src_intersect_space) == H5S_SEL_HYPERSLABS); |
2551 | | |
2552 | | /* If either the source space or the destination space is a point |
2553 | | * selection, iterate element by element */ |
2554 | 0 | if ((H5S_GET_SELECT_TYPE(src_space) == H5S_SEL_POINTS) || |
2555 | 0 | (H5S_GET_SELECT_TYPE(dst_space) == H5S_SEL_POINTS)) { |
2556 | 0 | hsize_t coords[H5S_MAX_RANK]; |
2557 | 0 | htri_t intersect; |
2558 | | |
2559 | | /* Start with "none" selection */ |
2560 | 0 | if (H5S_select_none(new_space) < 0) |
2561 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection"); |
2562 | | |
2563 | | /* Initialize iterators */ |
2564 | 0 | if (H5S_select_iter_init(ss_iter, src_space, 1, H5S_SEL_ITER_SHARE_WITH_DATASPACE) < 0) |
2565 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, |
2566 | 0 | "can't initialize source space selection iterator"); |
2567 | 0 | ss_iter_init = true; |
2568 | 0 | if (H5S_select_iter_init(ds_iter, dst_space, 1, H5S_SEL_ITER_SHARE_WITH_DATASPACE) < 0) |
2569 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, |
2570 | 0 | "can't initialize destination space selection iterator"); |
2571 | 0 | ds_iter_init = true; |
2572 | | |
2573 | | /* Iterate over points */ |
2574 | 0 | do { |
2575 | 0 | assert(ss_iter->elmt_left > 0); |
2576 | 0 | assert(ss_iter->elmt_left > 0); |
2577 | | |
2578 | | /* Get SS coords */ |
2579 | 0 | if (H5S_SELECT_ITER_COORDS(ss_iter, coords) < 0) |
2580 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, |
2581 | 0 | "can't get source selection coordinates"); |
2582 | | |
2583 | | /* Check for intersection */ |
2584 | 0 | if ((intersect = H5S_SELECT_INTERSECT_BLOCK(src_intersect_space, coords, coords)) < 0) |
2585 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCOMPARE, FAIL, "can't check for intersection"); |
2586 | | |
2587 | | /* Add point if it intersects */ |
2588 | 0 | if (intersect) { |
2589 | | /* Get DS coords */ |
2590 | 0 | if (H5S_SELECT_ITER_COORDS(ds_iter, coords) < 0) |
2591 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, |
2592 | 0 | "can't get destination selection coordinates"); |
2593 | | |
2594 | | /* Add point to new_space */ |
2595 | 0 | if (H5S_select_elements(new_space, H5S_SELECT_APPEND, 1, coords) < 0) |
2596 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, |
2597 | 0 | "can't add point to new selection"); |
2598 | 0 | } /* end if */ |
2599 | | |
2600 | | /* Advance iterators */ |
2601 | 0 | if (H5S_SELECT_ITER_NEXT(ss_iter, 1) < 0) |
2602 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, |
2603 | 0 | "can't advance source selection iterator"); |
2604 | 0 | ss_iter->elmt_left--; |
2605 | 0 | if (H5S_SELECT_ITER_NEXT(ds_iter, 1) < 0) |
2606 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, |
2607 | 0 | "can't advance destination selection iterator"); |
2608 | 0 | ds_iter->elmt_left--; |
2609 | 0 | } while (ss_iter->elmt_left > 0); |
2610 | 0 | assert(H5S_SELECT_ITER_NELMTS(ds_iter) == 0); |
2611 | 0 | } /* end if */ |
2612 | 0 | else { |
2613 | 0 | assert(H5S_GET_SELECT_TYPE(src_space) != H5S_SEL_NONE); |
2614 | 0 | assert(H5S_GET_SELECT_TYPE(dst_space) != H5S_SEL_NONE); |
2615 | | |
2616 | | /* Source and destination selections are all or hyperslab, |
2617 | | * intersecting selection is hyperslab. Call the hyperslab routine |
2618 | | * to project to another hyperslab selection. */ |
2619 | 0 | if (H5S__hyper_project_intersection(src_space, dst_space, src_intersect_space, new_space, |
2620 | 0 | share_selection) < 0) |
2621 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, |
2622 | 0 | "can't project hyperslab onto destination selection"); |
2623 | 0 | } /* end else */ |
2624 | 0 | } /* end else */ |
2625 | 0 | } /* end else */ |
2626 | | |
2627 | | /* load the address of the new space into *new_space_ptr */ |
2628 | 0 | *new_space_ptr = new_space; |
2629 | |
|
2630 | 0 | done: |
2631 | | /* Cleanup on error */ |
2632 | 0 | if (ret_value < 0) |
2633 | 0 | if (new_space && H5S_close(new_space) < 0) |
2634 | 0 | HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace"); |
2635 | | |
2636 | | /* General cleanup */ |
2637 | 0 | if (tmp_src_intersect_space && H5S_close(tmp_src_intersect_space) < 0) |
2638 | 0 | HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release temporary dataspace"); |
2639 | 0 | if (ss_iter_init && H5S_SELECT_ITER_RELEASE(ss_iter) < 0) |
2640 | 0 | HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release source selection iterator"); |
2641 | 0 | if (ds_iter_init && H5S_SELECT_ITER_RELEASE(ds_iter) < 0) |
2642 | 0 | HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release destination selection iterator"); |
2643 | |
|
2644 | 0 | ss_iter = H5FL_FREE(H5S_sel_iter_t, ss_iter); |
2645 | 0 | ds_iter = H5FL_FREE(H5S_sel_iter_t, ds_iter); |
2646 | |
|
2647 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
2648 | 0 | } /* end H5S_select_project_intersection() */ |
2649 | | |
2650 | | /*-------------------------------------------------------------------------- |
2651 | | NAME |
2652 | | H5Sselect_project_intersection |
2653 | | |
2654 | | PURPOSE |
2655 | | Projects the intersection of of the selections of src_space_id and |
2656 | | src_intersect_space_id within the selection of src_space_id as a |
2657 | | selection within the selection of dst_space_id. |
2658 | | |
2659 | | USAGE |
2660 | | hid_t H5Sselect_project_intersection(src_space_id,dst_space_d,src_intersect_space_id) |
2661 | | hid_t src_space_id; IN: Selection that is mapped to dst_space_id, and intersected with |
2662 | | src_intersect_space_id hid_t dst_space_id; IN: Selection that is mapped to src_space_id hid_t |
2663 | | src_intersect_space_id; IN: Selection whose intersection with src_space_id is projected to dst_space_id to |
2664 | | obtain the result |
2665 | | |
2666 | | RETURNS |
2667 | | A dataspace with a selection equal to the intersection of |
2668 | | src_intersect_space_id and src_space_id projected from src_space to |
2669 | | dst_space on success, negative on failure. |
2670 | | |
2671 | | DESCRIPTION |
2672 | | Projects the intersection of of the selections of src_space and |
2673 | | src_intersect_space within the selection of src_space as a selection |
2674 | | within the selection of dst_space. The result is placed in the |
2675 | | selection of new_space_ptr. |
2676 | | |
2677 | | GLOBAL VARIABLES |
2678 | | COMMENTS, BUGS, ASSUMPTIONS |
2679 | | EXAMPLES |
2680 | | REVISION LOG |
2681 | | --------------------------------------------------------------------------*/ |
2682 | | hid_t |
2683 | | H5Sselect_project_intersection(hid_t src_space_id, hid_t dst_space_id, hid_t src_intersect_space_id) |
2684 | 0 | { |
2685 | 0 | H5S_t *src_space, *dst_space, *src_intersect_space; /* Input dataspaces */ |
2686 | 0 | H5S_t *proj_space = NULL; /* Output dataspace */ |
2687 | 0 | hid_t ret_value; /* Return value */ |
2688 | |
|
2689 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
2690 | | |
2691 | | /* Check args */ |
2692 | 0 | if (NULL == (src_space = (H5S_t *)H5I_object_verify(src_space_id, H5I_DATASPACE))) |
2693 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, H5I_INVALID_HID, "not a dataspace"); |
2694 | 0 | if (NULL == (dst_space = (H5S_t *)H5I_object_verify(dst_space_id, H5I_DATASPACE))) |
2695 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, H5I_INVALID_HID, "not a dataspace"); |
2696 | 0 | if (NULL == (src_intersect_space = (H5S_t *)H5I_object_verify(src_intersect_space_id, H5I_DATASPACE))) |
2697 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, H5I_INVALID_HID, "not a dataspace"); |
2698 | | |
2699 | | /* Check numbers of points selected matches in source and destination */ |
2700 | 0 | if (H5S_GET_SELECT_NPOINTS(src_space) != H5S_GET_SELECT_NPOINTS(dst_space)) |
2701 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, H5I_INVALID_HID, |
2702 | 0 | "number of points selected in source space does not match that in destination space"); |
2703 | | |
2704 | | /* Check numbers of dimensions matches in source and source intersect spaces |
2705 | | */ |
2706 | 0 | if (H5S_GET_EXTENT_NDIMS(src_space) != H5S_GET_EXTENT_NDIMS(src_intersect_space)) |
2707 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, H5I_INVALID_HID, |
2708 | 0 | "rank of source space does not match rank of source intersect space"); |
2709 | | |
2710 | | /* Perform operation */ |
2711 | 0 | if (H5S_select_project_intersection(src_space, dst_space, src_intersect_space, &proj_space, false) < 0) |
2712 | 0 | HGOTO_ERROR(H5E_DATASET, H5E_CANTCLIP, H5I_INVALID_HID, "can't project dataspace intersection"); |
2713 | | |
2714 | | /* Register */ |
2715 | 0 | if ((ret_value = H5I_register(H5I_DATASPACE, proj_space, true)) < 0) |
2716 | 0 | HGOTO_ERROR(H5E_ID, H5E_CANTREGISTER, H5I_INVALID_HID, "unable to register dataspace ID"); |
2717 | | |
2718 | 0 | done: |
2719 | 0 | if (ret_value < 0) |
2720 | 0 | if (proj_space && H5S_close(proj_space) < 0) |
2721 | 0 | HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, H5I_INVALID_HID, "unable to release dataspace"); |
2722 | |
|
2723 | 0 | FUNC_LEAVE_API(ret_value) |
2724 | 0 | } /* end H5Sselect_project_intersection() */ |
2725 | | |
2726 | | /*-------------------------------------------------------------------------- |
2727 | | NAME |
2728 | | H5S_select_subtract |
2729 | | |
2730 | | PURPOSE |
2731 | | Subtract one selection from another |
2732 | | |
2733 | | USAGE |
2734 | | herr_t H5S_select_subtract(space,subtract_space) |
2735 | | H5S_t *space; IN/OUT: Selection to be operated on |
2736 | | H5S_t *subtract_space; IN: Selection that will be subtracted from space |
2737 | | |
2738 | | RETURNS |
2739 | | Non-negative on success/Negative on failure. |
2740 | | |
2741 | | DESCRIPTION |
2742 | | Removes any and all portions of space that are also present in |
2743 | | subtract_space. In essence, performs an A_NOT_B operation with the |
2744 | | two selections. |
2745 | | |
2746 | | GLOBAL VARIABLES |
2747 | | COMMENTS, BUGS, ASSUMPTIONS |
2748 | | EXAMPLES |
2749 | | REVISION LOG |
2750 | | --------------------------------------------------------------------------*/ |
2751 | | herr_t |
2752 | | H5S_select_subtract(H5S_t *space, H5S_t *subtract_space) |
2753 | 0 | { |
2754 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
2755 | |
|
2756 | 0 | FUNC_ENTER_NOAPI(FAIL) |
2757 | | |
2758 | | /* Sanity checks */ |
2759 | 0 | assert(space); |
2760 | 0 | assert(subtract_space); |
2761 | | |
2762 | | /* If either space is using the none selection, then we do not need to do |
2763 | | * anything */ |
2764 | 0 | if ((space->select.type->type != H5S_SEL_NONE) && (subtract_space->select.type->type != H5S_SEL_NONE)) { |
2765 | | /* If subtract_space is using the all selection, set space to none */ |
2766 | 0 | if (subtract_space->select.type->type == H5S_SEL_ALL) { |
2767 | | /* Change to "none" selection */ |
2768 | 0 | if (H5S_select_none(space) < 0) |
2769 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDELETE, FAIL, "can't change selection"); |
2770 | 0 | } /* end if */ |
2771 | | /* If either selection is a point selection, fail currently */ |
2772 | 0 | else if ((subtract_space->select.type->type == H5S_SEL_POINTS) || |
2773 | 0 | (space->select.type->type == H5S_SEL_POINTS)) { |
2774 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "point selections not currently supported"); |
2775 | 0 | } /* end if */ |
2776 | 0 | else { |
2777 | | /* Check for all selection in space, convert to hyperslab */ |
2778 | 0 | if (space->select.type->type == H5S_SEL_ALL) { |
2779 | | /* Convert current "all" selection to "real" hyperslab selection */ |
2780 | | /* Then allow operation to proceed */ |
2781 | 0 | hsize_t tmp_start[H5S_MAX_RANK]; /* Temporary start information */ |
2782 | 0 | hsize_t tmp_stride[H5S_MAX_RANK]; /* Temporary stride information */ |
2783 | 0 | hsize_t tmp_count[H5S_MAX_RANK]; /* Temporary count information */ |
2784 | 0 | hsize_t tmp_block[H5S_MAX_RANK]; /* Temporary block information */ |
2785 | 0 | unsigned u; /* Local index variable */ |
2786 | | |
2787 | | /* Fill in temporary information for the dimensions */ |
2788 | 0 | for (u = 0; u < space->extent.rank; u++) { |
2789 | 0 | tmp_start[u] = 0; |
2790 | 0 | tmp_stride[u] = 1; |
2791 | 0 | tmp_count[u] = 1; |
2792 | 0 | tmp_block[u] = space->extent.size[u]; |
2793 | 0 | } /* end for */ |
2794 | | |
2795 | | /* Convert to hyperslab selection */ |
2796 | 0 | if (H5S_select_hyperslab(space, H5S_SELECT_SET, tmp_start, tmp_stride, tmp_count, tmp_block) < |
2797 | 0 | 0) |
2798 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSELECT, FAIL, "can't convert selection"); |
2799 | 0 | } /* end if */ |
2800 | | |
2801 | 0 | assert(space->select.type->type == H5S_SEL_HYPERSLABS); |
2802 | 0 | assert(subtract_space->select.type->type == H5S_SEL_HYPERSLABS); |
2803 | | |
2804 | | /* Both spaces are now hyperslabs, perform the operation */ |
2805 | 0 | if (H5S__modify_select(space, H5S_SELECT_NOTB, subtract_space) < 0) |
2806 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCLIP, FAIL, "can't subtract hyperslab"); |
2807 | 0 | } /* end else */ |
2808 | 0 | } /* end if */ |
2809 | | |
2810 | 0 | done: |
2811 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
2812 | 0 | } /* end H5S_select_subtract() */ |
2813 | | |
2814 | | /*-------------------------------------------------------------------------- |
2815 | | NAME |
2816 | | H5Ssel_iter_create |
2817 | | PURPOSE |
2818 | | Create a dataspace selection iterator for a dataspace's selection |
2819 | | USAGE |
2820 | | hid_t H5Ssel_iter_create(space,elmt_size,flags) |
2821 | | hid_t space; IN: ID of the dataspace with selection to iterate over |
2822 | | RETURNS |
2823 | | Valid dataspace selection iterator ID on success, H5I_INVALID_HID on failure |
2824 | | DESCRIPTION |
2825 | | Creates a selection iterator and initializes it to start at the first |
2826 | | element selected in the dataspace. |
2827 | | PROGRAMMER |
2828 | | GLOBAL VARIABLES |
2829 | | COMMENTS, BUGS, ASSUMPTIONS |
2830 | | EXAMPLES |
2831 | | REVISION LOG |
2832 | | --------------------------------------------------------------------------*/ |
2833 | | hid_t |
2834 | | H5Ssel_iter_create(hid_t space_id, size_t elmt_size, unsigned flags) |
2835 | 0 | { |
2836 | 0 | H5S_t *space; /* Dataspace with selection to iterate over */ |
2837 | 0 | H5S_sel_iter_t *sel_iter; /* Selection iterator created */ |
2838 | 0 | hid_t ret_value; /* Return value */ |
2839 | |
|
2840 | 0 | FUNC_ENTER_API(H5I_INVALID_HID) |
2841 | | |
2842 | | /* Check args */ |
2843 | 0 | if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) |
2844 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, H5I_INVALID_HID, "not a dataspace"); |
2845 | 0 | if (elmt_size == 0) |
2846 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, H5I_INVALID_HID, "element size must be greater than 0"); |
2847 | 0 | if (flags != (flags & H5S_SEL_ITER_ALL_PUBLIC_FLAGS)) |
2848 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, H5I_INVALID_HID, "invalid selection iterator flag"); |
2849 | | |
2850 | | /* Allocate the iterator */ |
2851 | 0 | if (NULL == (sel_iter = H5FL_MALLOC(H5S_sel_iter_t))) |
2852 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, H5I_INVALID_HID, "can't allocate selection iterator"); |
2853 | | |
2854 | | /* Add flag to indicate that this iterator is from an API call */ |
2855 | 0 | flags |= H5S_SEL_ITER_API_CALL; |
2856 | | |
2857 | | /* Initialize the selection iterator */ |
2858 | 0 | if (H5S_select_iter_init(sel_iter, space, elmt_size, flags) < 0) |
2859 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, H5I_INVALID_HID, "unable to initialize selection iterator"); |
2860 | | |
2861 | | /* Register */ |
2862 | 0 | if ((ret_value = H5I_register(H5I_SPACE_SEL_ITER, sel_iter, true)) < 0) |
2863 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTREGISTER, H5I_INVALID_HID, |
2864 | 0 | "unable to register dataspace selection iterator ID"); |
2865 | | |
2866 | 0 | done: |
2867 | 0 | FUNC_LEAVE_API(ret_value) |
2868 | 0 | } /* end H5Ssel_iter_create() */ |
2869 | | |
2870 | | /*-------------------------------------------------------------------------- |
2871 | | NAME |
2872 | | H5Ssel_iter_get_seq_list |
2873 | | PURPOSE |
2874 | | Retrieve a list of offset / length sequences for the elements in an iterator |
2875 | | USAGE |
2876 | | herr_t H5Ssel_iter_get_seq_list(sel_iter_id, maxseq, maxbytes, nseq, nbytes, off, len) |
2877 | | hid_t sel_iter_id; IN: ID of the dataspace selection iterator to retrieve sequence from |
2878 | | size_t maxseq; IN: Max. # of sequences to retrieve |
2879 | | size_t maxelmts; IN: Max. # of elements to retrieve in sequences |
2880 | | size_t *nseq; OUT: # of sequences retrieved |
2881 | | size_t *nelmts; OUT: # of elements retrieved, in all sequences |
2882 | | hsize_t *off; OUT: Array of sequence offsets |
2883 | | size_t *len; OUT: Array of sequence lengths |
2884 | | RETURNS |
2885 | | Non-negative on success / Negative on failure |
2886 | | DESCRIPTION |
2887 | | Retrieve a list of offset / length pairs (a list of "sequences") matching |
2888 | | the selected elements for an iterator, according to the iteration order for |
2889 | | the iterator. The lengths returned are in _bytes_, not elements. |
2890 | | |
2891 | | Note that the iteration order for "all" and "hyperslab" selections is |
2892 | | row-major (i.e. "C-ordered"), but the iteration order for "point" |
2893 | | selections is "in order selected", unless the H5S_SEL_ITER_GET_SEQ_LIST_SORTED |
2894 | | flag is passed to H5Sset_iter_create for a point selection. |
2895 | | |
2896 | | MAXSEQ and MAXELMTS specify the most sequences or bytes possible to |
2897 | | place into the OFF and LEN arrays. *NSEQ and *NELMTS return the actual |
2898 | | number of sequences and bytes put into the arrays. |
2899 | | |
2900 | | Each call to H5Ssel_iter_get_seq_list() will retrieve the next set |
2901 | | of sequences for the selection being iterated over. |
2902 | | |
2903 | | The total number of bytes possible to retrieve from a selection iterator |
2904 | | is the 'elmt_size' passed to H5Ssel_iter_create multiplied by the number |
2905 | | of elements selected in the dataspace the iterator was created from |
2906 | | (which can be retrieved with H5Sget_select_npoints). When there are no |
2907 | | further sequences of elements to retrieve, calls to this routine will |
2908 | | set *NSEQ and *NELMTS to zero. |
2909 | | PROGRAMMER |
2910 | | GLOBAL VARIABLES |
2911 | | COMMENTS, BUGS, ASSUMPTIONS |
2912 | | EXAMPLES |
2913 | | REVISION LOG |
2914 | | --------------------------------------------------------------------------*/ |
2915 | | herr_t |
2916 | | H5Ssel_iter_get_seq_list(hid_t sel_iter_id, size_t maxseq, size_t maxelmts, size_t *nseq /*out*/, |
2917 | | size_t *nelmts /*out*/, hsize_t *off /*out*/, size_t *len /*out*/) |
2918 | 0 | { |
2919 | 0 | H5S_sel_iter_t *sel_iter; /* Dataspace selection iterator to operate on */ |
2920 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
2921 | |
|
2922 | 0 | FUNC_ENTER_API(FAIL) |
2923 | | |
2924 | | /* Check args */ |
2925 | 0 | if (NULL == (sel_iter = (H5S_sel_iter_t *)H5I_object_verify(sel_iter_id, H5I_SPACE_SEL_ITER))) |
2926 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace selection iterator"); |
2927 | 0 | if (NULL == nseq) |
2928 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "'nseq' pointer is NULL"); |
2929 | 0 | if (NULL == nelmts) |
2930 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "'nbytes' pointer is NULL"); |
2931 | 0 | if (NULL == off) |
2932 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "offset array pointer is NULL"); |
2933 | 0 | if (NULL == len) |
2934 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADVALUE, FAIL, "length array pointer is NULL"); |
2935 | | |
2936 | | /* Get the sequences of bytes */ |
2937 | 0 | if (maxseq > 0 && maxelmts > 0 && sel_iter->elmt_left > 0) { |
2938 | 0 | if (H5S_SELECT_ITER_GET_SEQ_LIST(sel_iter, maxseq, maxelmts, nseq, nelmts, off, len) < 0) |
2939 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "sequence length generation failed"); |
2940 | 0 | } /* end if */ |
2941 | 0 | else |
2942 | 0 | *nseq = *nelmts = 0; |
2943 | | |
2944 | 0 | done: |
2945 | 0 | FUNC_LEAVE_API(ret_value) |
2946 | 0 | } /* end H5Ssel_iter_get_seq_list() */ |
2947 | | |
2948 | | /*-------------------------------------------------------------------------- |
2949 | | NAME |
2950 | | H5S_select_contig_block |
2951 | | |
2952 | | PURPOSE |
2953 | | Determines if a selection is a single contiguous block, and returns the |
2954 | | offset and length (in elements) if it is |
2955 | | |
2956 | | USAGE |
2957 | | herr_t H5S_select_contig_block(space, is_contig, off, len) |
2958 | | H5S_t *space; IN: Selection to check |
2959 | | bool *is_contig; OUT: Whether the selection is contiguous |
2960 | | hsize_t *off; OUT: Offset of selection |
2961 | | size_t *len; OUT: Length of selection |
2962 | | |
2963 | | RETURNS |
2964 | | Non-negative on success/Negative on failure. |
2965 | | |
2966 | | DESCRIPTION |
2967 | | Determines if a selection is a single contiguous block, and returns the |
2968 | | offset and length (in elements) if it is. |
2969 | | |
2970 | | GLOBAL VARIABLES |
2971 | | COMMENTS, BUGS, ASSUMPTIONS |
2972 | | EXAMPLES |
2973 | | REVISION LOG |
2974 | | --------------------------------------------------------------------------*/ |
2975 | | herr_t |
2976 | | H5S_select_contig_block(H5S_t *space, bool *is_contig, hsize_t *off, size_t *len) |
2977 | 563 | { |
2978 | 563 | H5S_sel_iter_t *iter = NULL; /* Selection iterator */ |
2979 | 563 | bool iter_init = false; /* Selection iteration info has been initialized */ |
2980 | 563 | size_t nseq_tmp; |
2981 | 563 | size_t nelem_tmp; |
2982 | 563 | hsize_t sel_off; |
2983 | 563 | size_t sel_len; |
2984 | 563 | herr_t ret_value = SUCCEED; /* Return value */ |
2985 | | |
2986 | 563 | FUNC_ENTER_NOAPI(FAIL) |
2987 | | |
2988 | | /* Sanity checks */ |
2989 | 563 | assert(space); |
2990 | | |
2991 | | /* Allocate and initialize the iterator */ |
2992 | 563 | if (NULL == (iter = H5FL_MALLOC(H5S_sel_iter_t))) |
2993 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTALLOC, FAIL, "can't allocate iterator"); |
2994 | 563 | if (H5S_select_iter_init(iter, space, 1, 0) < 0) |
2995 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to initialize memory selection information"); |
2996 | 563 | iter_init = true; |
2997 | | |
2998 | | /* Get list of sequences for selection, to check if it is contiguous */ |
2999 | 563 | if (H5S_SELECT_ITER_GET_SEQ_LIST(iter, (size_t)1, (size_t)-1, &nseq_tmp, &nelem_tmp, &sel_off, &sel_len) < |
3000 | 563 | 0) |
3001 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTNEXT, FAIL, "sequence length generation failed"); |
3002 | | |
3003 | | /* If the first sequence includes all the elements selected in this piece, it it contiguous */ |
3004 | 563 | H5_CHECK_OVERFLOW(space->select.num_elem, hsize_t, size_t); |
3005 | 563 | if (sel_len == (size_t)space->select.num_elem) { |
3006 | 563 | if (is_contig) |
3007 | 563 | *is_contig = true; |
3008 | 563 | if (off) |
3009 | 563 | *off = sel_off; |
3010 | 563 | if (len) |
3011 | 0 | *len = sel_len; |
3012 | 563 | } |
3013 | 0 | else if (is_contig) |
3014 | 0 | *is_contig = false; |
3015 | | |
3016 | 563 | done: |
3017 | 563 | if (iter_init && H5S_SELECT_ITER_RELEASE(iter) < 0) |
3018 | 0 | HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't release selection iterator"); |
3019 | 563 | if (iter) |
3020 | 563 | iter = H5FL_FREE(H5S_sel_iter_t, iter); |
3021 | | |
3022 | 563 | FUNC_LEAVE_NOAPI(ret_value) |
3023 | 563 | } /* end H5S_select_contig_block() */ |
3024 | | |
3025 | | /*-------------------------------------------------------------------------- |
3026 | | NAME |
3027 | | H5Ssel_iter_reset |
3028 | | PURPOSE |
3029 | | Resets a dataspace selection iterator back to an initial state. |
3030 | | USAGE |
3031 | | herr_t H5Ssel_iter_reset(sel_iter_id,space_id) |
3032 | | hid_t sel_iter_id; IN: ID of the dataspace selection iterator to |
3033 | | reset |
3034 | | hid_t space_id; IN: ID of the dataspace with selection to |
3035 | | iterate over |
3036 | | RETURNS |
3037 | | Non-negative on success / Negative on failure |
3038 | | DESCRIPTION |
3039 | | Resets a dataspace selection iterator back to an initial state so that |
3040 | | the iterator may be used for iteration once again. |
3041 | | GLOBAL VARIABLES |
3042 | | COMMENTS, BUGS, ASSUMPTIONS |
3043 | | EXAMPLES |
3044 | | REVISION LOG |
3045 | | --------------------------------------------------------------------------*/ |
3046 | | herr_t |
3047 | | H5Ssel_iter_reset(hid_t sel_iter_id, hid_t space_id) |
3048 | 0 | { |
3049 | 0 | H5S_sel_iter_t *sel_iter; |
3050 | 0 | H5S_t *space; |
3051 | 0 | herr_t ret_value = SUCCEED; |
3052 | |
|
3053 | 0 | FUNC_ENTER_API(FAIL) |
3054 | | |
3055 | | /* Check args */ |
3056 | 0 | if (NULL == (sel_iter = (H5S_sel_iter_t *)H5I_object_verify(sel_iter_id, H5I_SPACE_SEL_ITER))) |
3057 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace selection iterator"); |
3058 | 0 | if (NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE))) |
3059 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace"); |
3060 | | |
3061 | | /* Call selection type-specific release routine */ |
3062 | 0 | if (H5S_SELECT_ITER_RELEASE(sel_iter) < 0) |
3063 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, |
3064 | 0 | "problem releasing a selection iterator's type-specific info"); |
3065 | | |
3066 | | /* Simply re-initialize iterator */ |
3067 | 0 | if (H5S_select_iter_init(sel_iter, space, sel_iter->elmt_size, sel_iter->flags) < 0) |
3068 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "unable to re-initialize selection iterator"); |
3069 | | |
3070 | 0 | done: |
3071 | 0 | FUNC_LEAVE_API(ret_value) |
3072 | 0 | } /* end H5Ssel_iter_reset() */ |
3073 | | |
3074 | | /*------------------------------------------------------------------------- |
3075 | | * Function: H5S__sel_iter_close_cb |
3076 | | * |
3077 | | * Purpose: Called when the ref count reaches zero on a selection iterator's ID |
3078 | | * |
3079 | | * Return: Non-negative on success / Negative on failure |
3080 | | * |
3081 | | *------------------------------------------------------------------------- |
3082 | | */ |
3083 | | herr_t |
3084 | | H5S__sel_iter_close_cb(void *_sel_iter, void H5_ATTR_UNUSED **request) |
3085 | 0 | { |
3086 | 0 | H5S_sel_iter_t *sel_iter = (H5S_sel_iter_t *)_sel_iter; /* The selection iterator to close */ |
3087 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
3088 | |
|
3089 | 0 | FUNC_ENTER_PACKAGE |
3090 | | |
3091 | | /* Sanity check */ |
3092 | 0 | assert(sel_iter); |
3093 | | |
3094 | | /* Close the selection iterator object */ |
3095 | 0 | if (H5S_sel_iter_close(sel_iter) < 0) |
3096 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CLOSEERROR, FAIL, "unable to close selection iterator"); |
3097 | | |
3098 | 0 | done: |
3099 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
3100 | 0 | } /* end H5S__sel_iter_close_cb() */ |
3101 | | |
3102 | | /*------------------------------------------------------------------------- |
3103 | | * Function: H5S_sel_iter_close |
3104 | | * |
3105 | | * Purpose: Releases a dataspace selection iterator and its memory. |
3106 | | * |
3107 | | * Return: Non-negative on success / Negative on failure |
3108 | | * |
3109 | | *------------------------------------------------------------------------- |
3110 | | */ |
3111 | | herr_t |
3112 | | H5S_sel_iter_close(H5S_sel_iter_t *sel_iter) |
3113 | 0 | { |
3114 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
3115 | |
|
3116 | 0 | FUNC_ENTER_NOAPI(FAIL) |
3117 | | |
3118 | | /* Sanity check */ |
3119 | 0 | assert(sel_iter); |
3120 | | |
3121 | | /* Call selection type-specific release routine */ |
3122 | 0 | if (H5S_SELECT_ITER_RELEASE(sel_iter) < 0) |
3123 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, |
3124 | 0 | "problem releasing a selection iterator's type-specific info"); |
3125 | | |
3126 | | /* Release the structure */ |
3127 | 0 | sel_iter = H5FL_FREE(H5S_sel_iter_t, sel_iter); |
3128 | |
|
3129 | 0 | done: |
3130 | 0 | FUNC_LEAVE_NOAPI(ret_value) |
3131 | 0 | } /* end H5S_sel_iter_close() */ |
3132 | | |
3133 | | /*-------------------------------------------------------------------------- |
3134 | | NAME |
3135 | | H5Ssel_iter_close |
3136 | | PURPOSE |
3137 | | Close a dataspace selection iterator |
3138 | | USAGE |
3139 | | herr_t H5Ssel_iter_close(sel_iter_id) |
3140 | | hid_t sel_iter_id; IN: ID of the dataspace selection iterator to close |
3141 | | RETURNS |
3142 | | Non-negative on success / Negative on failure |
3143 | | DESCRIPTION |
3144 | | Close a dataspace selection iterator, releasing its state. |
3145 | | PROGRAMMER |
3146 | | GLOBAL VARIABLES |
3147 | | COMMENTS, BUGS, ASSUMPTIONS |
3148 | | EXAMPLES |
3149 | | REVISION LOG |
3150 | | --------------------------------------------------------------------------*/ |
3151 | | herr_t |
3152 | | H5Ssel_iter_close(hid_t sel_iter_id) |
3153 | 0 | { |
3154 | 0 | herr_t ret_value = SUCCEED; /* Return value */ |
3155 | |
|
3156 | 0 | FUNC_ENTER_API(FAIL) |
3157 | | |
3158 | | /* Check args */ |
3159 | 0 | if (NULL == H5I_object_verify(sel_iter_id, H5I_SPACE_SEL_ITER)) |
3160 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_BADTYPE, FAIL, "not a dataspace selection iterator"); |
3161 | | |
3162 | | /* When the reference count reaches zero the resources are freed */ |
3163 | 0 | if (H5I_dec_app_ref(sel_iter_id) < 0) |
3164 | 0 | HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "problem freeing dataspace selection iterator ID"); |
3165 | | |
3166 | 0 | done: |
3167 | | FUNC_LEAVE_API(ret_value) |
3168 | 0 | } /* end H5Ssel_iter_close() */ |