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 /* Programmer: Robb Matzke <matzke@llnl.gov>
15 * Friday, September 19, 1997
16 *
17 */
18
19 /****************/
20 /* Module Setup */
21 /****************/
22
23 #include "H5Gmodule.h" /* This source code file is part of the H5G module */
24
25
26 /***********/
27 /* Headers */
28 /***********/
29 #include "H5private.h" /* Generic Functions */
30 #include "H5Eprivate.h" /* Error handling */
31 #include "H5Fprivate.h" /* File access */
32 #include "H5Gpkg.h" /* Groups */
33 #include "H5HLprivate.h" /* Local Heaps */
34 #include "H5MMprivate.h" /* Memory management */
35
36
37 /****************/
38 /* Local Macros */
39 /****************/
40
41
42 /******************/
43 /* Local Typedefs */
44 /******************/
45
46 /* User data for finding link information from B-tree */
47 typedef struct {
48 /* downward */
49 const char *name; /* Name to search for */
50 H5HL_t *heap; /* Local heap for group */
51
52 /* upward */
53 H5O_link_t *lnk; /* Caller's link location */
54 } H5G_stab_fnd_ud_t;
55
56 /* Data passed through B-tree iteration for looking up a name by index */
57 typedef struct H5G_bt_it_gnbi_t {
58 /* downward */
59 H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */
60 H5HL_t *heap; /*symbol table heap */
61
62 /* upward */
63 char *name; /*member name to be returned */
64 } H5G_bt_it_gnbi_t;
65
66 #ifndef H5_NO_DEPRECATED_SYMBOLS
67 /* Data passed through B-tree iteration for looking up a type by index */
68 typedef struct H5G_bt_it_gtbi_t {
69 /* downward */
70 H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */
71 H5F_t *f; /* Pointer to file that symbol table is in */
72 hid_t dxpl_id; /* DXPL for operation */
73
74 /* upward */
75 H5G_obj_t type; /*member type to be returned */
76 } H5G_bt_it_gtbi_t;
77 #endif /* H5_NO_DEPRECATED_SYMBOLS */
78
79 /* Data passed through B-tree iteration for looking up a link by index */
80 typedef struct H5G_bt_it_lbi_t {
81 /* downward */
82 H5G_bt_it_idx_common_t common; /* Common information for "by index" lookup */
83 H5HL_t *heap; /*symbol table heap */
84
85 /* upward */
86 H5O_link_t *lnk; /*link to be returned */
87 hbool_t found; /*whether we found the link */
88 } H5G_bt_it_lbi_t;
89
90
91 /********************/
92 /* Package Typedefs */
93 /********************/
94
95
96 /********************/
97 /* Local Prototypes */
98 /********************/
99
100
101 /*********************/
102 /* Package Variables */
103 /*********************/
104
105
106 /*****************************/
107 /* Library Private Variables */
108 /*****************************/
109
110
111 /*******************/
112 /* Local Variables */
113 /*******************/
114
115
116
117 /*-------------------------------------------------------------------------
118 * Function: H5G__stab_create_components
119 *
120 * Purpose: Creates the components for a new, empty, symbol table (name heap
121 * and B-tree). The caller can specify an initial size for the
122 * name heap.
123 *
124 * In order for the B-tree to operate correctly, the first
125 * item in the heap is the empty string, and must appear at
126 * heap offset zero.
127 *
128 * Return: Non-negative on success/Negative on failure
129 *
130 * Programmer: Quincey Koziol
131 * koziol@ncsa.uiuc.edu
132 * Nov 7 2005
133 *
134 *-------------------------------------------------------------------------
135 */
136 herr_t
H5G__stab_create_components(H5F_t * f,H5O_stab_t * stab,size_t size_hint,hid_t dxpl_id)137 H5G__stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint, hid_t dxpl_id)
138 {
139 H5HL_t *heap = NULL; /* Pointer to local heap */
140 size_t name_offset; /* Offset of "" name */
141 herr_t ret_value = SUCCEED; /* Return value */
142
143 FUNC_ENTER_PACKAGE
144
145 /*
146 * Check arguments.
147 */
148 HDassert(f);
149 HDassert(stab);
150 HDassert(size_hint > 0);
151
152 /* Create the B-tree */
153 if(H5B_create(f, dxpl_id, H5B_SNODE, NULL, &(stab->btree_addr)/*out*/) < 0)
154 HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree")
155
156 /* Create symbol table private heap */
157 if(H5HL_create(f, dxpl_id, size_hint, &(stab->heap_addr)/*out*/) < 0)
158 HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap")
159
160 /* Pin the heap down in memory */
161 if(NULL == (heap = H5HL_protect(f, dxpl_id, stab->heap_addr, H5AC__NO_FLAGS_SET)))
162 HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap")
163
164 /* Insert name into the heap */
165 if(UFAIL == (name_offset = H5HL_insert(f, dxpl_id, heap, (size_t)1, "")))
166 HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert name into heap")
167
168 /*
169 * B-tree's won't work if the first name isn't at the beginning
170 * of the heap.
171 */
172 HDassert(0 == name_offset);
173
174 done:
175 /* Release resources */
176 if(heap && FAIL == H5HL_unprotect(heap))
177 HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
178
179 FUNC_LEAVE_NOAPI(ret_value)
180 } /* end H5G__stab_create_components() */
181
182
183 /*-------------------------------------------------------------------------
184 * Function: H5G__stab_create
185 *
186 * Purpose: Creates a new empty symbol table (object header, name heap,
187 * and B-tree). The caller can specify an initial size for the
188 * name heap. The object header of the group is opened for
189 * write access.
190 *
191 * In order for the B-tree to operate correctly, the first
192 * item in the heap is the empty string, and must appear at
193 * heap offset zero.
194 *
195 * Return: Non-negative on success/Negative on failure
196 *
197 * Programmer: Robb Matzke
198 * matzke@llnl.gov
199 * Aug 1 1997
200 *
201 *-------------------------------------------------------------------------
202 */
203 herr_t
H5G__stab_create(H5O_loc_t * grp_oloc,hid_t dxpl_id,const H5O_ginfo_t * ginfo,H5O_stab_t * stab)204 H5G__stab_create(H5O_loc_t *grp_oloc, hid_t dxpl_id, const H5O_ginfo_t *ginfo,
205 H5O_stab_t *stab)
206 {
207 size_t heap_hint; /* Local heap size hint */
208 size_t size_hint; /* Local heap size hint */
209 herr_t ret_value = SUCCEED; /* Return value */
210
211 FUNC_ENTER_PACKAGE_TAG(dxpl_id, grp_oloc->addr, FAIL)
212
213 /*
214 * Check arguments.
215 */
216 HDassert(grp_oloc);
217 HDassert(stab);
218
219 /* Adjust the size hint, if necessary */
220 if(ginfo->lheap_size_hint == 0)
221 heap_hint = 8 + /* "null" name inserted for B-tree */
222 (ginfo->est_num_entries * H5HL_ALIGN(ginfo->est_name_len + 1)) + /* estimated size of names for links, aligned for inserting into local heap */
223 H5HL_SIZEOF_FREE(grp_oloc->file); /* Free list entry in local heap */
224 else
225 heap_hint = ginfo->lheap_size_hint;
226 size_hint = MAX(heap_hint, H5HL_SIZEOF_FREE(grp_oloc->file) + 2);
227
228 /* Go create the B-tree & local heap */
229 if(H5G__stab_create_components(grp_oloc->file, stab, size_hint, dxpl_id) < 0)
230 HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create symbol table components")
231
232 /*
233 * Insert the symbol table message into the object header and the symbol
234 * table entry.
235 */
236 if(H5O_msg_create(grp_oloc, H5O_STAB_ID, 0, H5O_UPDATE_TIME, stab, dxpl_id) < 0)
237 HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
238
239 done:
240 FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
241 } /* end H5G__stab_create() */
242
243
244 /*-------------------------------------------------------------------------
245 * Function: H5G__stab_insert_real
246 *
247 * Purpose: Insert a new symbol into a table.
248 * The name of the new symbol is NAME and its symbol
249 * table entry is OBJ_LNK.
250 *
251 * Return: Non-negative on success/Negative on failure
252 *
253 * Programmer: Quincey Koziol
254 * koziol@uiuc.edu
255 * Nov 7 2005
256 *
257 *-------------------------------------------------------------------------
258 */
259 herr_t
H5G__stab_insert_real(H5F_t * f,const H5O_stab_t * stab,const char * name,H5O_link_t * obj_lnk,H5O_type_t obj_type,const void * crt_info,hid_t dxpl_id)260 H5G__stab_insert_real(H5F_t *f, const H5O_stab_t *stab, const char *name,
261 H5O_link_t *obj_lnk, H5O_type_t obj_type, const void *crt_info,
262 hid_t dxpl_id)
263 {
264 H5HL_t *heap = NULL; /* Pointer to local heap */
265 H5G_bt_ins_t udata; /* Data to pass through B-tree */
266 herr_t ret_value = SUCCEED; /* Return value */
267
268 FUNC_ENTER_PACKAGE
269
270 /* check arguments */
271 HDassert(f);
272 HDassert(stab);
273 HDassert(name && *name);
274 HDassert(obj_lnk);
275
276 /* Pin the heap down in memory */
277 if(NULL == (heap = H5HL_protect(f, dxpl_id, stab->heap_addr, H5AC__NO_FLAGS_SET)))
278 HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap")
279
280 /* Initialize data to pass through B-tree */
281 udata.common.name = name;
282 udata.common.heap = heap;
283 udata.lnk = obj_lnk;
284 udata.obj_type = obj_type;
285 udata.crt_info = crt_info;
286
287 /* Insert into symbol table */
288 if(H5B_insert(f, dxpl_id, H5B_SNODE, stab->btree_addr, &udata) < 0)
289 HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry")
290
291 done:
292 /* Release resources */
293 if(heap && H5HL_unprotect(heap) < 0)
294 HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
295
296 FUNC_LEAVE_NOAPI(ret_value)
297 } /* end H5G__stab_insert_real() */
298
299
300 /*-------------------------------------------------------------------------
301 * Function: H5G__stab_insert
302 *
303 * Purpose: Insert a new symbol into the table described by GRP_ENT in
304 * file F. The name of the new symbol is NAME and its symbol
305 * table entry is OBJ_ENT.
306 *
307 * Return: Non-negative on success/Negative on failure
308 *
309 * Programmer: Robb Matzke
310 * matzke@llnl.gov
311 * Aug 1 1997
312 *
313 *-------------------------------------------------------------------------
314 */
315 herr_t
H5G__stab_insert(const H5O_loc_t * grp_oloc,const char * name,H5O_link_t * obj_lnk,H5O_type_t obj_type,const void * crt_info,hid_t dxpl_id)316 H5G__stab_insert(const H5O_loc_t *grp_oloc, const char *name,
317 H5O_link_t *obj_lnk, H5O_type_t obj_type, const void *crt_info,
318 hid_t dxpl_id)
319 {
320 H5O_stab_t stab; /* Symbol table message */
321 herr_t ret_value = SUCCEED; /* Return value */
322
323 FUNC_ENTER_PACKAGE_TAG(dxpl_id, grp_oloc->addr, FAIL)
324
325 /* check arguments */
326 HDassert(grp_oloc && grp_oloc->file);
327 HDassert(name && *name);
328 HDassert(obj_lnk);
329
330 /* Retrieve symbol table message */
331 if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id))
332 HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
333
334 if(H5G__stab_insert_real(grp_oloc->file, &stab, name, obj_lnk, obj_type,
335 crt_info, dxpl_id) < 0)
336 HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5_ITER_ERROR, "unable to insert the name")
337
338 done:
339 FUNC_LEAVE_NOAPI_TAG(ret_value, H5_ITER_ERROR)
340 } /* end H5G__stab_insert() */
341
342
343 /*-------------------------------------------------------------------------
344 * Function: H5G__stab_remove
345 *
346 * Purpose: Remove NAME from a symbol table.
347 *
348 * Return: Non-negative on success/Negative on failure
349 *
350 * Programmer: Robb Matzke
351 * Thursday, September 17, 1998
352 *
353 *-------------------------------------------------------------------------
354 */
355 herr_t
H5G__stab_remove(const H5O_loc_t * loc,hid_t dxpl_id,H5RS_str_t * grp_full_path_r,const char * name)356 H5G__stab_remove(const H5O_loc_t *loc, hid_t dxpl_id, H5RS_str_t *grp_full_path_r,
357 const char *name)
358 {
359 H5HL_t *heap = NULL; /* Pointer to local heap */
360 H5O_stab_t stab; /*symbol table message */
361 H5G_bt_rm_t udata; /*data to pass through B-tree */
362 herr_t ret_value = SUCCEED; /* Return value */
363
364 FUNC_ENTER_PACKAGE
365
366 HDassert(loc && loc->file);
367 HDassert(name && *name);
368
369 /* Read in symbol table message */
370 if(NULL == H5O_msg_read(loc, H5O_STAB_ID, &stab, dxpl_id))
371 HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
372
373 /* Pin the heap down in memory */
374 if(NULL == (heap = H5HL_protect(loc->file, dxpl_id, stab.heap_addr, H5AC__NO_FLAGS_SET)))
375 HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap")
376
377 /* Initialize data to pass through B-tree */
378 udata.common.name = name;
379 udata.common.heap = heap;
380 udata.grp_full_path_r = grp_full_path_r;
381
382 /* Remove from symbol table */
383 if(H5B_remove(loc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0)
384 HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry")
385
386 done:
387 /* Release resources */
388 if(heap && H5HL_unprotect(heap) < 0)
389 HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
390
391 FUNC_LEAVE_NOAPI(ret_value)
392 } /* end H5G__stab_remove() */
393
394
395 /*-------------------------------------------------------------------------
396 * Function: H5G__stab_remove_by_idx
397 *
398 * Purpose: Remove NAME from a symbol table, according to the name index.
399 *
400 * Return: Non-negative on success/Negative on failure
401 *
402 * Programmer: Quincey Koziol
403 * Wednesday, November 15, 2006
404 *
405 *-------------------------------------------------------------------------
406 */
407 herr_t
H5G__stab_remove_by_idx(const H5O_loc_t * grp_oloc,hid_t dxpl_id,H5RS_str_t * grp_full_path_r,H5_iter_order_t order,hsize_t n)408 H5G__stab_remove_by_idx(const H5O_loc_t *grp_oloc, hid_t dxpl_id, H5RS_str_t *grp_full_path_r,
409 H5_iter_order_t order, hsize_t n)
410 {
411 H5HL_t *heap = NULL; /* Pointer to local heap */
412 H5O_stab_t stab; /* Symbol table message */
413 H5G_bt_rm_t udata; /* Data to pass through B-tree */
414 H5O_link_t obj_lnk; /* Object's link within group */
415 hbool_t lnk_copied = FALSE; /* Whether the link was copied */
416 herr_t ret_value = SUCCEED; /* Return value */
417
418 FUNC_ENTER_PACKAGE
419
420 HDassert(grp_oloc && grp_oloc->file);
421
422 /* Look up name of link to remove, by index */
423 if(H5G__stab_lookup_by_idx(grp_oloc, order, n, &obj_lnk, dxpl_id) < 0)
424 HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get link information")
425 lnk_copied = TRUE;
426
427 /* Read in symbol table message */
428 if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id))
429 HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
430
431 /* Pin the heap down in memory */
432 if(NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, stab.heap_addr, H5AC__NO_FLAGS_SET)))
433 HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap")
434
435 /* Initialize data to pass through B-tree */
436 udata.common.name = obj_lnk.name;
437 udata.common.heap = heap;
438 udata.grp_full_path_r = grp_full_path_r;
439
440 /* Remove link from symbol table */
441 if(H5B_remove(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0)
442 HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry")
443
444 done:
445 /* Release resources */
446 if(heap && H5HL_unprotect(heap) < 0)
447 HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
448
449 /* Reset the link information, if we have a copy */
450 if(lnk_copied)
451 H5O_msg_reset(H5O_LINK_ID, &obj_lnk);
452
453 FUNC_LEAVE_NOAPI(ret_value)
454 } /* end H5G__stab_remove_by_idx() */
455
456
457 /*-------------------------------------------------------------------------
458 * Function: H5G__stab_delete
459 *
460 * Purpose: Delete entire symbol table information from file
461 *
462 * Return: Non-negative on success/Negative on failure
463 *
464 * Programmer: Quincey Koziol
465 * Thursday, March 20, 2003
466 *
467 * Modifications:
468 *
469 *-------------------------------------------------------------------------
470 */
471 herr_t
H5G__stab_delete(H5F_t * f,hid_t dxpl_id,const H5O_stab_t * stab)472 H5G__stab_delete(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab)
473 {
474 H5HL_t *heap = NULL; /* Pointer to local heap */
475 H5G_bt_rm_t udata; /*data to pass through B-tree */
476 herr_t ret_value = SUCCEED; /* Return value */
477
478 FUNC_ENTER_PACKAGE
479
480 HDassert(f);
481 HDassert(stab);
482 HDassert(H5F_addr_defined(stab->btree_addr));
483 HDassert(H5F_addr_defined(stab->heap_addr));
484
485 /* Pin the heap down in memory */
486 if(NULL == (heap = H5HL_protect(f, dxpl_id, stab->heap_addr, H5AC__NO_FLAGS_SET)))
487 HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap")
488
489 /* Set up user data for B-tree deletion */
490 udata.common.name = NULL;
491 udata.common.heap = heap;
492
493 /* Delete entire B-tree */
494 if(H5B_delete(f, dxpl_id, H5B_SNODE, stab->btree_addr, &udata) < 0)
495 HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete symbol table B-tree")
496
497 /* Release resources */
498 if(H5HL_unprotect(heap) < 0)
499 HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
500 heap = NULL;
501
502 /* Delete local heap for names */
503 if(H5HL_delete(f, dxpl_id, stab->heap_addr) < 0)
504 HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete symbol table heap")
505
506 done:
507 /* Release resources */
508 if(heap && H5HL_unprotect(heap) < 0)
509 HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
510
511 FUNC_LEAVE_NOAPI(ret_value)
512 } /* end H5G__stab_delete() */
513
514
515 /*-------------------------------------------------------------------------
516 * Function: H5G__stab_iterate
517 *
518 * Purpose: Iterate over the objects in a group
519 *
520 * Return: Non-negative on success/Negative on failure
521 *
522 * Programmer: Quincey Koziol
523 * Monday, October 3, 2005
524 *
525 *-------------------------------------------------------------------------
526 */
527 herr_t
H5G__stab_iterate(const H5O_loc_t * oloc,hid_t dxpl_id,H5_iter_order_t order,hsize_t skip,hsize_t * last_lnk,H5G_lib_iterate_t op,void * op_data)528 H5G__stab_iterate(const H5O_loc_t *oloc, hid_t dxpl_id, H5_iter_order_t order,
529 hsize_t skip, hsize_t *last_lnk, H5G_lib_iterate_t op, void *op_data)
530 {
531 H5HL_t *heap = NULL; /* Local heap for group */
532 H5O_stab_t stab; /* Info about symbol table */
533 H5G_link_table_t ltable = {0, NULL}; /* Link table */
534 herr_t ret_value = FAIL; /* Return value */
535
536 FUNC_ENTER_PACKAGE_TAG(dxpl_id, oloc->addr, FAIL)
537
538 /* Sanity check */
539 HDassert(oloc);
540 HDassert(op);
541
542 /* Get the B-tree info */
543 if(NULL == H5O_msg_read(oloc, H5O_STAB_ID, &stab, dxpl_id))
544 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address")
545
546 /* Pin the heap down in memory */
547 if(NULL == (heap = H5HL_protect(oloc->file, dxpl_id, stab.heap_addr, H5AC__READ_ONLY_FLAG)))
548 HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap")
549
550 /* Check on iteration order */
551 /* ("native" iteration order is increasing for this link storage mechanism) */
552 if(order != H5_ITER_DEC) {
553 H5G_bt_it_it_t udata; /* User data to pass to B-tree callback */
554
555 /* Build udata to pass through H5B_iterate() to H5G__node_iterate() */
556 udata.heap = heap;
557 udata.skip = skip;
558 udata.final_ent = last_lnk;
559 udata.op = op;
560 udata.op_data = op_data;
561
562 /* Iterate over the group members */
563 if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G__node_iterate, &udata)) < 0)
564 HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed");
565
566 /* Check for too high of a starting index (ex post facto :-) */
567 /* (Skipping exactly as many entries as are in the group is currently an error) */
568 if(skip > 0 && skip >= *last_lnk)
569 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
570 } /* end if */
571 else {
572 H5G_bt_it_bt_t udata; /* User data to pass to B-tree callback */
573
574 /* Build udata to pass through H5B_iterate() to H5G__node_build_table() */
575 udata.alloc_nlinks = 0;
576 udata.heap = heap;
577 udata.ltable = <able;
578
579 /* Iterate over the group members */
580 if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G__node_build_table, &udata) < 0)
581 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to build link table")
582
583 /* Check for skipping out of bounds */
584 if(skip > 0 && (size_t)skip >= ltable.nlinks)
585 HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "index out of bound")
586
587 /* Sort link table in correct iteration order */
588 if(H5G__link_sort_table(<able, H5_INDEX_NAME, order) < 0)
589 HGOTO_ERROR(H5E_SYM, H5E_CANTSORT, FAIL, "error sorting link messages")
590
591 /* Iterate over links in table */
592 if((ret_value = H5G__link_iterate_table(<able, skip, last_lnk, op, op_data)) < 0)
593 HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed");
594 } /* end else */
595
596 done:
597 /* Release resources */
598 if(heap && H5HL_unprotect(heap) < 0)
599 HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
600 if(ltable.lnks && H5G__link_release_table(<able) < 0)
601 HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table")
602
603 FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
604 } /* end H5G__stab_iterate() */
605
606
607 /*-------------------------------------------------------------------------
608 * Function: H5G__stab_count
609 *
610 * Purpose: Count the # of links in a group
611 *
612 * Return: Non-negative on success/Negative on failure
613 *
614 * Programmer: Quincey Koziol
615 * Tuesday, September 6, 2005
616 *
617 *-------------------------------------------------------------------------
618 */
619 herr_t
H5G__stab_count(H5O_loc_t * oloc,hsize_t * num_objs,hid_t dxpl_id)620 H5G__stab_count(H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id)
621 {
622 H5O_stab_t stab; /* Info about symbol table */
623 herr_t ret_value = SUCCEED;
624
625 FUNC_ENTER_PACKAGE_TAG(dxpl_id, oloc->addr, FAIL)
626
627 /* Sanity check */
628 HDassert(oloc);
629 HDassert(num_objs);
630
631 /* Reset the number of objects in the group */
632 *num_objs = 0;
633
634 /* Get the B-tree info */
635 if(NULL == H5O_msg_read(oloc, H5O_STAB_ID, &stab, dxpl_id))
636 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address")
637
638 /* Iterate over the group members */
639 if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G__node_sumup, num_objs) < 0)
640 HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed")
641
642 done:
643 FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
644 } /* end H5G__stab_count() */
645
646
647 /*-------------------------------------------------------------------------
648 * Function: H5G__stab_bh_size
649 *
650 * Purpose: Retrieve storage for btree and heap (1.6)
651 *
652 * Return: Non-negative on success/Negative on failure
653 *
654 * Programmer: Vailin Choi
655 * June 25 2007
656 *
657 *-------------------------------------------------------------------------
658 */
659 herr_t
H5G__stab_bh_size(H5F_t * f,hid_t dxpl_id,const H5O_stab_t * stab,H5_ih_info_t * bh_info)660 H5G__stab_bh_size(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab,
661 H5_ih_info_t *bh_info)
662 {
663 hsize_t snode_size; /* Symbol table node size */
664 H5B_info_t bt_info; /* B-tree node info */
665 herr_t ret_value = SUCCEED;
666
667 FUNC_ENTER_PACKAGE
668
669 /* Sanity check */
670 HDassert(f);
671 HDassert(stab);
672 HDassert(bh_info);
673
674 /* Set up user data for B-tree iteration */
675 snode_size = 0;
676
677 /* Get the B-tree & symbol table node size info */
678 if(H5B_get_info(f, dxpl_id, H5B_SNODE, stab->btree_addr, &bt_info, H5G__node_iterate_size, &snode_size) < 0)
679 HGOTO_ERROR(H5E_BTREE, H5E_CANTINIT, FAIL, "iteration operator failed")
680
681 /* Add symbol table & B-tree node sizes to index info */
682 bh_info->index_size += snode_size + bt_info.size;
683
684 /* Get the size of the local heap for the group */
685 if(H5HL_heapsize(f, dxpl_id, stab->heap_addr, &(bh_info->heap_size)) < 0)
686 HGOTO_ERROR(H5E_HEAP, H5E_CANTINIT, FAIL, "iteration operator failed")
687
688 done:
689 FUNC_LEAVE_NOAPI(ret_value)
690 } /* end H5G__stab_bh_size() */
691
692
693 /*-------------------------------------------------------------------------
694 * Function: H5G_stab_get_name_by_idx_cb
695 *
696 * Purpose: Callback for B-tree iteration 'by index' info query to
697 * retrieve the name of a link
698 *
699 * Return: Success: Non-negative
700 * Failure: Negative
701 *
702 * Programmer: Quincey Koziol
703 * Nov 7, 2006
704 *
705 *-------------------------------------------------------------------------
706 */
707 static herr_t
H5G_stab_get_name_by_idx_cb(const H5G_entry_t * ent,void * _udata)708 H5G_stab_get_name_by_idx_cb(const H5G_entry_t *ent, void *_udata)
709 {
710 H5G_bt_it_gnbi_t *udata = (H5G_bt_it_gnbi_t *)_udata;
711 size_t name_off; /* Offset of name in heap */
712 const char *name; /* Pointer to name string in heap */
713
714 FUNC_ENTER_NOAPI_NOINIT_NOERR
715
716 /* Sanity check */
717 HDassert(ent);
718 HDassert(udata && udata->heap);
719
720 /* Get name offset in heap */
721 name_off = ent->name_off;
722 name = (const char *)H5HL_offset_into(udata->heap, name_off);
723 HDassert(name);
724 udata->name = H5MM_strdup(name);
725 HDassert(udata->name);
726
727 FUNC_LEAVE_NOAPI(SUCCEED)
728 } /* end H5G_stab_get_name_by_idx_cb */
729
730
731 /*-------------------------------------------------------------------------
732 * Function: H5G__stab_get_name_by_idx
733 *
734 * Purpose: Returns the name of objects in the group by giving index.
735 *
736 * Return: Success: Non-negative, length of name
737 * Failure: Negative
738 *
739 * Programmer: Raymond Lu
740 * Nov 20, 2002
741 *
742 *-------------------------------------------------------------------------
743 */
744 ssize_t
H5G__stab_get_name_by_idx(const H5O_loc_t * oloc,H5_iter_order_t order,hsize_t n,char * name,size_t size,hid_t dxpl_id)745 H5G__stab_get_name_by_idx(const H5O_loc_t *oloc, H5_iter_order_t order, hsize_t n,
746 char* name, size_t size, hid_t dxpl_id)
747 {
748 H5HL_t *heap = NULL; /* Pointer to local heap */
749 H5O_stab_t stab; /* Info about local heap & B-tree */
750 H5G_bt_it_gnbi_t udata; /* Iteration information */
751 hbool_t udata_valid = FALSE; /* Whether iteration information is valid */
752 ssize_t ret_value = -1; /* Return value */
753
754 /* Portably clear udata struct (before FUNC_ENTER) */
755 HDmemset(&udata, 0, sizeof(udata));
756
757 FUNC_ENTER_NOAPI(FAIL)
758
759 /* Sanity check */
760 HDassert(oloc);
761
762 /* Get the B-tree & local heap info */
763 if(NULL == H5O_msg_read(oloc, H5O_STAB_ID, &stab, dxpl_id))
764 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address")
765
766 /* Pin the heap down in memory */
767 if(NULL == (heap = H5HL_protect(oloc->file, dxpl_id, stab.heap_addr, H5AC__READ_ONLY_FLAG)))
768 HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap")
769
770 /* Remap index for decreasing iteration order */
771 if(order == H5_ITER_DEC) {
772 hsize_t nlinks = 0; /* Number of links in group */
773
774 /* Iterate over the symbol table nodes, to count the links */
775 if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G__node_sumup, &nlinks) < 0)
776 HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed")
777
778 /* Map decreasing iteration order index to increasing iteration order index */
779 n = nlinks - (n + 1);
780 } /* end if */
781
782 /* Set iteration information */
783 udata.common.idx = n;
784 udata.common.num_objs = 0;
785 udata.common.op = H5G_stab_get_name_by_idx_cb;
786 udata.heap = heap;
787 udata.name = NULL;
788 udata_valid = TRUE;
789
790 /* Iterate over the group members */
791 if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G__node_by_idx, &udata) < 0)
792 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed")
793
794 /* If we don't know the name now, we almost certainly went out of bounds */
795 if(udata.name == NULL)
796 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound")
797
798 /* Get the length of the name */
799 ret_value = (ssize_t)HDstrlen(udata.name);
800
801 /* Copy the name into the user's buffer, if given */
802 if(name) {
803 HDstrncpy(name, udata.name, MIN((size_t)(ret_value + 1), size));
804 if((size_t)ret_value >= size)
805 name[size - 1]='\0';
806 } /* end if */
807
808 done:
809 /* Release resources */
810 if(heap && H5HL_unprotect(heap) < 0)
811 HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
812
813 /* Free the duplicated name */
814 if(udata_valid && udata.name != NULL)
815 H5MM_xfree(udata.name);
816
817 FUNC_LEAVE_NOAPI(ret_value)
818 } /* end H5G__stab_get_name_by_idx() */
819
820
821 /*-------------------------------------------------------------------------
822 * Function: H5G_stab_lookup_cb
823 *
824 * Purpose: B-tree 'find' callback to retrieve location for an object
825 *
826 * Return: Success: Non-negative
827 *
828 * Failure: Negative
829 *
830 * Programmer: Quincey Koziol
831 * Sep 20, 2005
832 *
833 *-------------------------------------------------------------------------
834 */
835 static herr_t
H5G_stab_lookup_cb(const H5G_entry_t * ent,void * _udata)836 H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata)
837 {
838 H5G_stab_fnd_ud_t *udata = (H5G_stab_fnd_ud_t *)_udata; /* 'User data' passed in */
839 herr_t ret_value = SUCCEED; /* Return value */
840
841 FUNC_ENTER_NOAPI_NOINIT
842
843 /* Check for setting link info */
844 if(udata->lnk)
845 /* Convert the entry to a link */
846 if(H5G__ent_to_link(udata->lnk, udata->heap, ent, udata->name) < 0)
847 HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, FAIL, "unable to convert symbol table entry to link")
848
849 done:
850 FUNC_LEAVE_NOAPI(ret_value)
851 } /* end H5G_stab_lookup_cb() */
852
853
854 /*-------------------------------------------------------------------------
855 * Function: H5G__stab_lookup
856 *
857 * Purpose: Look up an object relative to a group, using symbol table
858 *
859 * Return: Non-negative (TRUE/FALSE) on success/Negative on failure
860 *
861 * Programmer: Quincey Koziol
862 * koziol@ncsa.uiuc.edu
863 * Sep 20 2005
864 *
865 *-------------------------------------------------------------------------
866 */
867 htri_t
H5G__stab_lookup(const H5O_loc_t * grp_oloc,const char * name,H5O_link_t * lnk,hid_t dxpl_id)868 H5G__stab_lookup(const H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk,
869 hid_t dxpl_id)
870 {
871 H5HL_t *heap = NULL; /* Pointer to local heap */
872 H5G_bt_lkp_t bt_udata; /* Data to pass through B-tree */
873 H5G_stab_fnd_ud_t udata; /* 'User data' to give to callback */
874 H5O_stab_t stab; /* Symbol table message */
875 htri_t ret_value = FAIL; /* Return value */
876
877 FUNC_ENTER_PACKAGE
878
879 /* check arguments */
880 HDassert(grp_oloc && grp_oloc->file);
881 HDassert(name && *name);
882 HDassert(lnk);
883
884 /* Retrieve the symbol table message for the group */
885 if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id))
886 HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message")
887
888 /* Pin the heap down in memory */
889 if(NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, stab.heap_addr, H5AC__READ_ONLY_FLAG)))
890 HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap")
891
892 /* Set up user data to pass to 'find' operation callback */
893 udata.name = name;
894 udata.lnk = lnk;
895 udata.heap = heap;
896
897 /* Set up the user data for actual B-tree find operation */
898 bt_udata.common.name = name;
899 bt_udata.common.heap = heap;
900 bt_udata.op = H5G_stab_lookup_cb;
901 bt_udata.op_data = &udata;
902
903 /* Search the B-tree */
904 if((ret_value = H5B_find(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &bt_udata)) < 0)
905 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
906
907 done:
908 /* Release resources */
909 if(heap && H5HL_unprotect(heap) < 0)
910 HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
911
912 FUNC_LEAVE_NOAPI(ret_value)
913 } /* end H5G__stab_lookup() */
914
915
916 /*-------------------------------------------------------------------------
917 * Function: H5G_stab_lookup_by_idx_cb
918 *
919 * Purpose: Callback for B-tree iteration 'by index' info query to
920 * retrieve the link
921 *
922 * Return: Success: Non-negative
923 * Failure: Negative
924 *
925 * Programmer: Quincey Koziol
926 * Nov 9, 2006
927 *
928 *-------------------------------------------------------------------------
929 */
930 static herr_t
H5G_stab_lookup_by_idx_cb(const H5G_entry_t * ent,void * _udata)931 H5G_stab_lookup_by_idx_cb(const H5G_entry_t *ent, void *_udata)
932 {
933 H5G_bt_it_lbi_t *udata = (H5G_bt_it_lbi_t *)_udata;
934 const char *name; /* Pointer to name string in heap */
935 herr_t ret_value = SUCCEED; /* Return value */
936
937 FUNC_ENTER_NOAPI_NOINIT
938
939 /* Sanity check */
940 HDassert(ent);
941 HDassert(udata && udata->heap);
942
943 /* Get a pointer to the link name */
944 name = (const char *)H5HL_offset_into(udata->heap, ent->name_off);
945 HDassert(name);
946
947 /* Convert the entry to a link */
948 if(H5G__ent_to_link(udata->lnk, udata->heap, ent, name) < 0)
949 HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, FAIL, "unable to convert symbol table entry to link")
950 udata->found = TRUE;
951
952 done:
953 FUNC_LEAVE_NOAPI(ret_value)
954 } /* end H5G_stab_lookup_by_idx_cb */
955
956
957 /*-------------------------------------------------------------------------
958 * Function: H5G__stab_lookup_by_idx
959 *
960 * Purpose: Look up an object in a group, according to the name index
961 *
962 * Return: Non-negative on success/Negative on failure
963 *
964 * Programmer: Quincey Koziol
965 * koziol@hdfgroup.org
966 * Nov 7 2006
967 *
968 *-------------------------------------------------------------------------
969 */
970 herr_t
H5G__stab_lookup_by_idx(const H5O_loc_t * grp_oloc,H5_iter_order_t order,hsize_t n,H5O_link_t * lnk,hid_t dxpl_id)971 H5G__stab_lookup_by_idx(const H5O_loc_t *grp_oloc, H5_iter_order_t order, hsize_t n,
972 H5O_link_t *lnk, hid_t dxpl_id)
973 {
974 H5HL_t *heap = NULL; /* Pointer to local heap */
975 H5G_bt_it_lbi_t udata; /* Iteration information */
976 H5O_stab_t stab; /* Symbol table message */
977 herr_t ret_value = SUCCEED; /* Return value */
978
979 FUNC_ENTER_PACKAGE
980
981 /* check arguments */
982 HDassert(grp_oloc && grp_oloc->file);
983 HDassert(lnk);
984
985 /* Get the B-tree & local heap info */
986 if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id))
987 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address")
988
989 /* Pin the heap down in memory */
990 if(NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, stab.heap_addr, H5AC__READ_ONLY_FLAG)))
991 HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to protect symbol table heap")
992
993 /* Remap index for decreasing iteration order */
994 if(order == H5_ITER_DEC) {
995 hsize_t nlinks = 0; /* Number of links in group */
996
997 /* Iterate over the symbol table nodes, to count the links */
998 if(H5B_iterate(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G__node_sumup, &nlinks) < 0)
999 HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "iteration operator failed")
1000
1001 /* Map decreasing iteration order index to increasing iteration order index */
1002 n = nlinks - (n + 1);
1003 } /* end if */
1004
1005 /* Set iteration information */
1006 udata.common.idx = n;
1007 udata.common.num_objs = 0;
1008 udata.common.op = H5G_stab_lookup_by_idx_cb;
1009 udata.heap = heap;
1010 udata.lnk = lnk;
1011 udata.found = FALSE;
1012
1013 /* Iterate over the group members */
1014 if(H5B_iterate(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G__node_by_idx, &udata) < 0)
1015 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed")
1016
1017 /* If we didn't find the link, we almost certainly went out of bounds */
1018 if(!udata.found)
1019 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound")
1020
1021 done:
1022 /* Release resources */
1023 if(heap && H5HL_unprotect(heap) < 0)
1024 HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
1025
1026 FUNC_LEAVE_NOAPI(ret_value)
1027 } /* end H5G__stab_lookup_by_idx() */
1028
1029 #ifndef H5_STRICT_FORMAT_CHECKS
1030
1031 /*-------------------------------------------------------------------------
1032 * Function: H5G__stab_valid
1033 *
1034 * Purpose: Verify that a group's symbol table message is valid. If
1035 * provided, the addresses in alt_stab will be tried if the
1036 * addresses in the group's stab message are invalid, and
1037 * the stab message will be updated if necessary.
1038 *
1039 * NOTE: This function is only called when strict format
1040 * checks are disabled. This is so that, when strict
1041 * format checks are enabled, errors in the symbol table
1042 * messages are not fixed by this function and are instead
1043 * reported by the library.
1044 *
1045 * Return: Non-negative on success/Negative on failure
1046 *
1047 * Programmer: Neil Fortner
1048 * nfortne2@hdfgroup.org
1049 * Mar 17, 2009
1050 *
1051 *-------------------------------------------------------------------------
1052 */
1053 herr_t
H5G__stab_valid(H5O_loc_t * grp_oloc,hid_t dxpl_id,H5O_stab_t * alt_stab)1054 H5G__stab_valid(H5O_loc_t *grp_oloc, hid_t dxpl_id, H5O_stab_t *alt_stab)
1055 {
1056 H5O_stab_t stab; /* Current symbol table */
1057 H5HL_t *heap = NULL; /* Pointer to local heap */
1058 hbool_t changed = FALSE; /* Whether stab has been modified */
1059 herr_t ret_value = SUCCEED; /* Return value */
1060
1061 FUNC_ENTER_PACKAGE_TAG(dxpl_id, grp_oloc->addr, FAIL)
1062
1063 /* Read the symbol table message */
1064 if(NULL == H5O_msg_read(grp_oloc, H5O_STAB_ID, &stab, dxpl_id))
1065 HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "unable to read symbol table message");
1066
1067 /* Check if the symbol table message's b-tree address is valid */
1068 if(H5B_valid(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr) < 0) {
1069 /* Address is invalid, try the b-tree address in the alternate symbol
1070 * table message */
1071 if(!alt_stab || H5B_valid(grp_oloc->file, dxpl_id, H5B_SNODE, alt_stab->btree_addr) < 0)
1072 HGOTO_ERROR(H5E_BTREE, H5E_NOTFOUND, FAIL, "unable to locate b-tree")
1073 else {
1074 /* The alternate symbol table's b-tree address is valid. Adjust the
1075 * symbol table message in the group. */
1076 stab.btree_addr = alt_stab->btree_addr;
1077 changed = TRUE;
1078 } /* end else */
1079 } /* end if */
1080
1081 /* Check if the symbol table message's heap address is valid */
1082 if(NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, stab.heap_addr, H5AC__READ_ONLY_FLAG))) {
1083 /* Address is invalid, try the heap address in the alternate symbol
1084 * table message */
1085 if(!alt_stab || NULL == (heap = H5HL_protect(grp_oloc->file, dxpl_id, alt_stab->heap_addr, H5AC__READ_ONLY_FLAG)))
1086 HGOTO_ERROR(H5E_HEAP, H5E_NOTFOUND, FAIL, "unable to locate heap")
1087 else {
1088 /* The alternate symbol table's heap address is valid. Adjust the
1089 * symbol table message in the group. */
1090 stab.heap_addr = alt_stab->heap_addr;
1091 changed = TRUE;
1092 } /* end else */
1093 } /* end if */
1094
1095 /* Update the symbol table message and clear errors if necessary */
1096 if(changed) {
1097 H5E_clear_stack(NULL);
1098 if(H5O_msg_write(grp_oloc, H5O_STAB_ID, 0, H5O_UPDATE_TIME | H5O_UPDATE_FORCE, &stab, dxpl_id) < 0)
1099 HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to correct symbol table message")
1100 } /* end if */
1101
1102 done:
1103 /* Release resources */
1104 if(heap && H5HL_unprotect(heap) < 0)
1105 HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol table heap")
1106
1107 FUNC_LEAVE_NOAPI_TAG(ret_value, FAIL)
1108 } /* end H5G__stab_valid */
1109 #endif /* H5_STRICT_FORMAT_CHECKS */
1110
1111 #ifndef H5_NO_DEPRECATED_SYMBOLS
1112
1113 /*-------------------------------------------------------------------------
1114 * Function: H5G_stab_get_type_by_idx_cb
1115 *
1116 * Purpose: Callback for B-tree iteration 'by index' info query to
1117 * retrieve the type of an object
1118 *
1119 * Return: Success: Non-negative
1120 * Failure: Negative
1121 *
1122 * Programmer: Quincey Koziol
1123 * Nov 7, 2006
1124 *
1125 *-------------------------------------------------------------------------
1126 */
1127 static herr_t
H5G_stab_get_type_by_idx_cb(const H5G_entry_t * ent,void * _udata)1128 H5G_stab_get_type_by_idx_cb(const H5G_entry_t *ent, void *_udata)
1129 {
1130 H5G_bt_it_gtbi_t *udata = (H5G_bt_it_gtbi_t *)_udata;
1131 herr_t ret_value = SUCCEED; /* Return value */
1132
1133 FUNC_ENTER_NOAPI_NOINIT
1134
1135 /* Sanity check */
1136 HDassert(ent);
1137 HDassert(udata);
1138
1139 /* Check for a soft link */
1140 switch(ent->type) {
1141 case H5G_CACHED_SLINK:
1142 udata->type = H5G_LINK;
1143 break;
1144
1145 case H5G_CACHED_ERROR:
1146 case H5G_NOTHING_CACHED:
1147 case H5G_CACHED_STAB:
1148 case H5G_NCACHED:
1149 default:
1150 {
1151 H5O_loc_t tmp_oloc; /* Temporary object location */
1152 H5O_type_t obj_type; /* Type of object at location */
1153
1154 /* Build temporary object location */
1155 tmp_oloc.file = udata->f;
1156 HDassert(H5F_addr_defined(ent->header));
1157 tmp_oloc.addr = ent->header;
1158
1159 /* Get the type of the object */
1160 if(H5O_obj_type(&tmp_oloc, &obj_type, udata->dxpl_id) < 0)
1161 HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object type")
1162 udata->type = H5G_map_obj_type(obj_type);
1163 }
1164 break;
1165 } /* end switch */
1166
1167 done:
1168 FUNC_LEAVE_NOAPI(ret_value)
1169 } /* end H5G_stab_get_type_by_idx_cb */
1170
1171
1172 /*-------------------------------------------------------------------------
1173 * Function: H5G__stab_get_type_by_idx
1174 *
1175 * Purpose: Private function for H5Gget_objtype_by_idx.
1176 * Returns the type of objects in the group by giving index.
1177 *
1178 * Return: Success: H5G_GROUP(1), H5G_DATASET(2), H5G_TYPE(3)
1179 *
1180 * Failure: UNKNOWN
1181 *
1182 * Programmer: Raymond Lu
1183 * Nov 20, 2002
1184 *
1185 *-------------------------------------------------------------------------
1186 */
1187 H5G_obj_t
H5G__stab_get_type_by_idx(H5O_loc_t * oloc,hsize_t idx,hid_t dxpl_id)1188 H5G__stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
1189 {
1190 H5O_stab_t stab; /* Info about local heap & B-tree */
1191 H5G_bt_it_gtbi_t udata; /* User data for B-tree callback */
1192 H5G_obj_t ret_value = H5G_UNKNOWN; /* Return value */
1193
1194 FUNC_ENTER_PACKAGE_TAG(dxpl_id, oloc->addr, H5G_UNKNOWN)
1195
1196 /* Sanity check */
1197 HDassert(oloc);
1198
1199 /* Get the B-tree & local heap info */
1200 if(NULL == H5O_msg_read(oloc, H5O_STAB_ID, &stab, dxpl_id))
1201 HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "unable to determine local heap address")
1202
1203 /* Set iteration information */
1204 udata.common.idx = idx;
1205 udata.common.num_objs = 0;
1206 udata.common.op = H5G_stab_get_type_by_idx_cb;
1207 udata.f = oloc->file;
1208 udata.dxpl_id = dxpl_id;
1209 udata.type = H5G_UNKNOWN;
1210
1211 /* Iterate over the group members */
1212 if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, H5G__node_by_idx, &udata) < 0)
1213 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "iteration operator failed")
1214
1215 /* If we don't know the type now, we almost certainly went out of bounds */
1216 if(udata.type == H5G_UNKNOWN)
1217 HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "index out of bound")
1218
1219 /* Set the return value */
1220 ret_value = udata.type;
1221
1222 done:
1223 FUNC_LEAVE_NOAPI_TAG(ret_value, H5G_UNKNOWN)
1224 } /* end H5G__stab_get_type_by_idx() */
1225 #endif /* H5_NO_DEPRECATED_SYMBOLS */
1226
1227