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 *
16 * Created: H5Gloc.c
17 * Sep 13 2005
18 * Quincey Koziol <koziol@ncsa.uiuc.edu>
19 *
20 * Purpose: Functions for working with group "locations"
21 *
22 *-------------------------------------------------------------------------
23 */
24
25 /****************/
26 /* Module Setup */
27 /****************/
28
29 #include "H5Gmodule.h" /* This source code file is part of the H5G module */
30
31
32 /***********/
33 /* Headers */
34 /***********/
35 #include "H5private.h" /* Generic Functions */
36 #include "H5Aprivate.h" /* Attributes */
37 #include "H5Dprivate.h" /* Datasets */
38 #include "H5Eprivate.h" /* Error handling */
39 #include "H5Gpkg.h" /* Groups */
40 #include "H5Iprivate.h" /* IDs */
41 #include "H5Lprivate.h" /* Links */
42
43
44 /****************/
45 /* Local Macros */
46 /****************/
47
48
49 /******************/
50 /* Local Typedefs */
51 /******************/
52
53 /* User data for looking up an object in a group */
54 typedef struct {
55 /* upward */
56 H5G_loc_t *loc; /* Group location to set */
57 } H5G_loc_fnd_t;
58
59 /* User data for checking if an object exists */
60 typedef struct {
61 /* upward */
62 htri_t exists; /* Whether the object exists */
63 } H5G_loc_exists_t;
64
65 /* User data for looking up an object in a group by index */
66 typedef struct {
67 /* downward */
68 hid_t lapl_id; /* LAPL to use for operation */
69 hid_t dxpl_id; /* DXPL to use for operation */
70 H5_index_t idx_type; /* Index to use */
71 H5_iter_order_t order; /* Iteration order within index */
72 hsize_t n; /* Offset within index */
73
74 /* upward */
75 H5G_loc_t *loc; /* Group location to set */
76 } H5G_loc_fbi_t;
77
78 /* User data for getting an object's info in a group */
79 typedef struct {
80 /* downward */
81 hid_t dxpl_id; /* DXPL to use for operation */
82 hbool_t want_ih_info; /* Whether to retrieve the index & heap info */
83
84 /* upward */
85 H5O_info_t *oinfo; /* Object information to retrieve */
86 } H5G_loc_info_t;
87
88 /* User data for setting an object's comment in a group */
89 typedef struct {
90 /* downward */
91 hid_t dxpl_id; /* DXPL to use for operation */
92 const char *comment; /* Object comment buffer */
93
94 /* upward */
95 } H5G_loc_sc_t;
96
97 /* User data for getting an object's comment in a group */
98 typedef struct {
99 /* downward */
100 hid_t dxpl_id; /* DXPL to use for operation */
101 char *comment; /* Object comment buffer */
102 size_t bufsize; /* Size of object comment buffer */
103
104 /* upward */
105 ssize_t comment_size; /* Actual size of object comment */
106 } H5G_loc_gc_t;
107
108
109 /********************/
110 /* Local Prototypes */
111 /********************/
112
113 /* Group traversal callbacks */
114 static herr_t H5G_loc_find_cb(H5G_loc_t *grp_loc, const char *name,
115 const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
116 H5G_own_loc_t *own_loc);
117 static herr_t H5G_loc_find_by_idx_cb(H5G_loc_t *grp_loc, const char *name,
118 const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
119 H5G_own_loc_t *own_loc);
120 static herr_t H5G_loc_set_comment_cb(H5G_loc_t *grp_loc, const char *name,
121 const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
122 H5G_own_loc_t *own_loc);
123 static herr_t H5G_loc_get_comment_cb(H5G_loc_t *grp_loc, const char *name,
124 const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata,
125 H5G_own_loc_t *own_loc);
126
127
128 /*********************/
129 /* Package Variables */
130 /*********************/
131
132
133 /*****************************/
134 /* Library Private Variables */
135 /*****************************/
136
137
138 /*******************/
139 /* Local Variables */
140 /*******************/
141
142
143
144 /*-------------------------------------------------------------------------
145 * Function: H5G_loc
146 *
147 * Purpose: Given an object ID return a location for the object.
148 *
149 * Return: Success: Group pointer.
150 * Failure: NULL
151 *
152 * Programmer: Quincey Koziol
153 * Tuesday, September 13, 2005
154 *
155 *-------------------------------------------------------------------------
156 */
157 herr_t
H5G_loc(hid_t loc_id,H5G_loc_t * loc)158 H5G_loc(hid_t loc_id, H5G_loc_t *loc)
159 {
160 herr_t ret_value = SUCCEED; /* Return value */
161
162 FUNC_ENTER_NOAPI(FAIL)
163
164 switch(H5I_get_type(loc_id)) {
165 case H5I_FILE:
166 {
167 H5F_t *f;
168
169 /* Get the file struct */
170 if(NULL == (f = (H5F_t *)H5I_object(loc_id)))
171 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file ID")
172
173 /* Construct a group location for root group of the file */
174 if(H5G_root_loc(f, loc) < 0)
175 HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unable to create location for file")
176 } /* end case */
177 break;
178
179 case H5I_GENPROP_CLS:
180 case H5I_GENPROP_LST:
181 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of property list")
182
183 case H5I_ERROR_CLASS:
184 case H5I_ERROR_MSG:
185 case H5I_ERROR_STACK:
186 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of error class, message or stack")
187
188 case H5I_GROUP:
189 {
190 H5G_t *group;
191
192 if(NULL == (group = (H5G_t *)H5I_object(loc_id)))
193 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid group ID")
194 if(NULL == (loc->oloc = H5G_oloc(group)))
195 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of group")
196 if(NULL == (loc->path = H5G_nameof(group)))
197 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of group")
198 } /* end case */
199 break;
200
201 case H5I_DATATYPE:
202 {
203 H5T_t *dt;
204
205 if(NULL == (dt = (H5T_t *)H5I_object(loc_id)))
206 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid type ID")
207 if(NULL == (loc->oloc = H5T_oloc(dt)))
208 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of datatype")
209 if(NULL == (loc->path = H5T_nameof(dt)))
210 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of datatype")
211 } /* end case */
212 break;
213
214 case H5I_DATASPACE:
215 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of dataspace")
216
217 case H5I_DATASET:
218 {
219 H5D_t *dset;
220
221 if(NULL == (dset = (H5D_t *)H5I_object(loc_id)))
222 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid data ID")
223 if(NULL == (loc->oloc = H5D_oloc(dset)))
224 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of dataset")
225 if(NULL == (loc->path = H5D_nameof(dset)))
226 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of dataset")
227 } /* end case */
228 break;
229
230 case H5I_ATTR:
231 {
232 H5A_t *attr;
233
234 if(NULL == (attr = (H5A_t *)H5I_object(loc_id)))
235 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid attribute ID")
236 if(NULL == (loc->oloc = H5A_oloc(attr)))
237 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location of attribute")
238 if(NULL == (loc->path = H5A_nameof(attr)))
239 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of attribute")
240 } /* end case */
241 break;
242
243 case H5I_REFERENCE:
244 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get group location of reference")
245
246 case H5I_UNINIT:
247 case H5I_BADID:
248 case H5I_VFL:
249 case H5I_NTYPES:
250 default:
251 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object ID")
252 } /* end switch */
253
254 done:
255 FUNC_LEAVE_NOAPI(ret_value)
256 } /* end H5G_loc() */
257
258
259 /*-------------------------------------------------------------------------
260 * Function: H5G_loc_copy
261 *
262 * Purpose: Copy over information for a location
263 *
264 * Return: Non-negative on success/Negative on failure
265 *
266 * Programmer: Quincey Koziol
267 * Tuesday, September 13, 2005
268 *
269 *-------------------------------------------------------------------------
270 */
271 herr_t
H5G_loc_copy(H5G_loc_t * dst,const H5G_loc_t * src,H5_copy_depth_t depth)272 H5G_loc_copy(H5G_loc_t *dst, const H5G_loc_t *src, H5_copy_depth_t depth)
273 {
274 herr_t ret_value = SUCCEED; /* Return value */
275
276 FUNC_ENTER_NOAPI(FAIL)
277
278 /* Check args. */
279 HDassert(dst);
280 HDassert(src);
281
282 /* Copy components of the location */
283 if(H5O_loc_copy(dst->oloc, src->oloc, depth) < 0)
284 HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
285 if(H5G_name_copy(dst->path, src->path, depth) < 0)
286 HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to copy path")
287
288 done:
289 FUNC_LEAVE_NOAPI(ret_value)
290 } /* end H5G_loc_copy() */
291
292
293 /*-------------------------------------------------------------------------
294 * Function: H5G_loc_reset
295 *
296 * Purpose: Reset information for a location
297 *
298 * Return: Non-negative on success/Negative on failure
299 *
300 * Programmer: Quincey Koziol
301 * Tuesday, September 13, 2005
302 *
303 *-------------------------------------------------------------------------
304 */
305 herr_t
H5G_loc_reset(H5G_loc_t * loc)306 H5G_loc_reset(H5G_loc_t *loc)
307 {
308 herr_t ret_value = SUCCEED; /* Return value */
309
310 FUNC_ENTER_NOAPI(FAIL)
311
312 /* Check args. */
313 HDassert(loc);
314
315 /* Reset components of the location */
316 if(H5O_loc_reset(loc->oloc) < 0)
317 HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to reset entry")
318 if(H5G_name_reset(loc->path) < 0)
319 HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to reset path")
320
321 done:
322 FUNC_LEAVE_NOAPI(ret_value)
323 } /* end H5G_loc_reset() */
324
325
326 /*-------------------------------------------------------------------------
327 * Function: H5G_loc_free
328 *
329 * Purpose: Free information for a location
330 *
331 * Return: Non-negative on success/Negative on failure
332 *
333 * Programmer: Quincey Koziol
334 * Tuesday, September 13, 2005
335 *
336 *-------------------------------------------------------------------------
337 */
338 herr_t
H5G_loc_free(H5G_loc_t * loc)339 H5G_loc_free(H5G_loc_t *loc)
340 {
341 herr_t ret_value = SUCCEED; /* Return value */
342
343 FUNC_ENTER_NOAPI(FAIL)
344
345 /* Check args. */
346 HDassert(loc);
347
348 /* Reset components of the location */
349 if(H5G_name_free(loc->path) < 0)
350 HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to free path")
351 if(H5O_loc_free(loc->oloc) < 0)
352 HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to free object header location")
353
354 done:
355 FUNC_LEAVE_NOAPI(ret_value)
356 } /* end H5G_loc_free() */
357
358
359 /*-------------------------------------------------------------------------
360 * Function: H5G_loc_find_cb
361 *
362 * Purpose: Callback for retrieving object location for an object in a group
363 *
364 * Return: Non-negative on success/Negative on failure
365 *
366 * Programmer: Quincey Koziol
367 * Monday, October 17, 2005
368 *
369 *-------------------------------------------------------------------------
370 */
371 static herr_t
H5G_loc_find_cb(H5G_loc_t H5_ATTR_UNUSED * grp_loc,const char * name,const H5O_link_t H5_ATTR_UNUSED * lnk,H5G_loc_t * obj_loc,void * _udata,H5G_own_loc_t * own_loc)372 H5G_loc_find_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char *name,
373 const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
374 H5G_own_loc_t *own_loc/*out*/)
375 {
376 H5G_loc_fnd_t *udata = (H5G_loc_fnd_t *)_udata; /* User data passed in */
377 herr_t ret_value = SUCCEED; /* Return value */
378
379 FUNC_ENTER_NOAPI_NOINIT
380
381 /* Check if the name in this group resolved to a valid object */
382 if(obj_loc == NULL)
383 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object '%s' doesn't exist", name)
384
385 /* Take ownership of the object's group location */
386 /* (Group traversal callbacks are responsible for either taking ownership
387 * of the group location for the object, or freeing it. - QAK)
388 */
389 H5G_loc_copy(udata->loc, obj_loc, H5_COPY_SHALLOW);
390 *own_loc = H5G_OWN_OBJ_LOC;
391
392 done:
393 FUNC_LEAVE_NOAPI(ret_value)
394 } /* end H5G_loc_find_cb() */
395
396
397 /*-------------------------------------------------------------------------
398 * Function: H5G_loc_find
399 *
400 * Purpose: Find a symbol from a location
401 *
402 * Return: Non-negative on success/Negative on failure
403 *
404 * Programmer: Quincey Koziol
405 * Tuesday, September 13, 2005
406 *
407 *-------------------------------------------------------------------------
408 */
409 herr_t
H5G_loc_find(const H5G_loc_t * loc,const char * name,H5G_loc_t * obj_loc,hid_t lapl_id,hid_t dxpl_id)410 H5G_loc_find(const H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc/*out*/,
411 hid_t lapl_id, hid_t dxpl_id)
412 {
413 H5G_loc_fnd_t udata; /* User data for traversal callback */
414 herr_t ret_value = SUCCEED; /* Return value */
415
416 FUNC_ENTER_NOAPI(FAIL)
417
418 /* Check args. */
419 HDassert(loc);
420 HDassert(name && *name);
421 HDassert(obj_loc);
422
423 /* Set up user data for locating object */
424 udata.loc = obj_loc;
425
426 /* Traverse group hierarchy to locate object */
427 if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_find_cb, &udata, lapl_id, dxpl_id) < 0)
428 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object")
429
430 done:
431 FUNC_LEAVE_NOAPI(ret_value)
432 } /* end H5G_loc_find() */
433
434
435 /*-------------------------------------------------------------------------
436 * Function: H5G_loc_find_by_idx_cb
437 *
438 * Purpose: Callback for retrieving object location for an object in a group
439 * according to the order within an index
440 *
441 * Return: Non-negative on success/Negative on failure
442 *
443 * Programmer: Quincey Koziol
444 * Monday, November 20, 2006
445 *
446 *-------------------------------------------------------------------------
447 */
448 static herr_t
H5G_loc_find_by_idx_cb(H5G_loc_t H5_ATTR_UNUSED * grp_loc,const char H5_ATTR_UNUSED * name,const H5O_link_t H5_ATTR_UNUSED * lnk,H5G_loc_t * obj_loc,void * _udata,H5G_own_loc_t * own_loc)449 H5G_loc_find_by_idx_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name,
450 const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
451 H5G_own_loc_t *own_loc/*out*/)
452 {
453 H5G_loc_fbi_t *udata = (H5G_loc_fbi_t *)_udata; /* User data passed in */
454 H5O_link_t fnd_lnk; /* Link within group */
455 hbool_t lnk_copied = FALSE; /* Whether the link was copied */
456 size_t links_left = H5L_NUM_LINKS; /* # of links left to traverse */
457 hbool_t obj_loc_valid = FALSE; /* Flag to indicate that the object location is valid */
458 hbool_t obj_exists = FALSE; /* Whether the object exists (unused) */
459 herr_t ret_value = SUCCEED; /* Return value */
460
461 FUNC_ENTER_NOAPI_NOINIT
462
463 /* Check if the name in this group resolved to a valid link */
464 if(obj_loc == NULL)
465 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group doesn't exist")
466
467 /* Query link */
468 if(H5G_obj_lookup_by_idx(obj_loc->oloc, udata->idx_type, udata->order,
469 udata->n, &fnd_lnk, udata->dxpl_id) < 0)
470 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "link not found")
471 lnk_copied = TRUE;
472
473 /* Build the initial object location for the link */
474 if(H5G__link_to_loc(obj_loc, &fnd_lnk, udata->loc) < 0)
475 HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot initialize object location")
476 obj_loc_valid = TRUE;
477
478 /* Perform any special traversals that the link needs */
479 /* (soft links, user-defined links, file mounting, etc.) */
480 /* (may modify the object location) */
481 if(H5G__traverse_special(obj_loc, &fnd_lnk, H5G_TARGET_NORMAL, &links_left, TRUE, udata->loc, &obj_exists, udata->lapl_id, udata->dxpl_id) < 0)
482 HGOTO_ERROR(H5E_LINK, H5E_TRAVERSE, FAIL, "special link traversal failed")
483
484 done:
485 /* Reset the link information, if we have a copy */
486 if(lnk_copied)
487 H5O_msg_reset(H5O_LINK_ID, &fnd_lnk);
488
489 /* Release the object location if we failed after copying it */
490 if(ret_value < 0 && obj_loc_valid)
491 if(H5G_loc_free(udata->loc) < 0)
492 HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location")
493
494 /* Indicate that this callback didn't take ownership of the group *
495 * location for the object */
496 *own_loc = H5G_OWN_NONE;
497
498 FUNC_LEAVE_NOAPI(ret_value)
499 } /* end H5G_loc_find_by_idx_cb() */
500
501
502 /*-------------------------------------------------------------------------
503 * Function: H5G_loc_find_by_idx
504 *
505 * Purpose: Find a symbol from a location, according to the order in an index
506 *
507 * Return: Non-negative on success/Negative on failure
508 *
509 * Programmer: Quincey Koziol
510 * Monday, November 20, 2006
511 *
512 *-------------------------------------------------------------------------
513 */
514 herr_t
H5G_loc_find_by_idx(H5G_loc_t * loc,const char * group_name,H5_index_t idx_type,H5_iter_order_t order,hsize_t n,H5G_loc_t * obj_loc,hid_t lapl_id,hid_t dxpl_id)515 H5G_loc_find_by_idx(H5G_loc_t *loc, const char *group_name, H5_index_t idx_type,
516 H5_iter_order_t order, hsize_t n, H5G_loc_t *obj_loc/*out*/, hid_t lapl_id,
517 hid_t dxpl_id)
518 {
519 H5G_loc_fbi_t udata; /* User data for traversal callback */
520 herr_t ret_value = SUCCEED; /* Return value */
521
522 FUNC_ENTER_NOAPI(FAIL)
523
524 /* Check args. */
525 HDassert(loc);
526 HDassert(group_name && *group_name);
527 HDassert(obj_loc);
528
529 /* Set up user data for locating object */
530 udata.dxpl_id = dxpl_id;
531 udata.lapl_id = lapl_id;
532 udata.idx_type = idx_type;
533 udata.order = order;
534 udata.n = n;
535 udata.loc = obj_loc;
536
537 /* Traverse group hierarchy to locate object */
538 if(H5G_traverse(loc, group_name, H5G_TARGET_NORMAL, H5G_loc_find_by_idx_cb, &udata, lapl_id, dxpl_id) < 0)
539 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object")
540
541 done:
542 FUNC_LEAVE_NOAPI(ret_value)
543 } /* end H5G_loc_find_by_idx() */
544
545
546 /*-------------------------------------------------------------------------
547 * Function: H5G__loc_insert
548 *
549 * Purpose: Insert an object at a location
550 *
551 * Return: Non-negative on success/Negative on failure
552 *
553 * Programmer: Quincey Koziol
554 * Tuesday, September 13, 2005
555 *
556 *-------------------------------------------------------------------------
557 */
558 herr_t
H5G__loc_insert(H5G_loc_t * grp_loc,const char * name,H5G_loc_t * obj_loc,H5O_type_t obj_type,const void * crt_info,hid_t dxpl_id)559 H5G__loc_insert(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc,
560 H5O_type_t obj_type, const void *crt_info, hid_t dxpl_id)
561 {
562 H5O_link_t lnk; /* Link for object to insert */
563 herr_t ret_value = SUCCEED; /* Return value */
564
565 FUNC_ENTER_PACKAGE
566
567 /* Check args. */
568 HDassert(grp_loc);
569 HDassert(name && *name);
570 HDassert(obj_loc);
571
572 /* Create link object for the object location */
573 lnk.type = H5L_TYPE_HARD;
574 lnk.cset = H5F_DEFAULT_CSET;
575 lnk.corder = 0; /* Will be reset if the group is tracking creation order */
576 lnk.corder_valid = FALSE; /* Indicate that the creation order isn't valid (yet) */
577 /* Casting away const OK -QAK */
578 lnk.name = (char *)name;
579 lnk.u.hard.addr = obj_loc->oloc->addr;
580
581 /* Insert new group into current group's symbol table */
582 if(H5G_obj_insert(grp_loc->oloc, name, &lnk, TRUE, obj_type, crt_info,
583 dxpl_id) < 0)
584 HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert object")
585
586 /* Set the name of the object location */
587 if(H5G_name_set(grp_loc->path, obj_loc->path, name) < 0)
588 HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot set name")
589
590 done:
591 FUNC_LEAVE_NOAPI(ret_value)
592 } /* end H5G__loc_insert() */
593
594
595 /*-------------------------------------------------------------------------
596 * Function: H5G_loc_exists_cb
597 *
598 * Purpose: Callback for checking if an object exists
599 *
600 * Return: Non-negative on success/Negative on failure
601 *
602 * Programmer: Quincey Koziol
603 * Tuesday, February 2, 2010
604 *
605 *-------------------------------------------------------------------------
606 */
607 static herr_t
H5G_loc_exists_cb(H5G_loc_t H5_ATTR_UNUSED * grp_loc,const char H5_ATTR_UNUSED * name,const H5O_link_t H5_ATTR_UNUSED * lnk,H5G_loc_t * obj_loc,void * _udata,H5G_own_loc_t * own_loc)608 H5G_loc_exists_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name,
609 const H5O_link_t H5_ATTR_UNUSED *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/,
610 H5G_own_loc_t *own_loc/*out*/)
611 {
612 H5G_loc_exists_t *udata = (H5G_loc_exists_t *)_udata; /* User data passed in */
613
614 FUNC_ENTER_NOAPI_NOINIT_NOERR
615
616 /* Check if the name in this group resolved to a valid object */
617 if(obj_loc == NULL)
618 if(lnk)
619 udata->exists = FALSE;
620 else
621 udata->exists = FAIL;
622 else
623 udata->exists = TRUE;
624
625 /* Indicate that this callback didn't take ownership of the group *
626 * location for the object */
627 *own_loc = H5G_OWN_NONE;
628
629 FUNC_LEAVE_NOAPI(SUCCEED)
630 } /* end H5G_loc_exists_cb() */
631
632
633 /*-------------------------------------------------------------------------
634 * Function: H5G_loc_exists
635 *
636 * Purpose: Check if an object actually exists at a location
637 *
638 * Return: Success: TRUE/FALSE
639 * Failure: Negative
640 *
641 * Programmer: Quincey Koziol
642 * Tuesday, February 2, 2010
643 *
644 *-------------------------------------------------------------------------
645 */
646 htri_t
H5G_loc_exists(const H5G_loc_t * loc,const char * name,hid_t lapl_id,hid_t dxpl_id)647 H5G_loc_exists(const H5G_loc_t *loc, const char *name, hid_t lapl_id, hid_t dxpl_id)
648 {
649 H5G_loc_exists_t udata; /* User data for traversal callback */
650 htri_t ret_value = FAIL; /* Return value */
651
652 FUNC_ENTER_NOAPI(FAIL)
653
654 /* Check args. */
655 HDassert(loc);
656 HDassert(name && *name);
657
658 /* Set up user data for locating object */
659 udata.exists = FALSE;
660
661 /* Traverse group hierarchy to locate object */
662 if(H5G_traverse(loc, name, H5G_TARGET_EXISTS, H5G_loc_exists_cb, &udata, lapl_id, dxpl_id) < 0)
663 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't check if object exists")
664
665 /* Set return value */
666 ret_value = udata.exists;
667
668 done:
669 FUNC_LEAVE_NOAPI(ret_value)
670 } /* end H5G_loc_exists() */
671
672
673 /*-------------------------------------------------------------------------
674 * Function: H5G_loc_info_cb
675 *
676 * Purpose: Callback for retrieving object info for an object in a group
677 *
678 * Return: Non-negative on success/Negative on failure
679 *
680 * Programmer: Quincey Koziol
681 * Thursday, November 23, 2006
682 *
683 *-------------------------------------------------------------------------
684 */
685 static herr_t
H5G_loc_info_cb(H5G_loc_t H5_ATTR_UNUSED * grp_loc,const char H5_ATTR_UNUSED * name,const H5O_link_t H5_ATTR_UNUSED * lnk,H5G_loc_t * obj_loc,void * _udata,H5G_own_loc_t * own_loc)686 H5G_loc_info_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t H5_ATTR_UNUSED *lnk,
687 H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/)
688 {
689 H5G_loc_info_t *udata = (H5G_loc_info_t *)_udata; /* User data passed in */
690 herr_t ret_value = SUCCEED; /* Return value */
691
692 FUNC_ENTER_NOAPI_NOINIT
693
694 /* Check if the name in this group resolved to a valid link */
695 if(obj_loc == NULL)
696 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
697
698 /* Query object information */
699 if(H5O_get_info(obj_loc->oloc, udata->dxpl_id, udata->want_ih_info, udata->oinfo) < 0)
700 HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object info")
701
702 done:
703 /* Indicate that this callback didn't take ownership of the group *
704 * location for the object */
705 *own_loc = H5G_OWN_NONE;
706
707 FUNC_LEAVE_NOAPI(ret_value)
708 } /* end H5G_loc_info_cb() */
709
710
711 /*-------------------------------------------------------------------------
712 * Function: H5G_loc_info
713 *
714 * Purpose: Retrieve the information for an object from a group location
715 * and path to that object
716 *
717 * Return: Non-negative on success/Negative on failure
718 *
719 * Programmer: Quincey Koziol
720 * Thursday, November 23, 2006
721 *
722 *-------------------------------------------------------------------------
723 */
724 herr_t
H5G_loc_info(H5G_loc_t * loc,const char * name,hbool_t want_ih_info,H5O_info_t * oinfo,hid_t lapl_id,hid_t dxpl_id)725 H5G_loc_info(H5G_loc_t *loc, const char *name, hbool_t want_ih_info, H5O_info_t *oinfo/*out*/,
726 hid_t lapl_id, hid_t dxpl_id)
727 {
728 H5G_loc_info_t udata; /* User data for traversal callback */
729 herr_t ret_value = SUCCEED; /* Return value */
730
731 FUNC_ENTER_NOAPI(FAIL)
732
733 /* Check args. */
734 HDassert(loc);
735 HDassert(name && *name);
736 HDassert(oinfo);
737
738 /* Set up user data for locating object */
739 udata.dxpl_id = dxpl_id;
740 udata.want_ih_info = want_ih_info;
741 udata.oinfo = oinfo;
742
743 /* Traverse group hierarchy to locate object */
744 if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_info_cb, &udata, lapl_id, dxpl_id) < 0)
745 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object")
746
747 done:
748 FUNC_LEAVE_NOAPI(ret_value)
749 } /* end H5G_loc_info() */
750
751
752 /*-------------------------------------------------------------------------
753 * Function: H5G_loc_set_comment_cb
754 *
755 * Purpose: Callback for (re)setting object comment for an object in a group
756 *
757 * Return: Non-negative on success/Negative on failure
758 *
759 * Programmer: Quincey Koziol
760 * Thursday, August 30, 2007
761 *
762 *-------------------------------------------------------------------------
763 */
764 static herr_t
H5G_loc_set_comment_cb(H5G_loc_t H5_ATTR_UNUSED * grp_loc,const char H5_ATTR_UNUSED * name,const H5O_link_t H5_ATTR_UNUSED * lnk,H5G_loc_t * obj_loc,void * _udata,H5G_own_loc_t * own_loc)765 H5G_loc_set_comment_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t H5_ATTR_UNUSED *lnk,
766 H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/)
767 {
768 H5G_loc_sc_t *udata = (H5G_loc_sc_t *)_udata; /* User data passed in */
769 H5O_name_t comment; /* Object header "comment" message */
770 htri_t exists; /* Whether a "comment" message already exists */
771 herr_t ret_value = SUCCEED; /* Return value */
772
773 FUNC_ENTER_NOAPI_NOINIT
774
775 /* Check if the name in this group resolved to a valid link */
776 if(obj_loc == NULL)
777 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
778
779 /* Check for existing comment message */
780 if((exists = H5O_msg_exists(obj_loc->oloc, H5O_NAME_ID, udata->dxpl_id)) < 0)
781 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read object header")
782
783 /* Remove the previous comment message if any */
784 if(exists)
785 if(H5O_msg_remove(obj_loc->oloc, H5O_NAME_ID, 0, TRUE, udata->dxpl_id) < 0)
786 HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete existing comment object header message")
787
788 /* Add the new message */
789 if(udata->comment && *udata->comment) {
790 /* Casting away const OK -QAK */
791 comment.s = (char *)udata->comment;
792 if(H5O_msg_create(obj_loc->oloc, H5O_NAME_ID, 0, H5O_UPDATE_TIME, &comment, udata->dxpl_id) < 0)
793 HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to set comment object header message")
794 } /* end if */
795
796 done:
797 /* Indicate that this callback didn't take ownership of the group *
798 * location for the object */
799 *own_loc = H5G_OWN_NONE;
800
801 FUNC_LEAVE_NOAPI(ret_value)
802 } /* end H5G_loc_set_comment_cb() */
803
804
805 /*-------------------------------------------------------------------------
806 * Function: H5G_loc_set_comment
807 *
808 * Purpose: (Re)set the information for an object from a group location
809 * and path to that object
810 *
811 * Return: Non-negative on success/Negative on failure
812 *
813 * Programmer: Quincey Koziol
814 * Thursday, August 30, 2007
815 *
816 *-------------------------------------------------------------------------
817 */
818 herr_t
H5G_loc_set_comment(H5G_loc_t * loc,const char * name,const char * comment,hid_t lapl_id,hid_t dxpl_id)819 H5G_loc_set_comment(H5G_loc_t *loc, const char *name, const char *comment,
820 hid_t lapl_id, hid_t dxpl_id)
821 {
822 H5G_loc_sc_t udata; /* User data for traversal callback */
823 herr_t ret_value = SUCCEED; /* Return value */
824
825 FUNC_ENTER_NOAPI(FAIL)
826
827 /* Check args. */
828 HDassert(loc);
829 HDassert(name && *name);
830
831 /* Set up user data for locating object */
832 udata.dxpl_id = dxpl_id;
833 udata.comment = comment;
834
835 /* Traverse group hierarchy to locate object */
836 if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_set_comment_cb, &udata, lapl_id, dxpl_id) < 0)
837 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object")
838
839 done:
840 FUNC_LEAVE_NOAPI(ret_value)
841 } /* end H5G_loc_set_comment() */
842
843
844 /*-------------------------------------------------------------------------
845 * Function: H5G_loc_get_comment_cb
846 *
847 * Purpose: Callback for retrieving object comment for an object in a group
848 *
849 * Return: Non-negative on success/Negative on failure
850 *
851 * Programmer: Quincey Koziol
852 * Thursday, August 30, 2007
853 *
854 *-------------------------------------------------------------------------
855 */
856 static herr_t
H5G_loc_get_comment_cb(H5G_loc_t H5_ATTR_UNUSED * grp_loc,const char H5_ATTR_UNUSED * name,const H5O_link_t H5_ATTR_UNUSED * lnk,H5G_loc_t * obj_loc,void * _udata,H5G_own_loc_t * own_loc)857 H5G_loc_get_comment_cb(H5G_loc_t H5_ATTR_UNUSED *grp_loc/*in*/, const char H5_ATTR_UNUSED *name, const H5O_link_t H5_ATTR_UNUSED *lnk,
858 H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/)
859 {
860 H5G_loc_gc_t *udata = (H5G_loc_gc_t *)_udata; /* User data passed in */
861 H5O_name_t comment; /* Object header "comment" message */
862 herr_t ret_value = SUCCEED; /* Return value */
863
864 FUNC_ENTER_NOAPI_NOINIT
865
866 /* Check if the name in this group resolved to a valid link */
867 if(obj_loc == NULL)
868 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
869
870 /* Query object comment */
871 comment.s = NULL;
872 if(NULL == H5O_msg_read(obj_loc->oloc, H5O_NAME_ID, &comment, udata->dxpl_id)) {
873 if(udata->comment && udata->bufsize > 0)
874 udata->comment[0] = '\0';
875 udata->comment_size = 0;
876 } else {
877 if(udata->comment && udata->bufsize)
878 HDstrncpy(udata->comment, comment.s, udata->bufsize);
879 udata->comment_size = (ssize_t)HDstrlen(comment.s);
880 H5O_msg_reset(H5O_NAME_ID, &comment);
881 } /* end else */
882
883 done:
884 /* Indicate that this callback didn't take ownership of the group *
885 * location for the object */
886 *own_loc = H5G_OWN_NONE;
887
888 FUNC_LEAVE_NOAPI(ret_value)
889 } /* end H5G_loc_get_comment_cb() */
890
891
892 /*-------------------------------------------------------------------------
893 * Function: H5G_loc_get_comment
894 *
895 * Purpose: Retrieve the information for an object from a group location
896 * and path to that object
897 *
898 * Return: Success: Number of bytes in the comment excluding the
899 * null terminator. Zero if the object has no
900 * comment.
901 *
902 * Failure: Negative
903 *
904 * Programmer: Quincey Koziol
905 * Thursday, August 30, 2007
906 *
907 *-------------------------------------------------------------------------
908 */
909 ssize_t
H5G_loc_get_comment(H5G_loc_t * loc,const char * name,char * comment,size_t bufsize,hid_t lapl_id,hid_t dxpl_id)910 H5G_loc_get_comment(H5G_loc_t *loc, const char *name, char *comment/*out*/,
911 size_t bufsize, hid_t lapl_id, hid_t dxpl_id)
912 {
913 H5G_loc_gc_t udata; /* User data for traversal callback */
914 ssize_t ret_value = -1; /* Return value */
915
916 FUNC_ENTER_NOAPI(FAIL)
917
918 /* Check args. */
919 HDassert(loc);
920 HDassert(name && *name);
921
922 /* Set up user data for locating object */
923 udata.dxpl_id = dxpl_id;
924 udata.comment = comment;
925 udata.bufsize = bufsize;
926 udata.comment_size = (-1);
927
928 /* Traverse group hierarchy to locate object */
929 if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_get_comment_cb, &udata, lapl_id, dxpl_id) < 0)
930 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object")
931
932 /* Set the return value */
933 ret_value = udata.comment_size;
934
935 done:
936 FUNC_LEAVE_NOAPI(ret_value)
937 } /* end H5G_loc_get_comment() */
938
939