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