1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * Copyright by The HDF Group. *
3 * Copyright by the Board of Trustees of the University of Illinois. *
4 * All rights reserved. *
5 * *
6 * This file is part of HDF5. The full HDF5 copyright notice, including *
7 * terms governing use, modification, and redistribution, is contained in *
8 * the COPYING file, which can be found at the root of the source code *
9 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. *
10 * If you do not have access to either file, you may request a copy from *
11 * help@hdfgroup.org. *
12 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14 /****************/
15 /* Module Setup */
16 /****************/
17
18 #define H5D_PACKAGE /*suppress error about including H5Dpkg */
19
20 /* Interface initialization */
21 #define H5_INTERFACE_INIT_FUNC H5D__init_pub_interface
22
23
24 /***********/
25 /* Headers */
26 /***********/
27 #include "H5private.h" /* Generic Functions */
28 #include "H5Dpkg.h" /* Datasets */
29 #include "H5Eprivate.h" /* Error handling */
30 #include "H5FLprivate.h" /* Free lists */
31 #include "H5Iprivate.h" /* IDs */
32
33
34 /****************/
35 /* Local Macros */
36 /****************/
37
38
39 /******************/
40 /* Local Typedefs */
41 /******************/
42
43
44 /********************/
45 /* Local Prototypes */
46 /********************/
47
48
49 /*********************/
50 /* Package Variables */
51 /*********************/
52
53 /* Declare extern the free list to manage blocks of VL data */
54 H5FL_BLK_EXTERN(vlen_vl_buf);
55
56 /* Declare extern the free list to manage other blocks of VL data */
57 H5FL_BLK_EXTERN(vlen_fl_buf);
58
59
60 /*****************************/
61 /* Library Private Variables */
62 /*****************************/
63
64 /* Declare extern the free list to manage blocks of type conversion data */
65 H5FL_BLK_EXTERN(type_conv);
66
67
68 /*******************/
69 /* Local Variables */
70 /*******************/
71
72
73
74 /*--------------------------------------------------------------------------
75 NAME
76 H5D__init_pub_interface -- Initialize interface-specific information
77 USAGE
78 herr_t H5D__init_pub_interface()
79 RETURNS
80 Non-negative on success/Negative on failure
81 DESCRIPTION
82 Initializes any interface-specific data or routines. (Just calls
83 H5D_init() currently).
84
85 --------------------------------------------------------------------------*/
86 static herr_t
H5D__init_pub_interface(void)87 H5D__init_pub_interface(void)
88 {
89 FUNC_ENTER_STATIC_NOERR
90
91 FUNC_LEAVE_NOAPI(H5D_init())
92 } /* H5D__init_pub_interface() */
93
94
95 /*--------------------------------------------------------------------------
96 NAME
97 H5D__term_pub_interface -- Terminate interface
98 USAGE
99 herr_t H5D__term_pub_interface()
100 RETURNS
101 Non-negative on success/Negative on failure
102 DESCRIPTION
103 Terminates interface. (Just resets H5_interface_initialize_g
104 currently).
105
106 --------------------------------------------------------------------------*/
107 herr_t
H5D__term_pub_interface(void)108 H5D__term_pub_interface(void)
109 {
110 FUNC_ENTER_PACKAGE_NOERR
111
112 /* Mark closed */
113 H5_interface_initialize_g = 0;
114
115 FUNC_LEAVE_NOAPI(0)
116 } /* H5D__term_pub_interface() */
117
118
119 /*-------------------------------------------------------------------------
120 * Function: H5Dcreate2
121 *
122 * Purpose: Creates a new dataset named NAME at LOC_ID, opens the
123 * dataset for access, and associates with that dataset constant
124 * and initial persistent properties including the type of each
125 * datapoint as stored in the file (TYPE_ID), the size of the
126 * dataset (SPACE_ID), and other initial miscellaneous
127 * properties (DCPL_ID).
128 *
129 * All arguments are copied into the dataset, so the caller is
130 * allowed to derive new types, dataspaces, and creation
131 * parameters from the old ones and reuse them in calls to
132 * create other datasets.
133 *
134 * Return: Success: The object ID of the new dataset. At this
135 * point, the dataset is ready to receive its
136 * raw data. Attempting to read raw data from
137 * the dataset will probably return the fill
138 * value. The dataset should be closed when the
139 * caller is no longer interested in it.
140 *
141 * Failure: FAIL
142 *
143 * Programmer: Quincey Koziol
144 * Thursday, April 5, 2007
145 *
146 *-------------------------------------------------------------------------
147 */
148 hid_t
H5Dcreate2(hid_t loc_id,const char * name,hid_t type_id,hid_t space_id,hid_t lcpl_id,hid_t dcpl_id,hid_t dapl_id)149 H5Dcreate2(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
150 hid_t lcpl_id, hid_t dcpl_id, hid_t dapl_id)
151 {
152 H5G_loc_t loc; /* Object location to insert dataset into */
153 H5D_t *dset = NULL; /* New dataset's info */
154 const H5S_t *space; /* Dataspace for dataset */
155 hid_t ret_value; /* Return value */
156
157 FUNC_ENTER_API(FAIL)
158 H5TRACE7("i", "i*siiiii", loc_id, name, type_id, space_id, lcpl_id, dcpl_id,
159 dapl_id);
160
161 /* Check arguments */
162 if(H5G_loc(loc_id, &loc) < 0)
163 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID")
164 if(H5I_DATATYPE != H5I_get_type(type_id))
165 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype ID")
166 if(NULL == (space = (const H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
167 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace ID")
168
169 /* Get correct property list */
170 if(H5P_DEFAULT == lcpl_id)
171 lcpl_id = H5P_LINK_CREATE_DEFAULT;
172 else
173 if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
174 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list")
175
176 /* Get correct property list */
177 if(H5P_DEFAULT == dcpl_id)
178 dcpl_id = H5P_DATASET_CREATE_DEFAULT;
179 else
180 if(TRUE != H5P_isa_class(dcpl_id, H5P_DATASET_CREATE))
181 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list ID")
182
183 /* Get correct property list */
184 if(H5P_DEFAULT == dapl_id)
185 dapl_id = H5P_DATASET_ACCESS_DEFAULT;
186 else
187 if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS))
188 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
189
190 /* Create the new dataset & get its ID */
191 if(NULL == (dset = H5D__create_named(&loc, name, type_id, space, lcpl_id, dcpl_id, dapl_id, H5AC_dxpl_id)))
192 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset")
193 if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0)
194 HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset")
195
196 done:
197 if(ret_value < 0)
198 if(dset && H5D_close(dset) < 0)
199 HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset")
200
201 FUNC_LEAVE_API(ret_value)
202 } /* end H5Dcreate2() */
203
204
205 /*-------------------------------------------------------------------------
206 * Function: H5Dcreate_anon
207 *
208 * Purpose: Creates a new dataset named NAME at LOC_ID, opens the
209 * dataset for access, and associates with that dataset constant
210 * and initial persistent properties including the type of each
211 * datapoint as stored in the file (TYPE_ID), the size of the
212 * dataset (SPACE_ID), and other initial miscellaneous
213 * properties (DCPL_ID).
214 *
215 * All arguments are copied into the dataset, so the caller is
216 * allowed to derive new types, dataspaces, and creation
217 * parameters from the old ones and reuse them in calls to
218 * create other datasets.
219 *
220 * The resulting ID should be linked into the file with
221 * H5Olink or it will be deleted when closed.
222 *
223 * Return: Success: The object ID of the new dataset. At this
224 * point, the dataset is ready to receive its
225 * raw data. Attempting to read raw data from
226 * the dataset will probably return the fill
227 * value. The dataset should be linked into
228 * the group hierarchy before being closed or
229 * it will be deleted. The dataset should be
230 * closed when the caller is no longer interested
231 * in it.
232 *
233 * Failure: FAIL
234 *
235 * Programmer: James Laird
236 * Tuesday, January 24, 2006
237 *
238 *-------------------------------------------------------------------------
239 */
240 hid_t
H5Dcreate_anon(hid_t loc_id,hid_t type_id,hid_t space_id,hid_t dcpl_id,hid_t dapl_id)241 H5Dcreate_anon(hid_t loc_id, hid_t type_id, hid_t space_id, hid_t dcpl_id,
242 hid_t dapl_id)
243 {
244 H5G_loc_t loc; /* Object location to insert dataset into */
245 H5D_t *dset = NULL; /* New dataset's info */
246 const H5S_t *space; /* Dataspace for dataset */
247 hid_t ret_value; /* Return value */
248
249 FUNC_ENTER_API(FAIL)
250 H5TRACE5("i", "iiiii", loc_id, type_id, space_id, dcpl_id, dapl_id);
251
252 /* Check arguments */
253 if(H5G_loc(loc_id, &loc) < 0)
254 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID")
255 if(H5I_DATATYPE != H5I_get_type(type_id))
256 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype ID")
257 if(NULL == (space = (const H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
258 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace ID")
259 if(H5P_DEFAULT == dcpl_id)
260 dcpl_id = H5P_DATASET_CREATE_DEFAULT;
261 else
262 if(TRUE != H5P_isa_class(dcpl_id, H5P_DATASET_CREATE))
263 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list ID")
264
265 /* Get correct property list */
266 if(H5P_DEFAULT == dapl_id)
267 dapl_id = H5P_DATASET_ACCESS_DEFAULT;
268 else
269 if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS))
270 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
271
272 /* build and open the new dataset */
273 if(NULL == (dset = H5D__create(loc.oloc->file, type_id, space, dcpl_id, dapl_id, H5AC_dxpl_id)))
274 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset")
275
276 /* Register the new dataset to get an ID for it */
277 if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0)
278 HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset")
279
280 done:
281 /* Release the dataset's object header, if it was created */
282 if(dset) {
283 H5O_loc_t *oloc; /* Object location for dataset */
284
285 /* Get the new dataset's object location */
286 if(NULL == (oloc = H5D_oloc(dset)))
287 HDONE_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "unable to get object location of dataset")
288
289 /* Decrement refcount on dataset's object header in memory */
290 if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0)
291 HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object")
292 } /* end if */
293
294 /* Cleanup on failure */
295 if(ret_value < 0)
296 if(dset && H5D_close(dset) < 0)
297 HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset")
298
299 FUNC_LEAVE_API(ret_value)
300 } /* end H5Dcreate_anon() */
301
302
303 /*-------------------------------------------------------------------------
304 * Function: H5Dopen2
305 *
306 * Purpose: Finds a dataset named NAME at LOC_ID, opens it, and returns
307 * its ID. The dataset should be close when the caller is no
308 * longer interested in it.
309 *
310 * Takes a dataset access property list
311 *
312 * Return: Success: A new dataset ID
313 * Failure: FAIL
314 *
315 * Programmer: James Laird
316 * Thursday, July 27, 2006
317 *
318 *-------------------------------------------------------------------------
319 */
320 hid_t
H5Dopen2(hid_t loc_id,const char * name,hid_t dapl_id)321 H5Dopen2(hid_t loc_id, const char *name, hid_t dapl_id)
322 {
323 H5D_t *dset = NULL;
324 H5G_loc_t loc; /* Object location of group */
325 H5G_loc_t dset_loc; /* Object location of dataset */
326 H5G_name_t path; /* Dataset group hier. path */
327 H5O_loc_t oloc; /* Dataset object location */
328 H5O_type_t obj_type; /* Type of object at location */
329 hbool_t loc_found = FALSE; /* Location at 'name' found */
330 hid_t dxpl_id = H5AC_ind_dxpl_id; /* dxpl to use to open datset */
331 hid_t ret_value;
332
333 FUNC_ENTER_API(FAIL)
334 H5TRACE3("i", "i*si", loc_id, name, dapl_id);
335
336 /* Check args */
337 if(H5G_loc(loc_id, &loc) < 0)
338 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
339 if(!name || !*name)
340 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
341
342 /* Get correct property list */
343 if(H5P_DEFAULT == dapl_id)
344 dapl_id = H5P_DATASET_ACCESS_DEFAULT;
345 else
346 if(TRUE != H5P_isa_class(dapl_id, H5P_DATASET_ACCESS))
347 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset access property list")
348
349 /* Set up dataset location to fill in */
350 dset_loc.oloc = &oloc;
351 dset_loc.path = &path;
352 H5G_loc_reset(&dset_loc);
353
354 /* Find the dataset object */
355 if(H5G_loc_find(&loc, name, &dset_loc, dapl_id, dxpl_id) < 0)
356 HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found")
357 loc_found = TRUE;
358
359 /* Check that the object found is the correct type */
360 if(H5O_obj_type(&oloc, &obj_type, dxpl_id) < 0)
361 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get object type")
362 if(obj_type != H5O_TYPE_DATASET)
363 HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset")
364
365 /* Open the dataset */
366 if(NULL == (dset = H5D_open(&dset_loc, dapl_id, dxpl_id)))
367 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset")
368
369 /* Register an atom for the dataset */
370 if((ret_value = H5I_register(H5I_DATASET, dset, TRUE)) < 0)
371 HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't register dataset atom")
372
373 done:
374 if(ret_value < 0) {
375 if(dset) {
376 if(H5D_close(dset) < 0)
377 HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset")
378 } /* end if */
379 else {
380 if(loc_found && H5G_loc_free(&dset_loc) < 0)
381 HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't free location")
382 } /* end else */
383 } /* end if */
384
385 FUNC_LEAVE_API(ret_value)
386 } /* end H5Dopen2() */
387
388
389 /*-------------------------------------------------------------------------
390 * Function: H5Dclose
391 *
392 * Purpose: Closes access to a dataset (DATASET_ID) and releases
393 * resources used by it. It is illegal to subsequently use that
394 * same dataset ID in calls to other dataset functions.
395 *
396 * Return: Non-negative on success/Negative on failure
397 *
398 * Programmer: Robb Matzke
399 * Thursday, December 4, 1997
400 *
401 *-------------------------------------------------------------------------
402 */
403 herr_t
H5Dclose(hid_t dset_id)404 H5Dclose(hid_t dset_id)
405 {
406 herr_t ret_value = SUCCEED; /* Return value */
407
408 FUNC_ENTER_API(FAIL)
409 H5TRACE1("e", "i", dset_id);
410
411 /* Check args */
412 if(NULL == H5I_object_verify(dset_id, H5I_DATASET))
413 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
414
415 /*
416 * Decrement the counter on the dataset. It will be freed if the count
417 * reaches zero.
418 *
419 * Pass in TRUE for the 3rd parameter to tell the function to remove
420 * dataset's ID even though the freeing function might fail. Please
421 * see the comments in H5I_dec_ref for details. (SLU - 2010/9/7)
422 */
423 if(H5I_dec_app_ref_always_close(dset_id) < 0)
424 HGOTO_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't decrement count on dataset ID")
425
426 done:
427 FUNC_LEAVE_API(ret_value)
428 } /* end H5Dclose() */
429
430
431 /*-------------------------------------------------------------------------
432 * Function: H5Dget_space
433 *
434 * Purpose: Returns a copy of the file dataspace for a dataset.
435 *
436 * Return: Success: ID for a copy of the dataspace. The data
437 * space should be released by calling
438 * H5Sclose().
439 *
440 * Failure: FAIL
441 *
442 * Programmer: Robb Matzke
443 * Wednesday, January 28, 1998
444 *
445 *-------------------------------------------------------------------------
446 */
447 hid_t
H5Dget_space(hid_t dset_id)448 H5Dget_space(hid_t dset_id)
449 {
450 H5D_t *dset = NULL;
451 hid_t ret_value;
452
453 FUNC_ENTER_API(FAIL)
454 H5TRACE1("i", "i", dset_id);
455
456 /* Check args */
457 if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
458 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
459
460 if((ret_value = H5D_get_space(dset)) < 0)
461 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get dataspace")
462
463 done:
464 FUNC_LEAVE_API(ret_value)
465 }
466
467
468 /*-------------------------------------------------------------------------
469 * Function: H5Dget_space_status
470 *
471 * Purpose: Returns the status of dataspace allocation.
472 *
473 * Return:
474 * Success: Non-negative
475 *
476 * Failture: Negative
477 *
478 * Programmer: Raymond Lu
479 *
480 *-------------------------------------------------------------------------
481 */
482 herr_t
H5Dget_space_status(hid_t dset_id,H5D_space_status_t * allocation)483 H5Dget_space_status(hid_t dset_id, H5D_space_status_t *allocation)
484 {
485 H5D_t *dset = NULL;
486 herr_t ret_value = SUCCEED;
487
488 FUNC_ENTER_API(FAIL)
489 H5TRACE2("e", "i*Ds", dset_id, allocation);
490
491 /* Check arguments */
492 if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
493 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
494
495 /* Read dataspace address and return */
496 if(H5D__get_space_status(dset, allocation, H5AC_ind_dxpl_id) < 0)
497 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get space status")
498
499 done:
500 FUNC_LEAVE_API(ret_value)
501 }
502
503
504 /*-------------------------------------------------------------------------
505 * Function: H5Dget_type
506 *
507 * Purpose: Returns a copy of the file datatype for a dataset.
508 *
509 * Return: Success: ID for a copy of the datatype. The data
510 * type should be released by calling
511 * H5Tclose().
512 *
513 * Failure: FAIL
514 *
515 * Programmer: Robb Matzke
516 * Tuesday, February 3, 1998
517 *
518 *-------------------------------------------------------------------------
519 */
520 hid_t
H5Dget_type(hid_t dset_id)521 H5Dget_type(hid_t dset_id)
522 {
523
524 H5D_t *dset; /* Dataset */
525 hid_t ret_value; /* Return value */
526
527 FUNC_ENTER_API(FAIL)
528 H5TRACE1("i", "i", dset_id);
529
530 /* Check args */
531 if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
532 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
533
534 if((ret_value = H5D_get_type(dset)) < 0)
535 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to get dataspace")
536
537 done:
538 FUNC_LEAVE_API(ret_value)
539 } /* end H5Dget_type() */
540
541
542 /*-------------------------------------------------------------------------
543 * Function: H5Dget_create_plist
544 *
545 * Purpose: Returns a copy of the dataset creation property list.
546 *
547 * Return: Success: ID for a copy of the dataset creation
548 * property list. The template should be
549 * released by calling H5P_close().
550 *
551 * Failure: FAIL
552 *
553 * Programmer: Robb Matzke
554 * Tuesday, February 3, 1998
555 *
556 *-------------------------------------------------------------------------
557 */
558 hid_t
H5Dget_create_plist(hid_t dset_id)559 H5Dget_create_plist(hid_t dset_id)
560 {
561 H5D_t *dataset; /* Dataset structure */
562 hid_t ret_value = SUCCEED; /* Return value */
563
564 FUNC_ENTER_API(FAIL)
565 H5TRACE1("i", "i", dset_id);
566
567 /* Check args */
568 if(NULL == (dataset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
569 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
570
571 if((ret_value = H5D_get_create_plist(dataset)) < 0)
572 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't get creation plist")
573
574 done:
575 FUNC_LEAVE_API(ret_value)
576 } /* end H5Dget_create_plist() */
577
578
579 /*-------------------------------------------------------------------------
580 * Function: H5Dget_access_plist
581 *
582 * Purpose: Returns a copy of the dataset creation property list.
583 *
584 * Description: H5Dget_access_plist returns the dataset access property
585 * list identifier of the specified dataset.
586 *
587 * The chunk cache parameters in the returned property lists will be
588 * those used by the dataset. If the properties in the file access
589 * property list were used to determine the dataset’s chunk cache
590 * configuration, then those properties will be present in the
591 * returned dataset access property list. If the dataset does not
592 * use a chunked layout, then the chunk cache properties will be set
593 * to the default. The chunk cache properties in the returned list
594 * are considered to be “set”, and any use of this list will override
595 * the corresponding properties in the file’s file access property
596 * list.
597 *
598 * All link access properties in the returned list will be set to the
599 * default values.
600 *
601 * Return: Success: ID for a copy of the dataset access
602 * property list. The template should be
603 * released by calling H5Pclose().
604 *
605 * Failure: FAIL
606 *
607 * Programmer: Neil Fortner
608 * Wednesday, October 29, 2008
609 *
610 *-------------------------------------------------------------------------
611 */
612 hid_t
H5Dget_access_plist(hid_t dset_id)613 H5Dget_access_plist(hid_t dset_id)
614 {
615 H5D_t *dset; /* Dataset structure */
616 hid_t ret_value; /* Return value */
617
618 FUNC_ENTER_API(FAIL)
619 H5TRACE1("i", "i", dset_id);
620
621 /* Check args */
622 if (NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
623 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
624
625 if((ret_value = H5D_get_access_plist(dset)) < 0)
626 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "Can't get access plist")
627
628 done:
629 FUNC_LEAVE_API(ret_value)
630 } /* end H5Dget_access_plist() */
631
632
633 /*-------------------------------------------------------------------------
634 * Function: H5Dget_storage_size
635 *
636 * Purpose: Returns the amount of storage that is required for the
637 * dataset. For chunked datasets this is the number of allocated
638 * chunks times the chunk size.
639 *
640 * Return: Success: The amount of storage space allocated for the
641 * dataset, not counting meta data. The return
642 * value may be zero if no data has been stored.
643 *
644 * Failure: Zero
645 *
646 * Programmer: Robb Matzke
647 * Wednesday, April 21, 1999
648 *
649 *-------------------------------------------------------------------------
650 */
651 hsize_t
H5Dget_storage_size(hid_t dset_id)652 H5Dget_storage_size(hid_t dset_id)
653 {
654 H5D_t *dset; /* Dataset to query */
655 hsize_t ret_value; /* Return value */
656
657 FUNC_ENTER_API(0)
658 H5TRACE1("h", "i", dset_id);
659
660 /* Check args */
661 if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
662 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not a dataset")
663
664 /* Set return value */
665 if(H5D__get_storage_size(dset, H5AC_ind_dxpl_id, &ret_value) < 0)
666 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, 0, "can't get size of dataset's storage")
667
668 done:
669 FUNC_LEAVE_API(ret_value)
670 } /* end H5Dget_storage_size() */
671
672
673 /*-------------------------------------------------------------------------
674 * Function: H5Dget_offset
675 *
676 * Purpose: Returns the address of dataset in file.
677 *
678 * Return: Success: the address of dataset
679 *
680 * Failure: HADDR_UNDEF
681 *
682 * Programmer: Raymond Lu
683 * November 6, 2002
684 *
685 *-------------------------------------------------------------------------
686 */
687 haddr_t
H5Dget_offset(hid_t dset_id)688 H5Dget_offset(hid_t dset_id)
689 {
690 H5D_t *dset; /* Dataset to query */
691 haddr_t ret_value; /* Return value */
692
693 FUNC_ENTER_API(HADDR_UNDEF)
694 H5TRACE1("a", "i", dset_id);
695
696 /* Check args */
697 if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
698 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, HADDR_UNDEF, "not a dataset")
699
700 /* Set return value */
701 ret_value = H5D__get_offset(dset);
702
703 done:
704 FUNC_LEAVE_API(ret_value)
705 } /* end H5Dget_offset() */
706
707
708 /*-------------------------------------------------------------------------
709 * Function: H5Diterate
710 *
711 * Purpose: This routine iterates over all the elements selected in a memory
712 * buffer. The callback function is called once for each element selected
713 * in the dataspace. The selection in the dataspace is modified so
714 * that any elements already iterated over are removed from the selection
715 * if the iteration is interrupted (by the H5D_operator_t function
716 * returning non-zero) in the "middle" of the iteration and may be
717 * re-started by the user where it left off.
718 *
719 * NOTE: Until "subtracting" elements from a selection is implemented,
720 * the selection is not modified.
721 *
722 * Parameters:
723 * void *buf; IN/OUT: Pointer to the buffer in memory containing
724 * the elements to iterate over.
725 * hid_t type_id; IN: Datatype ID for the elements stored in BUF.
726 * hid_t space_id; IN: Dataspace ID for BUF, also contains the
727 * selection to iterate over.
728 * H5D_operator_t op; IN: Function pointer to the routine to be
729 * called for each element in BUF iterated over.
730 * void *operator_data; IN/OUT: Pointer to any user-defined data
731 * associated with the operation.
732 *
733 * Operation information:
734 * H5D_operator_t is defined as:
735 * typedef herr_t (*H5D_operator_t)(void *elem, hid_t type_id,
736 * unsigned ndim, const hsize_t *point, void *operator_data);
737 *
738 * H5D_operator_t parameters:
739 * void *elem; IN/OUT: Pointer to the element in memory containing
740 * the current point.
741 * hid_t type_id; IN: Datatype ID for the elements stored in ELEM.
742 * unsigned ndim; IN: Number of dimensions for POINT array
743 * const hsize_t *point; IN: Array containing the location of the element
744 * within the original dataspace.
745 * void *operator_data; IN/OUT: Pointer to any user-defined data
746 * associated with the operation.
747 *
748 * The return values from an operator are:
749 * Zero causes the iterator to continue, returning zero when all
750 * elements have been processed.
751 * Positive causes the iterator to immediately return that positive
752 * value, indicating short-circuit success. The iterator can be
753 * restarted at the next element.
754 * Negative causes the iterator to immediately return that value,
755 * indicating failure. The iterator can be restarted at the next
756 * element.
757 *
758 * Return: Returns the return value of the last operator if it was non-zero,
759 * or zero if all elements were processed. Otherwise returns a
760 * negative value.
761 *
762 * Programmer: Quincey Koziol
763 * Friday, June 11, 1999
764 *
765 *-------------------------------------------------------------------------
766 */
767 herr_t
H5Diterate(void * buf,hid_t type_id,hid_t space_id,H5D_operator_t op,void * operator_data)768 H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator_t op,
769 void *operator_data)
770 {
771 H5T_t *type; /* Datatype */
772 H5S_t *space; /* Dataspace for iteration */
773 H5S_sel_iter_op_t dset_op; /* Operator for iteration */
774 herr_t ret_value; /* Return value */
775
776 FUNC_ENTER_API(FAIL)
777 H5TRACE5("e", "*xiix*x", buf, type_id, space_id, op, operator_data);
778
779 /* Check args */
780 if(NULL == op)
781 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid operator")
782 if(NULL == buf)
783 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer")
784 if(H5I_DATATYPE != H5I_get_type(type_id))
785 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid datatype")
786 if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
787 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype")
788 if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
789 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace")
790 if(!(H5S_has_extent(space)))
791 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set")
792
793 dset_op.op_type = H5S_SEL_ITER_OP_APP;
794 dset_op.u.app_op.op = op;
795 dset_op.u.app_op.type_id = type_id;
796
797 ret_value = H5S_select_iterate(buf, type, space, &dset_op, operator_data);
798
799 done:
800 FUNC_LEAVE_API(ret_value)
801 } /* end H5Diterate() */
802
803
804 /*-------------------------------------------------------------------------
805 * Function: H5Dvlen_reclaim
806 *
807 * Purpose: Frees the buffers allocated for storing variable-length data
808 * in memory. Only frees the VL data in the selection defined in the
809 * dataspace. The dataset transfer property list is required to find the
810 * correct allocation/free methods for the VL data in the buffer.
811 *
812 * Return: Non-negative on success, negative on failure
813 *
814 * Programmer: Quincey Koziol
815 * Thursday, June 10, 1999
816 *
817 *-------------------------------------------------------------------------
818 */
819 herr_t
H5Dvlen_reclaim(hid_t type_id,hid_t space_id,hid_t plist_id,void * buf)820 H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf)
821 {
822 H5S_t *space; /* Dataspace for iteration */
823 herr_t ret_value; /* Return value */
824
825 FUNC_ENTER_API(FAIL)
826 H5TRACE4("e", "iii*x", type_id, space_id, plist_id, buf);
827
828 /* Check args */
829 if(H5I_DATATYPE != H5I_get_type(type_id) || buf == NULL)
830 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument")
831 if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
832 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace")
833 if(!(H5S_has_extent(space)))
834 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set")
835
836 /* Get the default dataset transfer property list if the user didn't provide one */
837 if(H5P_DEFAULT == plist_id)
838 plist_id = H5P_DATASET_XFER_DEFAULT;
839 else
840 if(TRUE != H5P_isa_class(plist_id, H5P_DATASET_XFER))
841 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
842
843 /* Call internal routine */
844 ret_value = H5D_vlen_reclaim(type_id, space, plist_id, buf);
845
846 done:
847 FUNC_LEAVE_API(ret_value)
848 } /* end H5Dvlen_reclaim() */
849
850
851 /*-------------------------------------------------------------------------
852 * Function: H5Dvlen_get_buf_size
853 *
854 * Purpose: This routine checks the number of bytes required to store the VL
855 * data from the dataset, using the space_id for the selection in the
856 * dataset on disk and the type_id for the memory representation of the
857 * VL data, in memory. The *size value is modified according to how many
858 * bytes are required to store the VL data in memory.
859 *
860 * Implementation: This routine actually performs the read with a custom
861 * memory manager which basically just counts the bytes requested and
862 * uses a temporary memory buffer (through the H5FL API) to make certain
863 * enough space is available to perform the read. Then the temporary
864 * buffer is released and the number of bytes allocated is returned.
865 * Kinda kludgy, but easier than the other method of trying to figure out
866 * the sizes without actually reading the data in... - QAK
867 *
868 * Return: Non-negative on success, negative on failure
869 *
870 * Programmer: Quincey Koziol
871 * Wednesday, August 11, 1999
872 *
873 *-------------------------------------------------------------------------
874 */
875 herr_t
H5Dvlen_get_buf_size(hid_t dataset_id,hid_t type_id,hid_t space_id,hsize_t * size)876 H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id,
877 hsize_t *size)
878 {
879 H5D_vlen_bufsize_t vlen_bufsize = {0, 0, 0, 0, 0, 0, 0};
880 H5D_t *dset; /* Dataset for operation */
881 H5S_t *fspace = NULL; /* Dataset's dataspace */
882 H5S_t *mspace = NULL; /* Memory dataspace */
883 char bogus; /* bogus value to pass to H5Diterate() */
884 H5S_t *space; /* Dataspace for iteration */
885 H5P_genplist_t *plist; /* Property list */
886 H5T_t *type; /* Datatype */
887 H5S_sel_iter_op_t dset_op; /* Operator for iteration */
888 herr_t ret_value; /* Return value */
889
890 FUNC_ENTER_API(FAIL)
891 H5TRACE4("e", "iii*h", dataset_id, type_id, space_id, size);
892
893 /* Check args */
894 if(H5I_DATASET != H5I_get_type(dataset_id) ||
895 H5I_DATATYPE != H5I_get_type(type_id) || size == NULL)
896 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument")
897 if(NULL == (dset = (H5D_t *)H5I_object(dataset_id)))
898 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
899 if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
900 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype")
901 if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
902 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace")
903 if(!(H5S_has_extent(space)))
904 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set")
905
906 /* Save the dataset */
907 vlen_bufsize.dset = dset;
908
909 /* Get a copy of the dataset's dataspace */
910 if(NULL == (fspace = H5S_copy(dset->shared->space, FALSE, TRUE)))
911 HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "unable to get dataspace")
912 vlen_bufsize.fspace = fspace;
913
914 /* Create a scalar for the memory dataspace */
915 if(NULL == (mspace = H5S_create(H5S_SCALAR)))
916 HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create dataspace")
917 vlen_bufsize.mspace = mspace;
918
919 /* Grab the temporary buffers required */
920 if(NULL == (vlen_bufsize.fl_tbuf = H5FL_BLK_MALLOC(vlen_fl_buf, (size_t)1)))
921 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available")
922 if(NULL == (vlen_bufsize.vl_tbuf = H5FL_BLK_MALLOC(vlen_vl_buf, (size_t)1)))
923 HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available")
924
925 /* Change to the custom memory allocation routines for reading VL data */
926 if((vlen_bufsize.xfer_pid = H5P_create_id(H5P_CLS_DATASET_XFER_g, FALSE)) < 0)
927 HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "no dataset xfer plists available")
928
929 /* Get the property list struct */
930 if(NULL == (plist = (H5P_genplist_t *)H5I_object(vlen_bufsize.xfer_pid)))
931 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset transfer property list")
932
933 /* Set the memory manager to the special allocation routine */
934 if(H5P_set_vlen_mem_manager(plist, H5D__vlen_get_buf_size_alloc, &vlen_bufsize, NULL, NULL) < 0)
935 HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "can't set VL data allocation routine")
936
937 /* Set the initial number of bytes required */
938 vlen_bufsize.size = 0;
939
940 /* Call H5S_select_iterate with args, etc. */
941 dset_op.op_type = H5S_SEL_ITER_OP_APP;
942 dset_op.u.app_op.op = H5D__vlen_get_buf_size;
943 dset_op.u.app_op.type_id = type_id;
944
945 ret_value = H5S_select_iterate(&bogus, type, space, &dset_op, &vlen_bufsize);
946
947 /* Get the size if we succeeded */
948 if(ret_value >= 0)
949 *size = vlen_bufsize.size;
950
951 done:
952 if(fspace && H5S_close(fspace) < 0)
953 HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace")
954 if(mspace && H5S_close(mspace) < 0)
955 HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace")
956 if(vlen_bufsize.fl_tbuf != NULL)
957 vlen_bufsize.fl_tbuf = H5FL_BLK_FREE(vlen_fl_buf, vlen_bufsize.fl_tbuf);
958 if(vlen_bufsize.vl_tbuf != NULL)
959 vlen_bufsize.vl_tbuf = H5FL_BLK_FREE(vlen_vl_buf, vlen_bufsize.vl_tbuf);
960 if(vlen_bufsize.xfer_pid > 0 && H5I_dec_ref(vlen_bufsize.xfer_pid) < 0)
961 HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to decrement ref count on property list")
962
963 FUNC_LEAVE_API(ret_value)
964 } /* end H5Dvlen_get_buf_size() */
965
966
967 /*-------------------------------------------------------------------------
968 * Function: H5Dset_extent
969 *
970 * Purpose: Modifies the dimensions of a dataset.
971 * Can change to a smaller dimension.
972 *
973 * Return: Non-negative on success, negative on failure
974 *
975 * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
976 * April 9, 2002
977 *
978 *-------------------------------------------------------------------------
979 */
980 herr_t
H5Dset_extent(hid_t dset_id,const hsize_t size[])981 H5Dset_extent(hid_t dset_id, const hsize_t size[])
982 {
983 H5D_t *dset; /* Dataset for this operation */
984 herr_t ret_value = SUCCEED; /* Return value */
985
986 FUNC_ENTER_API(FAIL)
987 H5TRACE2("e", "i*h", dset_id, size);
988
989 /* Check args */
990 if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
991 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
992 if(!size)
993 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no size specified")
994
995 /* Private function */
996 if(H5D__set_extent(dset, size, H5AC_dxpl_id) < 0)
997 HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to set extend dataset")
998
999 done:
1000 FUNC_LEAVE_API(ret_value)
1001 } /* end H5Dset_extent() */
1002
1003
1004 /*-------------------------------------------------------------------------
1005 * Function: H5Dget_chunk_storage_size
1006 *
1007 * Purpose: Returns the size of an allocated of chunk.
1008 *
1009 * Return: Non-negative on success, negative on failure
1010 *
1011 * Programmer: Matthew Strong (GE Healthcare)
1012 * 20 October 2016
1013 *
1014 *-------------------------------------------------------------------------
1015 */
1016 herr_t
H5Dget_chunk_storage_size(hid_t dset_id,const hsize_t * offset,hsize_t * chunk_nbytes)1017 H5Dget_chunk_storage_size(hid_t dset_id, const hsize_t *offset, hsize_t *chunk_nbytes)
1018 {
1019 H5D_t *dset = NULL;
1020 herr_t ret_value = SUCCEED;
1021
1022 FUNC_ENTER_API(FAIL)
1023 H5TRACE3("e", "i*h*h", dset_id, offset, chunk_nbytes);
1024
1025 /* Check arguments */
1026 if(NULL == (dset = (H5D_t *)H5I_object_verify(dset_id, H5I_DATASET)))
1027 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
1028 if( NULL == offset )
1029 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument (null)")
1030 if( NULL == chunk_nbytes )
1031 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument (null)")
1032
1033 if(H5D_CHUNKED != dset->shared->layout.type)
1034 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a chunked dataset")
1035
1036 /* Call private function */
1037 if(H5D__get_chunk_storage_size(dset, H5AC_ind_dxpl_id, offset, chunk_nbytes) < 0)
1038 HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get storage size of chunk")
1039
1040 done:
1041 FUNC_LEAVE_API(ret_value);
1042 }
1043
1044