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