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