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