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