diff options
Diffstat (limited to 'src/H5G.c')
-rw-r--r-- | src/H5G.c | 3721 |
1 files changed, 1186 insertions, 2535 deletions
@@ -71,30 +71,17 @@ * +--------------+------------+--------------------------------+ * * - * Modifications: - * - * Robb Matzke, 5 Aug 1997 - * Added calls to H5E. - * - * Robb Matzke, 30 Aug 1997 - * Added `Errors:' field to function prologues. - * - * Pedro Vicente, 22 Aug 2002 - * Added `id to name' support. - * *------------------------------------------------------------------------- */ -#define H5G_PACKAGE /*suppress error about including H5Gpkg */ #define H5F_PACKAGE /*suppress error about including H5Fpkg */ +#define H5G_PACKAGE /*suppress error about including H5Gpkg */ /* Interface initialization */ #define H5_INTERFACE_INIT_FUNC H5G_init_interface /* Packages needed by this file... */ #include "H5private.h" /* Generic Functions */ -#include "H5Aprivate.h" /* Attributes */ -#include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ #include "H5FLprivate.h" /* Free Lists */ @@ -108,102 +95,93 @@ #define H5G_INIT_HEAP 8192 #define H5G_RESERVED_ATOMS 0 -/* - * During name lookups (see H5G_namei()) we sometimes want information about - * a symbolic link or a mount point. The normal operation is to follow the - * symbolic link or mount point and return information about its target. - */ -#define H5G_TARGET_NORMAL 0x0000 -#define H5G_TARGET_SLINK 0x0001 -#define H5G_TARGET_MOUNT 0x0002 -#define H5G_CRT_INTMD_GROUP 0x0004 - /* Local typedefs */ -/* Struct only used by change name callback function */ -typedef struct H5G_names_t { - H5G_entry_t *loc; - H5RS_str_t *src_name; - H5G_entry_t *src_loc; - H5RS_str_t *dst_name; - H5G_entry_t *dst_loc; - H5G_names_op_t op; -} H5G_names_t; - -/* Enum for H5G_namei actions */ -typedef enum { - H5G_NAMEI_TRAVERSE, /* Just traverse groups */ - H5G_NAMEI_INSERT /* Insert entry in group */ -} H5G_namei_act_t ; - -/* - * This table contains a list of object types, descriptions, and the - * functions that determine if some object is a particular type. The table - * is allocated dynamically. - */ -typedef struct H5G_typeinfo_t { - H5G_obj_t type; /*one of the public H5G_* types */ - htri_t (*isa)(H5G_entry_t*, hid_t); /*function to determine type */ - char *desc; /*description of object type */ -} H5G_typeinfo_t; +/* User data for path traversal routine for "insertion file" routine */ +typedef struct { + H5F_t *file; /* Pointer to the file for insertion */ +} H5G_trav_ud1_t; + +/* User data for path traversal routine for moving a link */ +typedef struct { + H5G_obj_t type; /* Type of object being moved */ + const char *src_name; /* Source name for moving object */ + H5G_loc_t *src_loc; /* Source location for moving object */ + const char *dst_name; /* Destination name for moving object */ + H5G_loc_t *dst_loc; /* Destination location for moving object */ +} H5G_trav_ud2_t; + +/* User data for path traversal callback to creating link */ +typedef struct { + H5F_t *file; /* Pointer to the file */ + hid_t dxpl_id; /* Dataset transfer property list */ + H5O_link_t *lnk; /* Pointer to link information to insert */ +} H5G_trav_ud3_t; + +/* User data for path traversal routine for getting object info */ +typedef struct { + H5G_stat_t *statbuf; /* Stat buffer about object */ + hbool_t follow_link; /* Whether we are following a link or not */ + hid_t dxpl_id; /* Dataset transfer property list */ +} H5G_trav_ud4_t; + +/* User data for path traversal routine for getting soft link value */ +typedef struct { + size_t size; /* Size of user buffer */ + char *buf; /* User buffer */ +} H5G_trav_ud5_t; + +/* User data for path traversal routine for removing link (i.e. unlink) */ +typedef struct { + hid_t dxpl_id; /* Dataset transfer property list */ +} H5G_trav_ud6_t; + +/* User data for path traversal routine for inserting object */ +typedef struct { + H5G_loc_t *obj_loc; /* Object location */ + hid_t dxpl_id; /* Dataset transfer property list */ +} H5G_trav_ud7_t; /* Package variables */ /* Local variables */ -static H5G_typeinfo_t *H5G_type_g = NULL; /*object typing info */ -static size_t H5G_ntypes_g = 0; /*entries in type table */ -static size_t H5G_atypes_g = 0; /*entries allocated */ -static char *H5G_comp_g = NULL; /*component buffer */ -static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */ /* Declare a free list to manage the H5G_t struct */ H5FL_DEFINE(H5G_t); H5FL_DEFINE(H5G_shared_t); -/* Declare extern the PQ free list for the wrapped strings */ -H5FL_BLK_EXTERN(str_buf); - -/* Declare a free list to manage haddr_t's */ -H5FL_DEFINE(haddr_t); - /* Private prototypes */ -static herr_t H5G_register_type(H5G_obj_t type, htri_t(*isa)(H5G_entry_t*, hid_t), - const char *desc); -static const char * H5G_component(const char *name, size_t *size_p); -static const char * H5G_basename(const char *name, size_t *size_p); static char * H5G_normalize(const char *name); -static herr_t H5G_namei(const H5G_entry_t *loc_ent, const char *name, - const char **rest/*out*/, H5G_entry_t *grp_ent/*out*/, H5G_entry_t *obj_ent/*out*/, - unsigned target, int *nlinks/*out*/, H5G_namei_act_t action, - H5G_entry_t *ent, hid_t dxpl_id); -static herr_t H5G_traverse_slink(H5G_entry_t *grp_ent/*in,out*/, - H5G_entry_t *obj_ent/*in,out*/, int *nlinks/*in,out*/, hid_t dxpl_id); -static H5G_t *H5G_create(H5G_entry_t *loc, const char *name, hid_t dxpl_id, +static H5G_t *H5G_create(H5G_loc_t *loc, const char *name, hid_t dxpl_id, hid_t gcpl_id, hid_t gapl_id); -static htri_t H5G_isa(H5G_entry_t *ent, hid_t dxpl_id); -static htri_t H5G_link_isa(H5G_entry_t *ent, hid_t dxpl_id); -static H5G_t * H5G_open_oid(H5G_entry_t *ent, hid_t dxpl_id); -static H5G_t *H5G_rootof(H5F_t *f); -static herr_t H5G_link(H5G_entry_t *cur_loc, const char *cur_name, - H5G_entry_t *new_loc, const char *new_name, H5G_link_t type, - unsigned namei_flags, hid_t dxpl_id); -static herr_t H5G_get_num_objs(H5G_entry_t *grp, hsize_t *num_objs, hid_t dxpl_id); -static ssize_t H5G_get_objname_by_idx(H5G_entry_t *loc, hsize_t idx, char* name, size_t size, hid_t dxpl_id); -static H5G_obj_t H5G_get_objtype_by_idx(H5G_entry_t *loc, hsize_t idx, hid_t dxpl_id); -static herr_t H5G_linkval(H5G_entry_t *loc, const char *name, size_t size, +static herr_t H5G_open_oid(H5G_t *grp, hid_t dxpl_id); +static herr_t H5G_insert_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5G_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5G_link(H5G_loc_t *cur_loc, const char *cur_name, + H5G_loc_t *new_loc, const char *new_name, H5G_link_t type, + unsigned traverse_flags, hid_t dxpl_id); +static herr_t H5G_linkval_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5G_linkval(H5G_loc_t *loc, const char *name, size_t size, char *buf/*out*/, hid_t dxpl_id); -static herr_t H5G_set_comment(H5G_entry_t *loc, const char *name, +static herr_t H5G_set_comment(H5G_loc_t *loc, const char *name, const char *buf, hid_t dxpl_id); -static int H5G_get_comment(H5G_entry_t *loc, const char *name, +static int H5G_get_comment(H5G_loc_t *loc, const char *name, size_t bufsize, char *buf, hid_t dxpl_id); -static herr_t H5G_unlink(H5G_entry_t *loc, const char *name, hid_t dxpl_id); -static herr_t H5G_move(H5G_entry_t *src_loc, const char *src_name, - H5G_entry_t *dst_loc, const char *dst_name, hid_t dxpl_id); -static htri_t H5G_common_path(const H5RS_str_t *fullpath_r, - const H5RS_str_t *prefix_r); -static H5RS_str_t *H5G_build_fullpath(const H5RS_str_t *prefix_r, const H5RS_str_t *name_r); -static int H5G_replace_ent(void *obj_ptr, hid_t obj_id, void *key); -static herr_t H5G_copy(H5G_entry_t *ent_src, H5G_entry_t *loc_dst, +static herr_t H5G_unlink_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5G_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id); +static herr_t H5G_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5G_move(H5G_loc_t *src_loc, const char *src_name, + H5G_loc_t *dst_loc, const char *dst_name, hid_t dxpl_id); +static herr_t H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *name_dst, hid_t plist_id); @@ -239,19 +217,19 @@ static herr_t H5G_copy(H5G_entry_t *ent_src, H5G_entry_t *loc_dst, hid_t H5Gcreate(hid_t loc_id, const char *name, size_t size_hint) { - H5G_entry_t *loc = NULL; - H5G_t *grp = NULL; - hid_t tmp_gcpl = (-1); /* Temporary group creation property list */ - hid_t ret_value; + H5G_loc_t loc; + H5G_t *grp = NULL; + hid_t tmp_gcpl = (-1); /* Temporary group creation property list */ + hid_t ret_value; - FUNC_ENTER_API(H5Gcreate, FAIL); + FUNC_ENTER_API(H5Gcreate, FAIL) H5TRACE3("i","isz",loc_id,name,size_hint); /* Check arguments */ - if (NULL==(loc=H5G_loc (loc_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given"); + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") /* Check if we need to create a non-standard GCPL */ if(size_hint > 0) { @@ -277,16 +255,16 @@ H5Gcreate(hid_t loc_id, const char *name, size_t size_hint) /* Set the non-default local heap size hint */ ginfo.lheap_size_hint = size_hint; if(H5P_set(gc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set group info") + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set group info") } /* end if */ else tmp_gcpl = H5P_GROUP_CREATE_DEFAULT; /* Create the group */ - if (NULL == (grp = H5G_create(loc, name, H5AC_dxpl_id, tmp_gcpl, H5P_DEFAULT))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group"); - if ((ret_value = H5I_register(H5I_GROUP, grp)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group"); + if(NULL == (grp = H5G_create(&loc, name, H5AC_dxpl_id, tmp_gcpl, H5P_DEFAULT))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") + if((ret_value = H5I_register(H5I_GROUP, grp)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") done: if(tmp_gcpl > 0 && tmp_gcpl != H5P_GROUP_CREATE_DEFAULT) @@ -298,8 +276,8 @@ done: H5G_close(grp); } /* end if */ - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Gcreate() */ /*------------------------------------------------------------------------- @@ -334,16 +312,16 @@ done: hid_t H5Gcreate_expand(hid_t loc_id, const char *name, hid_t gcpl_id, hid_t gapl_id) { - H5G_entry_t *loc = NULL; - H5G_t *grp = NULL; - hid_t ret_value; + H5G_loc_t loc; + H5G_t *grp = NULL; + hid_t ret_value; FUNC_ENTER_API(H5Gcreate_expand, FAIL) /* Check arguments */ - if (NULL==(loc=H5G_loc (loc_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if (!name || !*name) + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") /* Check group creation property list */ @@ -362,13 +340,13 @@ H5Gcreate_expand(hid_t loc_id, const char *name, hid_t gcpl_id, hid_t gapl_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list") #endif /* LATER */ - if (NULL == (grp = H5G_create(loc, name, H5AC_dxpl_id, gcpl_id, gapl_id))) + if(NULL == (grp = H5G_create(&loc, name, H5AC_dxpl_id, gcpl_id, gapl_id))) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") - if ((ret_value = H5I_register(H5I_GROUP, grp)) < 0) + if((ret_value = H5I_register(H5I_GROUP, grp)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") done: - if(ret_value<0) { + if(ret_value < 0) { if(grp!=NULL) H5G_close(grp); } /* end if */ @@ -399,40 +377,57 @@ done: hid_t H5Gopen(hid_t loc_id, const char *name) { - hid_t ret_value = FAIL; H5G_t *grp = NULL; - H5G_entry_t *loc = NULL; - H5G_entry_t ent; + H5G_loc_t loc; + H5G_loc_t grp_loc; /* Location used to open group */ + H5G_name_t grp_path; /* Opened object group hier. path */ + H5O_loc_t grp_oloc; /* Opened object object location */ + hbool_t ent_found = FALSE; /* Entry at 'name' found */ + hid_t ret_value = FAIL; - FUNC_ENTER_API(H5Gopen, FAIL); + FUNC_ENTER_API(H5Gopen, FAIL) H5TRACE2("i","is",loc_id,name); /* Check args */ - if (NULL==(loc=H5G_loc(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name"); + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") + + /* Set up opened group location to fill in */ + grp_loc.oloc = &grp_oloc; + grp_loc.path = &grp_path; + H5G_loc_reset(&grp_loc); - /* Open the parent group, making sure it's a group */ - if (H5G_find(loc, name, &ent/*out*/, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found"); + /* Find the group object */ + if(H5G_loc_find(&loc, name, &grp_loc/*out*/, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found") + ent_found = TRUE; + + /* Check that the object found is the correct type */ + if(H5O_obj_type(&grp_oloc, H5AC_dxpl_id) != H5G_GROUP) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not a group") /* Open the group */ - if ((grp = H5G_open(&ent, H5AC_dxpl_id))==NULL) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group"); + if((grp = H5G_open(&grp_loc, H5AC_dxpl_id)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") /* Register an atom for the group */ - if ((ret_value = H5I_register(H5I_GROUP, grp)) < 0) - HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group"); + if((ret_value = H5I_register(H5I_GROUP, grp)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") done: - if(ret_value<0) { - if(grp!=NULL) + if(ret_value < 0) { + if(grp != NULL) H5G_close(grp); + else { + if(ent_found) + H5G_name_free(&grp_path); + } /* end else */ } /* end if */ - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* H5Gopen() */ /*------------------------------------------------------------------------- @@ -497,76 +492,47 @@ done: * Programmer: Robb Matzke * Monday, March 23, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t H5Giterate(hid_t loc_id, const char *name, int *idx_p, H5G_iterate_t op, void *op_data) { - H5O_stab_t stab; /*info about B-tree */ - int idx; - H5G_bt_it_ud1_t udata; - H5G_t *grp = NULL; - herr_t ret_value; + int last_obj; /* Index of last object looked at */ + int idx; /* Internal location to hold index */ + herr_t ret_value; - FUNC_ENTER_API(H5Giterate, FAIL); + FUNC_ENTER_API(H5Giterate, FAIL) H5TRACE5("e","is*Isxx",loc_id,name,idx_p,op,op_data); /* Check args */ - if (!name || !*name) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified"); + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") idx = (idx_p == NULL ? 0 : *idx_p); - if (!idx_p) - idx_p = &idx; - if (idx<0) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified"); - if (!op) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified"); - - /* - * Open the group on which to operate. We also create a group ID which - * we can pass to the application-defined operator. - */ - if ((udata.group_id = H5Gopen (loc_id, name)) <0) - HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group"); - if ((grp=H5I_object(udata.group_id))==NULL) { - H5Gclose(udata.group_id); - HGOTO_ERROR (H5E_ATOM, H5E_BADATOM, FAIL, "bad group atom"); - } - - /* Get the B-tree info */ - if (NULL==H5O_read (&(grp->ent), H5O_STAB_ID, 0, &stab, H5AC_dxpl_id)) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address") + if(idx < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified") + if(!op) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified") - /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */ - udata.skip = idx; - udata.heap_addr = stab.heap_addr; - udata.op = op; - udata.op_data = op_data; + /* Set number of objects looked at to zero */ + last_obj = 0; - /* Set the number of entries looked at to zero */ - udata.final_ent = 0; - - /* Iterate over the group members */ - if ((ret_value = H5B_iterate (H5G_fileof(grp), H5AC_dxpl_id, H5B_SNODE, - H5G_node_iterate, stab.btree_addr, &udata))<0) - HERROR (H5E_SYM, H5E_CANTNEXT, "iteration operator failed"); - - H5I_dec_ref (udata.group_id); /*also closes 'grp'*/ + /* Call private function. */ + if((ret_value = H5G_obj_iterate(loc_id, name, idx, &last_obj, op, op_data, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group iteration failed") /* Check for too high of a starting index (ex post facto :-) */ /* (Skipping exactly as many entries as are in the group is currently an error) */ - if(idx>0 && idx>=udata.final_ent) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified"); + if(idx > 0 && idx >= last_obj) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified") /* Set the index we stopped at */ - *idx_p=udata.final_ent; + if(idx_p) + *idx_p=last_obj; done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Giterate() */ /*------------------------------------------------------------------------- @@ -582,33 +548,32 @@ done: * Programmer: Raymond Lu * Nov 20, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs) { - H5G_entry_t *loc = NULL; /* Pointer to symbol table entry */ + H5G_loc_t loc; /* Location of object */ herr_t ret_value; - FUNC_ENTER_API(H5Gget_num_objs, FAIL); + FUNC_ENTER_API(H5Gget_num_objs, FAIL) H5TRACE2("e","i*h",loc_id,num_objs); /* Check args */ - if (NULL==(loc=H5G_loc (loc_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID"); - if(H5G_get_type(loc,H5AC_ind_dxpl_id)!=H5G_GROUP) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a group"); - if (!num_objs) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "nil pointer"); + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID") + if(H5O_obj_type(loc.oloc, H5AC_ind_dxpl_id) != H5G_GROUP) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") + if(!num_objs) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "nil pointer") /* Call private function. */ - ret_value = H5G_get_num_objs(loc, num_objs, H5AC_ind_dxpl_id); + if((ret_value = H5G_obj_count(loc.oloc, num_objs, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "can't determine ") done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Gget_num_objs() */ /*------------------------------------------------------------------------- @@ -638,24 +603,25 @@ done: ssize_t H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name, size_t size) { - H5G_entry_t *loc = NULL; /* Pointer to symbol table entry */ - ssize_t ret_value = FAIL; + H5G_loc_t loc; /* Object location */ + ssize_t ret_value; - FUNC_ENTER_API(H5Gget_objname_by_idx, FAIL); + FUNC_ENTER_API(H5Gget_objname_by_idx, FAIL) H5TRACE4("Zs","ihsz",loc_id,idx,name,size); /* Check args */ - if (NULL==(loc=H5G_loc (loc_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID"); - if(H5G_get_type(loc,H5AC_ind_dxpl_id)!=H5G_GROUP) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a group"); + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID") + if(H5O_obj_type(loc.oloc, H5AC_ind_dxpl_id) != H5G_GROUP) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") - /*call private function*/ - ret_value = H5G_get_objname_by_idx(loc, idx, name, size, H5AC_ind_dxpl_id); + /* Call internal function*/ + if((ret_value = H5G_obj_get_name_by_idx(loc.oloc, idx, name, size, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "can't get object name") done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Gget_objname_by_idx() */ /*------------------------------------------------------------------------- @@ -678,25 +644,25 @@ done: H5G_obj_t H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx) { - H5G_entry_t *loc = NULL; /* Pointer to symbol table entry */ + H5G_loc_t loc; /* Object location */ H5G_obj_t ret_value; - FUNC_ENTER_API(H5Gget_objtype_by_idx, H5G_UNKNOWN); + FUNC_ENTER_API(H5Gget_objtype_by_idx, H5G_UNKNOWN) H5TRACE2("Go","ih",loc_id,idx); /* Check args */ - if (NULL==(loc=H5G_loc (loc_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a location ID"); - if(H5G_get_type(loc,H5AC_ind_dxpl_id)!=H5G_GROUP) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a group"); + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a location ID") + if(H5O_obj_type(loc.oloc, H5AC_ind_dxpl_id) != H5G_GROUP) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a group") - /*call private function*/ - ret_value = H5G_get_objtype_by_idx(loc, idx, H5AC_ind_dxpl_id); + /* Call internal function*/ + if((ret_value = H5G_obj_get_type_by_idx(loc.oloc, idx, H5AC_ind_dxpl_id)) == H5G_UNKNOWN) + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "can't get object type") done: - FUNC_LEAVE_API(ret_value); - -} + FUNC_LEAVE_API(ret_value) +} /* end H5Gget_objtype_by_idx() */ /*------------------------------------------------------------------------- @@ -724,39 +690,40 @@ herr_t H5Gmove2(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, const char *dst_name) { - H5G_entry_t *src_loc=NULL; - H5G_entry_t *dst_loc=NULL; + H5G_loc_t src_loc, *src_loc_p; + H5G_loc_t dst_loc, *dst_loc_p; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_API(H5Gmove2, FAIL); + FUNC_ENTER_API(H5Gmove2, FAIL) H5TRACE4("e","isis",src_loc_id,src_name,dst_loc_id,dst_name); - if (src_loc_id != H5G_SAME_LOC && NULL==(src_loc=H5G_loc(src_loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); - if (dst_loc_id != H5G_SAME_LOC && NULL==(dst_loc=H5G_loc(dst_loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); - if (!src_name || !*src_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified"); - if (!dst_name || !*dst_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified"); - - if(src_loc_id == H5G_SAME_LOC && dst_loc_id == H5G_SAME_LOC) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not be both H5G_SAME_LOC"); - } else if(src_loc_id == H5G_SAME_LOC) { - src_loc = dst_loc; - } - else if(dst_loc_id == H5G_SAME_LOC) { - dst_loc = src_loc; - } - else if(src_loc->file != dst_loc->file) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file."); - - if (H5G_move(src_loc, src_name, dst_loc, dst_name, H5AC_dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to change object name"); + if(src_loc_id != H5G_SAME_LOC && H5G_loc(src_loc_id, &src_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(dst_loc_id != H5G_SAME_LOC && H5G_loc(dst_loc_id, &dst_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!src_name || !*src_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified") + if(!dst_name || !*dst_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified") + + /* Set up src & dst location pointers */ + src_loc_p = &src_loc; + dst_loc_p = &dst_loc; + if(src_loc_id == H5G_SAME_LOC && dst_loc_id == H5G_SAME_LOC) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not be both H5G_SAME_LOC") + else if(src_loc_id == H5G_SAME_LOC) + src_loc_p = dst_loc_p; + else if(dst_loc_id == H5G_SAME_LOC) + dst_loc_p = src_loc_p; + else if(src_loc_p->oloc->file != dst_loc_p->oloc->file) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file.") + + if(H5G_move(src_loc_p, src_name, dst_loc_p, dst_name, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to change object name") done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Gmove2() */ /*------------------------------------------------------------------------- @@ -790,43 +757,43 @@ herr_t H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, hid_t new_loc_id, const char *new_name) { - H5G_entry_t *cur_loc = NULL; - H5G_entry_t *new_loc = NULL; + H5G_loc_t cur_loc, *cur_loc_p; + H5G_loc_t new_loc, *new_loc_p; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_API(H5Glink2, FAIL); + FUNC_ENTER_API(H5Glink2, FAIL) H5TRACE5("e","isGlis",cur_loc_id,cur_name,type,new_loc_id,new_name); /* Check arguments */ - if (cur_loc_id != H5G_SAME_LOC && NULL==(cur_loc=H5G_loc(cur_loc_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); - if (new_loc_id != H5G_SAME_LOC && NULL==(new_loc=H5G_loc(new_loc_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); - if (type!=H5G_LINK_HARD && type!=H5G_LINK_SOFT) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "unrecognized link type"); - if (!cur_name || !*cur_name) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified"); - if (!new_name || !*new_name) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified"); - - if(cur_loc_id == H5G_SAME_LOC && new_loc_id == H5G_SAME_LOC) { - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not be both H5G_SAME_LOC"); - } - else if(cur_loc_id == H5G_SAME_LOC) { - cur_loc = new_loc; - } - else if(new_loc_id == H5G_SAME_LOC) { - new_loc = cur_loc; - } - else if(cur_loc->file != new_loc->file) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file."); - - if (H5G_link(cur_loc, cur_name, new_loc, new_name, type, H5G_TARGET_NORMAL, H5AC_dxpl_id) <0) - HGOTO_ERROR (H5E_SYM, H5E_LINK, FAIL, "unable to create link"); + if(cur_loc_id != H5G_SAME_LOC && H5G_loc(cur_loc_id, &cur_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(new_loc_id != H5G_SAME_LOC && H5G_loc(new_loc_id, &new_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(type != H5G_LINK_HARD && type != H5G_LINK_SOFT) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unrecognized link type") + if(!cur_name || !*cur_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified") + if(!new_name || !*new_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified") + + /* Set up current & new location pointers */ + cur_loc_p = &cur_loc; + new_loc_p = &new_loc; + if(cur_loc_id == H5G_SAME_LOC && new_loc_id == H5G_SAME_LOC) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not be both H5G_SAME_LOC") + else if(cur_loc_id == H5G_SAME_LOC) + cur_loc_p = new_loc_p; + else if(new_loc_id == H5G_SAME_LOC) + new_loc_p = cur_loc_p; + else if(cur_loc_p->oloc->file != new_loc_p->oloc->file) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file.") + + if(H5G_link(cur_loc_p, cur_name, new_loc_p, new_name, type, H5G_TARGET_NORMAL, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to create link") done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Glink2() */ /*------------------------------------------------------------------------- @@ -851,25 +818,25 @@ done: herr_t H5Gunlink(hid_t loc_id, const char *name) { - H5G_entry_t *loc = NULL; + H5G_loc_t loc; herr_t ret_value=SUCCEED; /* Return value */ - FUNC_ENTER_API(H5Gunlink, FAIL); + FUNC_ENTER_API(H5Gunlink, FAIL) H5TRACE2("e","is",loc_id,name); /* Check arguments */ - if (NULL==(loc=H5G_loc(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name"); + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") /* Unlink */ - if (H5G_unlink(loc, name, H5AC_dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to unlink object"); + if(H5G_unlink(&loc, name, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to unlink object") done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Gunlink() */ /*------------------------------------------------------------------------- @@ -893,25 +860,25 @@ herr_t H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, H5G_stat_t *statbuf/*out*/) { - H5G_entry_t *loc = NULL; - herr_t ret_value=SUCCEED; /* Return value */ + H5G_loc_t loc; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(H5Gget_objinfo, FAIL); + FUNC_ENTER_API(H5Gget_objinfo, FAIL) H5TRACE4("e","isbx",loc_id,name,follow_link,statbuf); /* Check arguments */ - if (NULL==(loc=H5G_loc (loc_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); - if (!name || !*name) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified"); + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") /* Get info */ - if (H5G_get_objinfo (loc, name, follow_link, statbuf, H5AC_ind_dxpl_id)<0) - HGOTO_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "cannot stat object"); + if(H5G_get_objinfo(&loc, name, follow_link, statbuf, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "cannot stat object") done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Gget_objinfo() */ /*------------------------------------------------------------------------- @@ -935,25 +902,25 @@ done: herr_t H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/) { - H5G_entry_t *loc = NULL; - herr_t ret_value=SUCCEED; /* Return value */ + H5G_loc_t loc; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(H5Gget_linkval, FAIL); + FUNC_ENTER_API(H5Gget_linkval, FAIL) H5TRACE4("e","iszx",loc_id,name,size,buf); /* Check arguments */ - if (NULL==(loc=H5G_loc (loc_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); - if (!name || !*name) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified"); + if(H5G_loc(loc_id, &loc)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") /* Get the link value */ - if (H5G_linkval (loc, name, size, buf, H5AC_ind_dxpl_id)<0) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value"); + if(H5G_linkval(&loc, name, size, buf, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value") done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Gget_linkval() */ /*------------------------------------------------------------------------- @@ -969,30 +936,28 @@ done: * Programmer: Robb Matzke * Monday, July 20, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t H5Gset_comment(hid_t loc_id, const char *name, const char *comment) { - H5G_entry_t *loc = NULL; - herr_t ret_value=SUCCEED; /* Return value */ + H5G_loc_t loc; + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_API(H5Gset_comment, FAIL); + FUNC_ENTER_API(H5Gset_comment, FAIL) H5TRACE3("e","iss",loc_id,name,comment); - if (NULL==(loc=H5G_loc(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified"); + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") - if (H5G_set_comment(loc, name, comment, H5AC_dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to set comment value"); + if(H5G_set_comment(&loc, name, comment, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to set comment value") done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Gset_comment() */ /*------------------------------------------------------------------------- @@ -1014,32 +979,99 @@ done: * Programmer: Robb Matzke * Monday, July 20, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf) { - H5G_entry_t *loc = NULL; + H5G_loc_t loc; int ret_value; - FUNC_ENTER_API(H5Gget_comment, FAIL); + FUNC_ENTER_API(H5Gget_comment, FAIL) H5TRACE4("Is","iszs",loc_id,name,bufsize,buf); - if (NULL==(loc=H5G_loc(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location"); - if (!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified"); - if (bufsize>0 && !buf) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no buffer specified"); + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + if(bufsize > 0 && !buf) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no buffer specified") - if ((ret_value=H5G_get_comment(loc, name, bufsize, buf, H5AC_ind_dxpl_id))<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to get comment value"); + if((ret_value = H5G_get_comment(&loc, name, bufsize, buf, H5AC_ind_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to get comment value") done: - FUNC_LEAVE_API(ret_value); -} + FUNC_LEAVE_API(ret_value) +} /* end H5Gget_comment() */ + + +/*------------------------------------------------------------------------- + * Function: H5Gget_create_plist + * + * Purpose: Returns a copy of the group creation property list. + * + * Return: Success: ID for a copy of the group creation + * property list. The property list ID should be + * released by calling H5Pclose(). + * + * Failure: FAIL + * + * Programmer: Quincey Koziol + * Tuesday, October 25, 2005 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Gget_create_plist(hid_t group_id) +{ + htri_t ginfo_exists = 0; + H5G_t *grp = NULL; + H5P_genplist_t *gcpl_plist; + H5P_genplist_t *new_plist; + hid_t new_gcpl_id = FAIL; + hid_t ret_value = FAIL; + + FUNC_ENTER_API(H5Gget_create_plist, FAIL) + H5TRACE1("i","i", group_id); + + /* Check args */ + if(NULL == (grp = H5I_object_verify(group_id, H5I_GROUP))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group") + + /* Copy the default group creation property list */ + if(NULL == (gcpl_plist = H5I_object(H5P_LST_GROUP_CREATE_g))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get default group creation property list") + if((new_gcpl_id = H5P_copy_plist(gcpl_plist)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to copy the creation property list") + if(NULL == (new_plist = H5I_object(new_gcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list") + + /* Check for the group having a group info message */ + if((ginfo_exists = H5O_exists(&(grp->oloc), H5O_GINFO_ID, 0, H5AC_dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") + if(ginfo_exists) { + H5O_ginfo_t ginfo; /* Group info message */ + + /* Read the group info */ + if(NULL == H5O_read(&(grp->oloc), H5O_GINFO_ID, 0, &ginfo, H5AC_dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info") + + /* Set the group info for the property list */ + if(H5P_set(new_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set group info") + } /* end if */ + + /* Set the return value */ + ret_value = new_gcpl_id; + +done: + if(ret_value < 0) { + if(new_gcpl_id > 0) + (void)H5I_dec_ref(new_gcpl_id); + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Gget_create_plist() */ /*------------------------------------------------------------------------- @@ -1055,18 +1087,19 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Gcopy(hid_t id_src, hid_t loc_dst, const char *name_dst, hid_t plist_id) +H5Gcopy(hid_t src_id, hid_t dst_id, const char *name_dst, hid_t plist_id) { - H5G_entry_t *ent_src = NULL, *ent_dst=NULL; - herr_t ret_value = SUCCEED; /* Return value */ + H5G_loc_t src_loc; /* Source object group location */ + H5G_loc_t dst_loc; /* Destination group location */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5Gcopy, FAIL) /* Check arguments */ - if(NULL == (ent_src = H5G_loc(id_src))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(NULL == (ent_dst = H5G_loc(loc_dst))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(H5G_loc(src_id, &src_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(H5G_loc(dst_id, &dst_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") if(!name_dst || !*name_dst) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") @@ -1078,7 +1111,7 @@ else if(TRUE != H5P_isa_class(plist_id, H5P_DATATYPE_CREATE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not object create property list") - if(H5G_copy(ent_src, ent_dst, name_dst, plist_id) < 0) + if(H5G_copy(&src_loc, &dst_loc, name_dst, plist_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") done: @@ -1103,21 +1136,20 @@ done: * Programmer: Robb Matzke * Monday, January 5, 1998 * - * Modifications: + * Notes: The group creation properties are registered in the property + * list interface initialization routine (H5P_init_interface) + * so that the file creation property class can inherit from it + * correctly. (Which allows the file creation property list to + * control the group creation properties of the root group of + * a file) QAK - 24/10/2005 * *------------------------------------------------------------------------- */ static herr_t H5G_init_interface(void) { - /* Group creation property class variables. In sequence, they are, - * - Creation property list class to modify - * - Default value for "group info" - */ H5P_genclass_t *crt_pclass; - H5O_ginfo_t ginfo = H5G_CRT_GROUP_INFO_DEF; - size_t nprops; /* Number of properties */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_init_interface); @@ -1126,16 +1158,6 @@ H5G_init_interface(void) (H5I_free_t)H5G_close) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to initialize interface"); - /* - * Initialize the type info table. Begin with the most general types and - * end with the most specific. For instance, any object that has a data - * type message is a datatype but only some of them are datasets. - */ - H5G_register_type(H5G_TYPE, H5T_isa, "datatype"); - H5G_register_type(H5G_GROUP, H5G_isa, "group"); - H5G_register_type(H5G_DATASET, H5D_isa, "dataset"); - H5G_register_type(H5G_LINK, H5G_link_isa, "link"); - /* ========== group Creation Property Class Initialization ============*/ assert(H5P_CLS_GROUP_CREATE_g!=-1); @@ -1143,18 +1165,6 @@ H5G_init_interface(void) if(NULL == (crt_pclass = H5I_object(H5P_CLS_GROUP_CREATE_g))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") - /* Get the number of properties in the class */ - if(H5P_get_nprops_pclass(crt_pclass, &nprops, FALSE)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't query number of properties") - - /* Assume that if there are properties in the class, they are the default ones */ - if(nprops==0) { - /* Register group info */ - if(H5P_register(crt_pclass,H5G_CRT_GROUP_INFO_NAME,H5G_CRT_GROUP_INFO_SIZE, - &ginfo,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - } /* end if */ - /* Only register the default property list if it hasn't been created yet */ if(H5P_LST_GROUP_CREATE_g==(-1)) { /* Register the default group creation property list */ @@ -1180,118 +1190,33 @@ done: * Programmer: Robb Matzke * Monday, January 5, 1998 * - * Modifications: - * Robb Matzke, 2002-03-28 - * Free the global component buffer. *------------------------------------------------------------------------- */ int H5G_term_interface(void) { - size_t i; - int n=0; + int n = 0; - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_term_interface); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_term_interface) if (H5_interface_initialize_g) { - if ((n=H5I_nmembers(H5I_GROUP))) { + if ((n = H5I_nmembers(H5I_GROUP))) { H5I_clear_type(H5I_GROUP, FALSE); } else { - /* Empty the object type table */ - for (i=0; i<H5G_ntypes_g; i++) - H5MM_xfree(H5G_type_g[i].desc); - H5G_ntypes_g = H5G_atypes_g = 0; - H5G_type_g = H5MM_xfree(H5G_type_g); - /* Destroy the group object id group */ H5I_dec_type_ref(H5I_GROUP); /* Free the global component buffer */ - H5G_comp_g = H5MM_xfree(H5G_comp_g); - H5G_comp_alloc_g = 0; + H5G_traverse_term_interface(); /* Mark closed */ H5_interface_initialize_g = 0; n = 1; /*H5I*/ - } - } - - FUNC_LEAVE_NOAPI(n); -} - - -/*------------------------------------------------------------------------- - * Function: H5G_register_type - * - * Purpose: Register a new object type so H5G_get_type() can detect it. - * One should always register a general type before a more - * specific type. For instance, any object that has a datatype - * message is a datatype, but only some of those objects are - * datasets. - * - * Return: Success: Non-negative - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Wednesday, November 4, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_register_type(H5G_obj_t type, htri_t(*isa)(H5G_entry_t*, hid_t), const char *_desc) -{ - char *desc = NULL; - size_t i; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_register_type); - - assert(type>=0); - assert(isa); - assert(_desc); - - /* Copy the description */ - if (NULL==(desc=H5MM_strdup(_desc))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for object type description"); - - /* - * If the type is already registered then just update its entry without - * moving it to the end - */ - for (i=0; i<H5G_ntypes_g; i++) { - if (H5G_type_g[i].type==type) { - H5G_type_g[i].isa = isa; - H5MM_xfree(H5G_type_g[i].desc); - H5G_type_g[i].desc = desc; - HGOTO_DONE(SUCCEED); - } - } - - /* Increase table size */ - if (H5G_ntypes_g>=H5G_atypes_g) { - size_t n = MAX(32, 2*H5G_atypes_g); - H5G_typeinfo_t *x = H5MM_realloc(H5G_type_g, - n*sizeof(H5G_typeinfo_t)); - if (!x) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for objec type table"); - H5G_atypes_g = n; - H5G_type_g = x; - } - - /* Add a new entry */ - H5G_type_g[H5G_ntypes_g].type = type; - H5G_type_g[H5G_ntypes_g].isa = isa; - H5G_type_g[H5G_ntypes_g].desc = desc; /*already copied*/ - H5G_ntypes_g++; + } /* end else */ + } /* end if */ -done: - if (ret_value<0) - H5MM_xfree(desc); - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(n) +} /* end H5G_term_interface() */ /*------------------------------------------------------------------------- @@ -1302,8 +1227,6 @@ done: * the size in characters of the component through SIZE_P not * counting leading slashes or the null terminator. * - * Errors: - * * Return: Success: Ptr into NAME. * * Failure: Ptr to the null terminator of NAME. @@ -1312,15 +1235,13 @@ done: * matzke@llnl.gov * Aug 11 1997 * - * Modifications: - * *------------------------------------------------------------------------- */ -static const char * +const char * H5G_component(const char *name, size_t *size_p) { /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_component); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_component) assert(name); @@ -1329,54 +1250,8 @@ H5G_component(const char *name, size_t *size_p) if (size_p) *size_p = HDstrcspn(name, "/"); - FUNC_LEAVE_NOAPI(name); -} - - -/*------------------------------------------------------------------------- - * Function: H5G_basename - * - * Purpose: Returns a pointer to the last component of the specified - * name. The length of the component is returned through SIZE_P. - * The base name is followed by zero or more slashes and a null - * terminator, but SIZE_P does not count the slashes or the null - * terminator. - * - * Note: The base name of the root directory is a single slash. - * - * Return: Success: Ptr to base name. - * - * Failure: Ptr to the null terminator. - * - * Programmer: Robb Matzke - * Thursday, September 17, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static const char * -H5G_basename(const char *name, size_t *size_p) -{ - size_t i; - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_basename); - - /* Find the end of the base name */ - i = HDstrlen(name); - while (i>0 && '/'==name[i-1]) - --i; - - /* Skip backward over base name */ - while (i>0 && '/'!=name[i-1]) - --i; - - /* Watch out for root special case */ - if ('/'==name[i] && size_p) - *size_p = 1; - - FUNC_LEAVE_NOAPI(name+i); -} + FUNC_LEAVE_NOAPI(name) +} /* end H5G_component() */ /*------------------------------------------------------------------------- @@ -1446,411 +1321,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_namei - * - * Purpose: Translates a name to a symbol table entry. - * - * If the specified name can be fully resolved, then this - * function returns the symbol table entry for the named object - * through the OBJ_ENT argument. The symbol table entry for the - * group containing the named object is returned through the - * GRP_ENT argument if it is non-null. However, if the name - * refers to the root object then the GRP_ENT will be - * initialized with an undefined object header address. The - * REST argument, if present, will point to the null terminator - * of NAME. - * - * If the specified name cannot be fully resolved, then OBJ_ENT - * is initialized with the undefined object header address. The - * REST argument will point into the NAME argument to the start - * of the component that could not be located. The GRP_ENT will - * contain the entry for the symbol table that was being - * searched at the time of the failure and will have an - * undefined object header address if the search failed at the - * root object. For instance, if NAME is `/foo/bar/baz' and the - * root directory exists and contains an entry for `foo', and - * foo is a group that contains an entry for bar, but bar is not - * a group, then the results will be that REST points to `baz', - * OBJ_ENT has an undefined object header address, and GRP_ENT - * is the symbol table entry for `bar' in `/foo'. - * - * Every file has a root group whose name is `/'. Components of - * a name are separated from one another by one or more slashes - * (/). Slashes at the end of a name are ignored. If the name - * begins with a slash then the search begins at the root group - * of the file containing LOC_ENT. Otherwise it begins at - * LOC_ENT. The component `.' is a no-op, but `..' is not - * understood by this function (unless it appears as an entry in - * the symbol table). - * - * Symbolic links are followed automatically, but if TARGET - * includes the H5G_TARGET_SLINK bit and the last component of - * the name is a symbolic link then that link is not followed. - * The *NLINKS value is decremented each time a link is followed - * and link traversal fails if the value would become negative. - * If NLINKS is the null pointer then a default value is used. - * - * Mounted files are handled by calling H5F_mountpoint() after - * each step of the translation. If the input argument to that - * function is a mount point then the argument shall be replaced - * with information about the root group of the mounted file. - * But if TARGET includes the H5G_TARGET_MOUNT bit and the last - * component of the name is a mount point then H5F_mountpoint() - * is not called and information about the mount point itself is - * returned. - * - * Errors: - * - * Return: Success: Non-negative if name can be fully resolved. - * See above for values of REST, GRP_ENT, and - * OBJ_ENT. NLINKS has been decremented for - * each symbolic link that was followed. - * - * Failure: Negative if the name could not be fully - * resolved. See above for values of REST, - * GRP_ENT, and OBJ_ENT. - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 11 1997 - * - * Modifications: - * Robb Matzke, 2002-03-28 - * The component name buffer on the stack has been replaced by - * a dynamically allocated buffer on the heap in order to - * remove limitations on the length of a name component. - * There are two reasons that the buffer pointer is global: - * (1) We want to be able to reuse the buffer without - * allocating and freeing it each time this function is - * called. - * (2) We need to be able to free it from H5G_term_interface() - * when the library terminates. - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002 - * Modified to deep copies of symbol table entries - * Added `id to name' support. - * - * Quincey Koziol, 2003-01-06 - * Added "action" and "ent" parameters to allow different actions when - * working on the last component of a name. (Specifically, this allows - * inserting an entry into a group, instead of trying to look it up) - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_namei(const H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/, - H5G_entry_t *grp_ent/*out*/, H5G_entry_t *obj_ent/*out*/, - unsigned target, int *nlinks/*out*/, H5G_namei_act_t action, - H5G_entry_t *ent, hid_t dxpl_id) -{ - H5G_entry_t _grp_ent; /*entry for current group */ - H5G_entry_t _obj_ent; /*entry found */ - size_t nchars; /*component name length */ - int _nlinks = H5G_NLINKS; - const char *s = NULL; - unsigned null_obj; /* Flag to indicate this function was called with obj_ent set to NULL */ - unsigned null_grp; /* Flag to indicate this function was called with grp_ent set to NULL */ - unsigned obj_copy = 0; /* Flag to indicate that the object entry is copied */ - unsigned group_copy = 0; /* Flag to indicate that the group entry is copied */ - unsigned last_comp = 0; /* Flag to indicate that a component is the last component in the name */ - unsigned did_insert = 0; /* Flag to indicate that H5G_stab_insert was called */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_namei); - - /* Set up "out" parameters */ - if (rest) - *rest = name; - if (!grp_ent) { - grp_ent = &_grp_ent; - null_grp = 1; - } /* end if */ - else - null_grp = 0; - if (!obj_ent) { - obj_ent = &_obj_ent; - null_obj = 1; - } /* end if */ - else - null_obj = 0; - if (!nlinks) - nlinks = &_nlinks; - - /* Check args */ - if (!name || !*name) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "no name given"); - if (!loc_ent) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "no current working group"); - - /* - * Where does the searching start? For absolute names it starts at the - * root of the file; for relative names it starts at CWG. - */ - /* Check if we need to get the root group's entry */ - if ('/' == *name) { - H5G_t *tmp_grp; /* Temporary pointer to root group of file */ - - tmp_grp=H5G_rootof(loc_ent->file); - assert(tmp_grp); - - /* Set the location entry to the root group's entry*/ - loc_ent=&(tmp_grp->ent); - } /* end if */ - - /* Deep copy of the symbol table entry (duplicates strings) */ - if (H5G_ent_copy(obj_ent, loc_ent,H5G_COPY_DEEP)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to copy entry"); - obj_copy = 1; - - H5G_ent_reset(grp_ent); - - /* traverse the name */ - while ((name = H5G_component(name, &nchars)) && *name) { - /* Update the "rest of name" pointer */ - if (rest) - *rest = name; - - /* - * Copy the component name into a null-terminated buffer so - * we can pass it down to the other symbol table functions. - */ - if (nchars+1 > H5G_comp_alloc_g) { - H5G_comp_alloc_g = MAX3(1024, 2*H5G_comp_alloc_g, nchars+1); - H5G_comp_g = H5MM_realloc(H5G_comp_g, H5G_comp_alloc_g); - if (!H5G_comp_g) { - H5G_comp_alloc_g = 0; - HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "unable to allocate component buffer"); - } - } - HDmemcpy(H5G_comp_g, name, nchars); - H5G_comp_g[nchars] = '\0'; - - /* - * The special name `.' is a no-op. - */ - if ('.' == H5G_comp_g[0] && !H5G_comp_g[1]) { - name += nchars; - continue; - } - - /* - * Advance to the next component of the name. - */ - /* If we've already copied a new entry into the group entry, - * it needs to be freed before overwriting it with another entry - */ - if(group_copy) - H5G_free_ent_name(grp_ent); - - /* Transfer "ownership" of the entry's information to the group entry */ - H5G_ent_copy(grp_ent,obj_ent,H5G_COPY_SHALLOW); - H5G_ent_reset(obj_ent); - - /* Set flag that we've copied a new entry into the group entry */ - group_copy =1; - - /* Check if this is the last component of the name */ - if(!((s=H5G_component(name+nchars, NULL)) && *s)) - last_comp=1; - - switch(action) { - case H5G_NAMEI_TRAVERSE: - if (H5G_stab_find(grp_ent, H5G_comp_g, obj_ent/*out*/, dxpl_id )<0) { - /* - * Component was not found in the current symbol table, possibly - * because GRP_ENT isn't a symbol table. - */ - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found"); - } - break; - - case H5G_NAMEI_INSERT: - if(!last_comp) { - if (H5G_stab_find(grp_ent, H5G_comp_g, obj_ent/*out*/, dxpl_id )<0) { - /* If an intermediate group doesn't exist & flag is set, create the group */ - if (target & H5G_CRT_INTMD_GROUP) { - H5G_entry_t new_ent; - - /* Reset group entry */ - H5G_ent_reset(&new_ent); - - /* Create the intermediate group */ - if (H5G_stab_create(grp_ent->file, dxpl_id, 0, &new_ent/*out*/) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create grp"); - - /* Insert new group into current group's symbol table */ - if (H5G_stab_insert(grp_ent, H5G_comp_g, &new_ent, TRUE, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert intermediate group"); - - /* Keep newly created group's entry, so we can traverse into it */ - if (H5G_ent_copy(obj_ent, &new_ent, H5G_COPY_DEEP)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to copy entry"); - - /* Close new group */ - if (H5O_close(&new_ent) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close"); - } - else - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found"); - } - } /* end if */ - else { - did_insert = 1; - if (H5G_stab_insert(grp_ent, H5G_comp_g, ent, TRUE, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert name"); - HGOTO_DONE(SUCCEED); - } /* end else */ - break; - } /* end switch */ - - /* - * If we found a symbolic link then we should follow it. But if this - * is the last component of the name and the H5G_TARGET_SLINK bit of - * TARGET is set then we don't follow it. - */ - if(H5G_CACHED_SLINK==obj_ent->type && - (0==(target & H5G_TARGET_SLINK) || !last_comp)) { - if ((*nlinks)-- <= 0) - HGOTO_ERROR (H5E_SYM, H5E_SLINK, FAIL, "too many links"); - if (H5G_traverse_slink (grp_ent, obj_ent, nlinks, dxpl_id)<0) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "symbolic link traversal failed"); - } - - /* - * Resolve mount points to the mounted group. Do not do this step if - * the H5G_TARGET_MOUNT bit of TARGET is set and this is the last - * component of the name. - */ - if (0==(target & H5G_TARGET_MOUNT) || !last_comp) - H5F_mountpoint(obj_ent/*in,out*/); - - /* next component */ - name += nchars; - } /* end while */ - - /* Update the "rest of name" pointer */ - if (rest) - *rest = name; /*final null */ - - /* If this was an insert, make sure that the insert function was actually - * called (this catches no-op names like "." and "/") */ - if(action == H5G_NAMEI_INSERT && !did_insert) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group already exists"); - -done: - /* If we started with a NULL obj_ent, free the entry information */ - if(null_obj || (ret_value < 0 && obj_copy)) - H5G_free_ent_name(obj_ent); - /* If we started with a NULL grp_ent and we copied something into it, free the entry information */ - if(null_grp && group_copy) - H5G_free_ent_name(grp_ent); - - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5G_traverse_slink - * - * Purpose: Traverses symbolic link. The link head appears in the group - * whose entry is GRP_ENT and the link head entry is OBJ_ENT. - * - * Return: Success: Non-negative, OBJ_ENT will contain information - * about the object to which the link points and - * GRP_ENT will contain the information about - * the group in which the link tail appears. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Friday, April 10, 1998 - * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002 - * Added `id to name' support. - * - * John Mainzer - 6/8/05 - * Modified function to use the new dirtied parmeter of - * H5AC_unprotect(), which allows management of the is_dirty - * field of the cache info to be moved into the cache code. - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/, - H5G_entry_t *obj_ent/*in,out*/, - int *nlinks/*in,out*/, hid_t dxpl_id) -{ - H5O_stab_t stab_mesg; /*info about local heap */ - const char *clv = NULL; /*cached link value */ - char *linkval = NULL; /*the copied link value */ - H5G_entry_t tmp_grp_ent; /* Temporary copy of group entry */ - H5RS_str_t *tmp_user_path_r=NULL, *tmp_canon_path_r=NULL; /* Temporary pointer to object's user path & canonical path */ - const H5HL_t *heap; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_slink); - - /* Portably initialize the temporary group entry */ - H5G_ent_reset(&tmp_grp_ent); - - /* Get the link value */ - if (NULL==H5O_read (grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id)) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address"); - - if (NULL == (heap = H5HL_protect(grp_ent->file, dxpl_id, stab_mesg.heap_addr))) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value") - - clv = H5HL_offset_into(grp_ent->file, heap, obj_ent->cache.slink.lval_offset); - - linkval = H5MM_xstrdup (clv); - assert(linkval); - - if (H5HL_unprotect(grp_ent->file, dxpl_id, heap, stab_mesg.heap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") - - /* Hold the entry's name (& old_name) to restore later */ - tmp_user_path_r=obj_ent->user_path_r; - obj_ent->user_path_r=NULL; - tmp_canon_path_r=obj_ent->canon_path_r; - obj_ent->canon_path_r=NULL; - - /* Free the names for the group entry */ - H5G_free_ent_name(grp_ent); - - /* Clone the group entry, so we can track the names properly */ - H5G_ent_copy(&tmp_grp_ent,grp_ent,H5G_COPY_DEEP); - - /* Traverse the link */ - if (H5G_namei (&tmp_grp_ent, linkval, NULL, grp_ent, obj_ent, H5G_TARGET_NORMAL, nlinks, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link"); - - /* Free the entry's names, we will use the original name for the object */ - H5G_free_ent_name(obj_ent); - - /* Restore previous name for object */ - obj_ent->user_path_r = tmp_user_path_r; - tmp_user_path_r=NULL; - obj_ent->canon_path_r = tmp_canon_path_r; - tmp_canon_path_r=NULL; - -done: - /* Error cleanup */ - if(tmp_user_path_r) - H5RS_decr(tmp_user_path_r); - if(tmp_canon_path_r) - H5RS_decr(tmp_canon_path_r); - - /* Release cloned copy of group entry */ - H5G_free_ent_name(&tmp_grp_ent); - - H5MM_xfree (linkval); - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- * Function: H5G_mkroot * * Purpose: Creates a root group in an empty file and opens it. If a @@ -1866,78 +1336,91 @@ done: * matzke@llnl.gov * Aug 11 1997 * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002 - * Added `id to name' support. - * *------------------------------------------------------------------------- */ herr_t -H5G_mkroot (H5F_t *f, hid_t dxpl_id, H5G_entry_t *ent) +H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *loc) { - H5G_entry_t new_root; /*new root object */ - herr_t ret_value=SUCCEED; /* Return value */ + H5O_loc_t new_root_oloc; /* New root object location */ + H5G_name_t new_root_path; /* New root path */ + H5G_loc_t new_root_loc; /* New root location information */ + H5G_loc_t root_loc; /* Root location information */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_mkroot, FAIL); + FUNC_ENTER_NOAPI(H5G_mkroot, FAIL) /* check args */ - assert(f); - if (f->shared->root_grp) - HGOTO_DONE(SUCCEED); + HDassert(f); + if(f->shared->root_grp) + HGOTO_DONE(SUCCEED) /* Create information needed for group nodes */ - if(H5G_node_init(f)<0) + if(H5G_node_init(f) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group node info") /* * If there is no root object then create one. The root group always starts * with a hard link count of one since it's pointed to by the boot block. */ - if (!ent) { - ent = &new_root; - H5G_ent_reset(ent); - if (H5G_stab_create (f, dxpl_id, (size_t)H5G_SIZE_HINT, ent/*out*/)<0) - HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to create root group"); - if (1 != H5O_link (ent, 1, dxpl_id)) - HGOTO_ERROR (H5E_SYM, H5E_LINK, FAIL, "internal error (wrong link count)"); + if (loc == NULL) { + H5P_genplist_t *fc_plist; /* File creation property list */ + H5O_ginfo_t ginfo; /* Group info parameters */ + + /* Get the file creation property list */ + /* (Which is a sub-class of the group creation property class) */ + if(NULL == (fc_plist = H5I_object(f->shared->fcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + /* Get the group info property */ + if(H5P_get(fc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info") + + /* Set up group location for root group */ + new_root_loc.oloc = &new_root_oloc; + new_root_loc.path = &new_root_path; + H5G_loc_reset(&new_root_loc); + loc = &new_root_loc; + + if(H5G_obj_create(f, dxpl_id, &ginfo, loc->oloc/*out*/) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry") + if(1 != H5O_link(loc->oloc, 1, dxpl_id)) + HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "internal error (wrong link count)") } else { /* * Open the root object as a group. */ - if (H5O_open (ent)<0) - HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open root group"); - } + if(H5O_open(loc->oloc) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open root group") + } /* end else */ /* Create the path names for the root group's entry */ - ent->user_path_r=H5RS_create("/"); - assert(ent->user_path_r); - ent->canon_path_r=H5RS_create("/"); - assert(ent->canon_path_r); - ent->user_path_hidden=0; + H5G_name_init(loc->path, "/"); /* * Create the group pointer. Also decrement the open object count so we * don't count the root group as an open object. The root group will * never be closed. */ - if (NULL==(f->shared->root_grp = H5FL_CALLOC (H5G_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - if (NULL==(f->shared->root_grp->shared = H5FL_CALLOC (H5G_shared_t))) { + if(NULL == (f->shared->root_grp = H5FL_CALLOC(H5G_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + if(NULL == (f->shared->root_grp->shared = H5FL_CALLOC(H5G_shared_t))) { H5FL_FREE(H5G_t, f->shared->root_grp); - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - } - /* Shallow copy (take ownership) of the group entry object */ - if(H5G_ent_copy(&(f->shared->root_grp->ent), ent, H5G_COPY_SHALLOW)<0) - HGOTO_ERROR (H5E_SYM, H5E_CANTCOPY, FAIL, "can't copy group entry") + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + } /* end if */ + + /* Shallow copy (take ownership) of the group object info */ + root_loc.oloc = &(f->shared->root_grp->oloc); + root_loc.path = &(f->shared->root_grp->path); + if(H5G_loc_copy(&root_loc, loc, H5G_COPY_SHALLOW) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "can't copy group object location") f->shared->root_grp->shared->fo_count = 1; - assert (1==f->nopen_objs); + HDassert(1 == f->nopen_objs); f->nopen_objs = 0; done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_mkroot() */ /*------------------------------------------------------------------------- @@ -1946,8 +1429,6 @@ done: * Purpose: Creates a new empty group with the specified name. The name * is either an absolute name or is relative to LOC. * - * Errors: - * * Return: Success: A handle for the group. The group is opened * and should eventually be close by calling * H5G_close(). @@ -1958,85 +1439,88 @@ done: * matzke@llnl.gov * Aug 11 1997 * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002 - * Added `id to name' support. - * *------------------------------------------------------------------------- */ static H5G_t * -H5G_create(H5G_entry_t *loc, const char *name, +H5G_create(H5G_loc_t *loc, const char *name, hid_t dxpl_id, hid_t gcpl_id, hid_t UNUSED gapl_id) { H5G_t *grp = NULL; /*new group */ H5F_t *file = NULL; /* File new group will be in */ H5P_genplist_t *gc_plist; /* Property list created */ - unsigned stab_init=0; /* Flag to indicate that the symbol table was created successfully */ + H5O_ginfo_t ginfo; /* Group info */ + unsigned oloc_init = 0; /* Flag to indicate that the group object location was created successfully */ + H5G_loc_t grp_loc; /* Group location wrapper structure */ H5G_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_create); + FUNC_ENTER_NOAPI_NOINIT(H5G_create) /* check args */ - assert(loc); - assert(name && *name); - assert(gcpl_id != H5P_DEFAULT); + HDassert(loc); + HDassert(name && *name); + HDassert(gcpl_id != H5P_DEFAULT); #ifdef LATER - assert(gapl_id != H5P_DEFAULT); + HDassert(gapl_id != H5P_DEFAULT); #endif /* LATER */ /* create an open group */ - if (NULL==(grp = H5FL_CALLOC(H5G_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - if (NULL==(grp->shared = H5FL_CALLOC(H5G_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + if(NULL == (grp = H5FL_CALLOC(H5G_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + if(NULL == (grp->shared = H5FL_CALLOC(H5G_shared_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") /* What file is the group being added to? */ - if (NULL==(file=H5G_insertion_file(loc, name, dxpl_id))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to locate insertion point"); - - /* Create the group entry */ - if (H5G_stab_create(file, dxpl_id, (size_t)H5G_SIZE_HINT, &(grp->ent)/*out*/) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create grp"); - stab_init=1; /* Indicate that the symbol table information is valid */ + if(NULL == (file = H5G_insertion_file(loc, name, dxpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to locate insertion point") /* Get the property list */ - if (NULL == (gc_plist = H5I_object(gcpl_id))) + if(NULL == (gc_plist = H5I_object(gcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list") - /* insert child name into parent */ - if(H5G_insert(loc,name,&(grp->ent), dxpl_id, gc_plist)<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group"); + /* Get the group info property */ + if(H5P_get(gc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get group info") + + /* Create the group object header */ + if(H5G_obj_create(file, dxpl_id, &ginfo, &(grp->oloc)/*out*/) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group object header") + oloc_init = 1; /* Indicate that the object location information is valid */ + + /* Insert child name into parent */ + grp_loc.oloc = &(grp->oloc); + grp_loc.path = &(grp->path); + if(H5G_insert(loc, name, &grp_loc, dxpl_id, gc_plist) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group") /* Add group to list of open objects in file */ - if(H5FO_top_incr(grp->ent.file, grp->ent.header)<0) + if(H5FO_top_incr(grp->oloc.file, grp->oloc.addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINC, NULL, "can't incr object ref. count") - if(H5FO_insert(grp->ent.file, grp->ent.header, grp->shared)<0) + if(H5FO_insert(grp->oloc.file, grp->oloc.addr, grp->shared) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group into list of open objects") grp->shared->fo_count = 1; /* Set return value */ - ret_value=grp; + ret_value = grp; done: - if(ret_value==NULL) { + if(ret_value == NULL) { /* Check if we need to release the file-oriented symbol table info */ - if(stab_init) { - if(H5O_close(&(grp->ent))<0) - HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "unable to release object header"); - if(H5O_delete(file, dxpl_id,grp->ent.header)<0) - HDONE_ERROR(H5E_SYM, H5E_CANTDELETE, NULL, "unable to delete object header"); + if(oloc_init) { + if(H5O_close(&(grp->oloc)) < 0) + HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "unable to release object header") + if(H5O_delete(file, dxpl_id, grp->oloc.addr) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTDELETE, NULL, "unable to delete object header") } /* end if */ - if(grp!=NULL) { + if(grp != NULL) { if(grp->shared != NULL) H5FL_FREE(H5G_shared_t, grp->shared); H5FL_FREE(H5G_t,grp); - } + } /* end if */ } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_create() */ /*------------------------------------------------------------------------- @@ -2054,61 +1538,30 @@ done: * Programmer: Robb Matzke * Monday, November 2, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ -static htri_t -H5G_isa(H5G_entry_t *ent, hid_t dxpl_id) +htri_t +H5G_isa(H5O_loc_t *loc, hid_t dxpl_id) { + htri_t stab_exists; + htri_t linfo_exists; htri_t ret_value; - FUNC_ENTER_NOAPI_NOINIT(H5G_isa); - - assert(ent); - - if ((ret_value=H5O_exists(ent, H5O_STAB_ID, 0, dxpl_id))<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header"); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5G_link_isa - * - * Purpose: Determines if an object has the requisite form for being - * a soft link. - * - * Return: Success: TRUE if the symbol table entry is of type - * H5G_LINK; FALSE otherwise. - * - * Failure: Shouldn't fail. - * - * Programmer: Quincey Koziol - * Wednesday, June 23, 2004 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static htri_t -H5G_link_isa(H5G_entry_t *ent, hid_t UNUSED dxpl_id) -{ - htri_t ret_value; + FUNC_ENTER_NOAPI_NOINIT(H5G_isa) - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_link_isa); + HDassert(loc); - assert(ent); + /* Check for any of the messages that indicate a group */ + if((stab_exists = H5O_exists(loc, H5O_STAB_ID, 0, dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") + if((linfo_exists = H5O_exists(loc, H5O_LINFO_ID, 0, dxpl_id)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") - if(ent->type == H5G_CACHED_SLINK) - ret_value=TRUE; - else - ret_value=FALSE; + ret_value = (stab_exists > 0 || linfo_exists > 0); - FUNC_LEAVE_NOAPI(ret_value); -} /* end H5G_link_isa() */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_isa() */ /*------------------------------------------------------------------------- @@ -2124,58 +1577,54 @@ H5G_link_isa(H5G_entry_t *ent, hid_t UNUSED dxpl_id) * Programmer: Robb Matzke * Monday, January 5, 1998 * - * Modifications: - * Modified to call H5G_open_oid - QAK - 3/17/99 - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002 - * Added `id to name' support. - * *------------------------------------------------------------------------- */ H5G_t * -H5G_open(H5G_entry_t *ent, hid_t dxpl_id) +H5G_open(H5G_loc_t *loc, hid_t dxpl_id) { H5G_t *grp = NULL; - H5G_shared_t *shared_fo=NULL; - H5G_t *ret_value=NULL; + H5G_shared_t *shared_fo = NULL; + H5G_t *ret_value = NULL; - FUNC_ENTER_NOAPI(H5G_open, NULL); + FUNC_ENTER_NOAPI(H5G_open, NULL) /* Check args */ - assert(ent); + HDassert(loc); + + /* Allocate the group structure */ + if(NULL == (grp = H5FL_CALLOC(H5G_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for group") + + /* Shallow copy (take ownership) of the group location object */ + if(H5O_loc_copy(&(grp->oloc), loc->oloc, H5O_COPY_SHALLOW) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy object location") + if(H5G_name_copy(&(grp->path), loc->path, H5G_COPY_SHALLOW) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy path") /* Check if group was already open */ - if((shared_fo=H5FO_opened(ent->file, ent->header))==NULL) { + if((shared_fo = H5FO_opened(grp->oloc.file, grp->oloc.addr)) == NULL) { /* Clear any errors from H5FO_opened() */ H5E_clear_stack(NULL); /* Open the group object */ - if ((grp=H5G_open_oid(ent, dxpl_id)) ==NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "not found"); + if(H5G_open_oid(grp, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "not found") /* Add group to list of open objects in file */ - if(H5FO_insert(grp->ent.file, grp->ent.header, grp->shared)<0) - { + if(H5FO_insert(grp->oloc.file, grp->oloc.addr, grp->shared) < 0) { H5FL_FREE(H5G_shared_t, grp->shared); HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group into list of open objects") - } + } /* end if */ /* Increment object count for the object in the top file */ - if(H5FO_top_incr(grp->ent.file, grp->ent.header) < 0) + if(H5FO_top_incr(grp->oloc.file, grp->oloc.addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINC, NULL, "can't increment object count") /* Set open object count */ grp->shared->fo_count = 1; - } + } /* end if */ else { - if(NULL == (grp = H5FL_CALLOC(H5G_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for group") - - /* Shallow copy (take ownership) of the group entry object */ - if(H5G_ent_copy(&(grp->ent), ent, H5G_COPY_SHALLOW)<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy group entry") - /* Point to shared group info */ grp->shared = shared_fo; @@ -2183,16 +1632,16 @@ H5G_open(H5G_entry_t *ent, hid_t dxpl_id) shared_fo->fo_count++; /* Check if the object has been opened through the top file yet */ - if(H5FO_top_count(grp->ent.file, grp->ent.header) == 0) { + if(H5FO_top_count(grp->oloc.file, grp->oloc.addr) == 0) { /* Open the object through this top file */ - if(H5O_open(&(grp->ent)) < 0) + if(H5O_open(&(grp->oloc)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open object header") } /* end if */ /* Increment object count for the object in the top file */ - if(H5FO_top_incr(grp->ent.file, grp->ent.header) < 0) + if(H5FO_top_incr(grp->oloc.file, grp->oloc.addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINC, NULL, "can't increment object count") - } + } /* end else */ /* Set return value */ ret_value = grp; @@ -2201,8 +1650,8 @@ done: if (!ret_value && grp) H5FL_FREE(H5G_t,grp); - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_open() */ /*------------------------------------------------------------------------- @@ -2218,59 +1667,43 @@ done: * Programmer: Quincey Koziol * Wednesday, March 17, 1999 * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002 - * Added a deep copy of the symbol table entry - * *------------------------------------------------------------------------- */ -static H5G_t * -H5G_open_oid(H5G_entry_t *ent, hid_t dxpl_id) +static herr_t +H5G_open_oid(H5G_t *grp, hid_t dxpl_id) { - H5G_t *grp = NULL; - H5G_t *ret_value = NULL; - hbool_t ent_opened = FALSE; + hbool_t obj_opened = FALSE; + herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI_NOINIT(H5G_open_oid); + FUNC_ENTER_NOAPI_NOINIT(H5G_open_oid) /* Check args */ - assert(ent); - - /* Open the object, making sure it's a group */ - if (NULL==(grp = H5FL_CALLOC(H5G_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); - if (NULL==(grp->shared = H5FL_CALLOC(H5G_shared_t))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed"); + HDassert(grp); - /* Copy over (take ownership) of the group entry object */ - H5G_ent_copy(&(grp->ent),ent,H5G_COPY_SHALLOW); + /* Allocate the shared information for the group */ + if(NULL == (grp->shared = H5FL_CALLOC(H5G_shared_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* Grab the object header */ - if (H5O_open(&(grp->ent)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open group") - ent_opened = TRUE; + if(H5O_open(&(grp->oloc)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group") + obj_opened = TRUE; /* Check if this object has the right message(s) to be treated as a group */ - if(H5O_exists(&(grp->ent), H5O_STAB_ID, 0, dxpl_id) <= 0) - HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, NULL, "not a group") - - /* Set return value */ - ret_value = grp; + if(H5O_exists(&(grp->oloc), H5O_STAB_ID, 0, dxpl_id) <= 0 + && H5O_exists(&(grp->oloc), H5O_LINFO_ID, 0, dxpl_id) <= 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "not a group") done: - if(!ret_value) { - if(grp) { - if(ent_opened) - H5O_close(&(grp->ent)); - if(grp->shared) - H5FL_FREE(H5G_shared_t, grp->shared); - H5FL_FREE(H5G_t,grp); - } /* end if */ + if(ret_value < 0) { + if(obj_opened) + H5O_close(&(grp->oloc)); + if(grp->shared) + H5FL_FREE(H5G_shared_t, grp->shared); } /* end if */ - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_open_oid() */ /*------------------------------------------------------------------------- @@ -2283,42 +1716,40 @@ done: * Programmer: Robb Matzke * Monday, January 5, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t H5G_close(H5G_t *grp) { - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_close, FAIL); + FUNC_ENTER_NOAPI(H5G_close, FAIL) /* Check args */ - assert(grp && grp->shared); - assert(grp->shared->fo_count > 0); + HDassert(grp && grp->shared); + HDassert(grp->shared->fo_count > 0); --grp->shared->fo_count; - if (0 == grp->shared->fo_count) { - assert (grp!=H5G_rootof(H5G_fileof(grp))); + if(0 == grp->shared->fo_count) { + HDassert(grp != H5G_rootof(H5G_fileof(grp))); /* Remove the group from the list of opened objects in the file */ - if(H5FO_top_decr(grp->ent.file, grp->ent.header) < 0) + if(H5FO_top_decr(grp->oloc.file, grp->oloc.addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't decrement count for object") - if(H5FO_delete(grp->ent.file, H5AC_dxpl_id, grp->ent.header)<0) + if(H5FO_delete(grp->oloc.file, H5AC_dxpl_id, grp->oloc.addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't remove group from list of open objects") - if(H5O_close(&(grp->ent)) < 0) + if(H5O_close(&(grp->oloc)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close") - H5FL_FREE (H5G_shared_t, grp->shared); + H5FL_FREE(H5G_shared_t, grp->shared); } else { /* Decrement the ref. count for this object in the top file */ - if(H5FO_top_decr(grp->ent.file, grp->ent.header) < 0) + if(H5FO_top_decr(grp->oloc.file, grp->oloc.addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't decrement count for object") /* Check reference count for this object in the top file */ - if(H5FO_top_count(grp->ent.file, grp->ent.header) == 0) - if(H5O_close(&(grp->ent)) < 0) + if(H5FO_top_count(grp->oloc.file, grp->oloc.addr) == 0) + if(H5O_close(&(grp->oloc)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close") /* If this group is a mount point and the mount point is the last open @@ -2326,21 +1757,20 @@ H5G_close(H5G_t *grp) */ if(grp->shared->mounted && grp->shared->fo_count == 1) { /* Attempt to close down the file hierarchy */ - if(H5F_try_close(grp->ent.file) < 0) + if(H5F_try_close(grp->oloc.file) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close") } /* end if */ + } /* end else */ - if(H5G_free_ent_name(&(grp->ent))<0) - { - H5FL_FREE (H5G_t,grp); - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't free group entry name"); - } - } + if(H5G_name_free(&(grp->path)) < 0) { + H5FL_FREE(H5G_t,grp); + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't free group entry name") + } /* end if */ - H5FL_FREE (H5G_t,grp); + H5FL_FREE(H5G_t,grp); done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_close() */ @@ -2364,18 +1794,18 @@ done: herr_t H5G_free(H5G_t *grp) { - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_free, FAIL); + FUNC_ENTER_NOAPI(H5G_free, FAIL) - assert(grp && grp->shared); + HDassert(grp && grp->shared); H5FL_FREE(H5G_shared_t, grp->shared); H5FL_FREE(H5G_t, grp); done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_free() */ /*------------------------------------------------------------------------- @@ -2398,275 +1828,238 @@ done: * *------------------------------------------------------------------------- */ -static H5G_t * +H5G_t * H5G_rootof(H5F_t *f) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_rootof); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_rootof) - while (f->mtab.parent) + while(f->mtab.parent) f = f->mtab.parent; - FUNC_LEAVE_NOAPI(f->shared->root_grp); -} + FUNC_LEAVE_NOAPI(f->shared->root_grp) +} /* end H5G_rootof() */ /*------------------------------------------------------------------------- - * Function: H5G_insert - * - * Purpose: Inserts a symbol table entry into the group graph. + * Function: H5G_oloc * - * Errors: + * Purpose: Returns a pointer to the object location for a group. * - * Return: Non-negative on success/Negative on failure + * Return: Success: Ptr to group entry + * Failure: NULL * * Programmer: Robb Matzke - * Friday, September 19, 1997 - * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002 - * Added `id to name' support. - * - * Peter Cao - * May 09, 2005 - * Add flag 'crt_intmd_group' to support creating missing groups + * Tuesday, March 24, 1998 * *------------------------------------------------------------------------- */ -herr_t -H5G_insert(H5G_entry_t *loc, const char *name, H5G_entry_t *ent, hid_t dxpl_id, H5P_genplist_t *oc_plist) +H5O_loc_t * +H5G_oloc(H5G_t *grp) { - herr_t ret_value=SUCCEED; /* Return value */ - unsigned target=H5G_TARGET_NORMAL; - - FUNC_ENTER_NOAPI(H5G_insert, FAIL); - - /* Check args. */ - assert (loc); - assert (name && *name); - assert (ent); - - /* Check for intermediate group creation flag present */ - if(oc_plist != NULL) { - unsigned crt_intmd_group; - - if(H5P_get(oc_plist, H5G_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for creating missing groups"); - - if (crt_intmd_group > 0) - target |= H5G_CRT_INTMD_GROUP; - } /* end if */ - - /* - * Lookup and insert the name -- it shouldn't exist yet. - */ - if (H5G_namei(loc, name, NULL, NULL, NULL, target, NULL, H5G_NAMEI_INSERT, ent, dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "already exists"); + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_oloc) -done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(grp ? &(grp->oloc) : NULL) +} /* end H5G_oloc() */ /*------------------------------------------------------------------------- - * Function: H5G_find - * - * Purpose: Finds an object with the specified NAME at location LOC. On - * successful return, GRP_ENT (if non-null) will be initialized - * with the symbol table information for the group in which the - * object appears (it will have an undefined object header - * address if the object is the root object) and OBJ_ENT will be - * initialized with the symbol table entry for the object - * (OBJ_ENT is optional when the caller is interested only in - * the existence of the object). - * - * Errors: + * Function: H5G_nameof * - * Return: Success: Non-negative, see above for values of GRP_ENT - * and OBJ_ENT. + * Purpose: Returns a pointer to the hier. name for a group. * - * Failure: Negative - * - * Programmer: Robb Matzke - * matzke@llnl.gov - * Aug 12 1997 + * Return: Success: Ptr to hier. name + * Failure: NULL * - * Modifications: - * Removed the "H5G_entry_t *grp_ent" parameter, since it was unused - * Quincey Koziol - * Aug 29 2005 + * Programmer: Quincey Koziol + * Monday, September 12, 2005 * *------------------------------------------------------------------------- */ -herr_t -H5G_find(H5G_entry_t *loc, const char *name, - H5G_entry_t *obj_ent/*out*/, hid_t dxpl_id) +H5G_name_t * +H5G_nameof(H5G_t *grp) { - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5G_find, FAIL); - - /* check args */ - assert (loc); - assert (name && *name); - - if (H5G_namei(loc, name, NULL, NULL, obj_ent, H5G_TARGET_NORMAL, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found"); + /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_nameof) -done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(grp ? &(grp->path) : NULL) +} /* end H5G_nameof() */ /*------------------------------------------------------------------------- - * Function: H5G_entof + * Function: H5G_fileof * - * Purpose: Returns a pointer to the entry for a group. + * Purpose: Returns the file to which the specified group belongs. * - * Return: Success: Ptr to group entry + * Return: Success: File pointer. * * Failure: NULL * * Programmer: Robb Matzke * Tuesday, March 24, 1998 * - * Modifications: - * *------------------------------------------------------------------------- */ -H5G_entry_t * -H5G_entof (H5G_t *grp) +H5F_t * +H5G_fileof(H5G_t *grp) { /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_entof); + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_fileof) - FUNC_LEAVE_NOAPI(grp ? &(grp->ent) : NULL); -} + HDassert(grp); + + FUNC_LEAVE_NOAPI(grp->oloc.file) +} /* end H5G_fileof() */ /*------------------------------------------------------------------------- - * Function: H5G_fileof - * - * Purpose: Returns the file to which the specified group belongs. - * - * Return: Success: File pointer. + * Function: H5G_insert_cb * - * Failure: NULL + * Purpose: Path traversal callback for inserting an object in a group. * - * Programmer: Robb Matzke - * Tuesday, March 24, 1998 + * Return: Non-negative on success/Negative on failure * - * Modifications: + * Programmer: Quincey Koziol + * Tuesday, September 13, 2005 * *------------------------------------------------------------------------- */ -H5F_t * -H5G_fileof (H5G_t *grp) +static herr_t +H5G_insert_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/) { - /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_fileof); + H5G_trav_ud7_t *udata = (H5G_trav_ud7_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ - assert (grp); + FUNC_ENTER_NOAPI_NOINIT(H5G_insert_cb) - FUNC_LEAVE_NOAPI(grp->ent.file); -} + /* Check for object using name already */ + if(obj_loc != NULL) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name already exists") + + /* Insert object into group */ + if(H5G_loc_insert(grp_loc, name, udata->obj_loc, TRUE, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert name") + +done: + if(ret_value < 0) { + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_insert_cb() */ /*------------------------------------------------------------------------- - * Function: H5G_loc - * - * Purpose: Given an object ID return a symbol table entry for the - * object. + * Function: H5G_insert * - * Return: Success: Group pointer. + * Purpose: Inserts a symbol table entry into the group graph. * - * Failure: NULL + * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke - * Tuesday, March 24, 1998 - * - * Modifications: + * Friday, September 19, 1997 * *------------------------------------------------------------------------- */ -H5G_entry_t * -H5G_loc (hid_t loc_id) +herr_t +H5G_insert(H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc, hid_t dxpl_id, H5P_genplist_t *oc_plist) { - H5F_t *f; - H5G_entry_t *ret_value=NULL; - H5G_t *group=NULL; - H5T_t *dt=NULL; - H5D_t *dset=NULL; - H5A_t *attr=NULL; - - FUNC_ENTER_NOAPI(H5G_loc, NULL); - - switch (H5I_get_type(loc_id)) { - case H5I_FILE: - if (NULL==(f=H5I_object (loc_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, NULL, "invalid file ID"); - if (NULL==(ret_value=H5G_entof(H5G_rootof(f)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry for root group"); - - /* Patch up root group's symbol table entry to reflect this file */ - /* (Since the root group info is only stored once for files which - * share an underlying low-level file) - */ - /* (but only for non-mounted files) */ - if(!f->mtab.parent) - ret_value->file = f; - break; + H5G_trav_ud7_t udata; /* User data for callback routine */ + unsigned target_flags = H5G_TARGET_NORMAL; + herr_t ret_value = SUCCEED; /* Return value */ - case H5I_GENPROP_CLS: - case H5I_GENPROP_LST: - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of property list"); + FUNC_ENTER_NOAPI(H5G_insert, FAIL) - case H5I_ERROR_CLASS: - case H5I_ERROR_MSG: - case H5I_ERROR_STACK: - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of error class, message or stack"); + /* Check args. */ + HDassert(loc); + HDassert(name && *name); + HDassert(obj_loc); - case H5I_GROUP: - if (NULL==(group=H5I_object (loc_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, NULL, "invalid group ID"); - if (NULL==(ret_value=H5G_entof(group))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of group"); - break; + /* Check for intermediate group creation flag present */ + if(oc_plist != NULL) { + unsigned crt_intmd_group; - case H5I_DATATYPE: - if (NULL==(dt=H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid type ID"); - if (NULL==(ret_value=H5T_entof(dt))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of datatype"); - break; + if(H5P_get(oc_plist, H5G_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for creating missing groups") - case H5I_DATASPACE: - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of dataspace"); + if (crt_intmd_group > 0) + target_flags |= H5G_CRT_INTMD_GROUP; + } /* end if */ - case H5I_DATASET: - if (NULL==(dset=H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid data ID"); - if (NULL==(ret_value=H5D_entof(dset))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of dataset"); - break; + /* Set up user data callback for path traversal */ + udata.obj_loc = obj_loc; + udata.dxpl_id = dxpl_id; - case H5I_ATTR: - if (NULL==(attr=H5I_object(loc_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid attribute ID"); - if (NULL==(ret_value=H5A_entof(attr))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of attribute"); - break; + /* + * Lookup and insert the name -- it shouldn't exist yet. + */ + if(H5G_traverse(loc, name, target_flags, H5G_insert_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "can't insert object in group") - case H5I_REFERENCE: - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of reference"); +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_insert() */ - default: - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object ID"); - } + +/*------------------------------------------------------------------------- + * Function: H5G_link_cb + * + * Purpose: Callback for creating a link to an object. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, September 19, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/) +{ + H5G_trav_ud3_t *udata = (H5G_trav_ud3_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_link_cb) + + /* Check if the name in this group resolved to a valid location */ + /* (which is not what we want) */ + if(obj_loc != NULL) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name already exists") + + /* Check for crossing file boundaries with a new hard link */ + if(udata->lnk->type == H5G_LINK_HARD) { + /* Check that both objects are in same file */ + if(grp_loc->oloc->file->shared != udata->file->shared) + HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "interfile hard links are not allowed") + } /* end if */ + + /* Set the link's name correctly */ + /* Casting away const OK -QAK */ + udata->lnk->name = name; + + /* Insert link into group */ + if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, (hbool_t)(udata->lnk->type == H5G_LINK_HARD ? TRUE : FALSE), udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object") done: - FUNC_LEAVE_NOAPI(ret_value); -} + if(ret_value < 0) { + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_link_cb() */ /*------------------------------------------------------------------------- @@ -2688,431 +2081,280 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5G_link (H5G_entry_t *cur_loc, const char *cur_name, H5G_entry_t *new_loc, - const char *new_name, H5G_link_t type, unsigned namei_flags, hid_t dxpl_id) +H5G_link(H5G_loc_t *cur_loc, const char *cur_name, H5G_loc_t *new_loc, + const char *new_name, H5G_link_t type, unsigned traverse_flags, hid_t dxpl_id) { - H5G_entry_t cur_obj; /*entry for the link tail */ - unsigned cur_obj_init=0; /* Flag to indicate that the current object is initialized */ - H5G_entry_t grp_ent; /*ent for grp containing link hd*/ - H5O_stab_t stab_mesg; /*symbol table message */ - const char *rest = NULL; /*last component of new name */ - char *norm_cur_name = NULL; /* Pointer to normalized current name */ - char *norm_new_name = NULL; /* Pointer to normalized current name */ - size_t nchars; /*characters in component */ - size_t offset; /*offset to sym-link value */ - herr_t ret_value=SUCCEED; /* Return value */ + char *norm_cur_name = NULL; /* Pointer to normalized current name */ + char *norm_new_name = NULL; /* Pointer to normalized current name */ + H5G_trav_ud3_t udata; /* User data for callback */ + H5O_link_t lnk; /* Link to insert */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_link); + FUNC_ENTER_NOAPI_NOINIT(H5G_link) /* Check args */ - assert (cur_loc); - assert (new_loc); - assert (cur_name && *cur_name); - assert (new_name && *new_name); + HDassert(cur_loc); + HDassert(new_loc); + HDassert(cur_name && *cur_name); + HDassert(new_name && *new_name); /* Get normalized copies of the current and new names */ - if((norm_cur_name=H5G_normalize(cur_name))==NULL) - HGOTO_ERROR (H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name"); - if((norm_new_name=H5G_normalize(new_name))==NULL) - HGOTO_ERROR (H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name"); + if((norm_cur_name = H5G_normalize(cur_name)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") + if((norm_new_name = H5G_normalize(new_name)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") - switch (type) { + switch(type) { case H5G_LINK_SOFT: - /* - * Lookup the the new_name so we can get the group which will contain - * the new entry. The entry shouldn't exist yet. - */ - if (H5G_namei(new_loc, norm_new_name, &rest, &grp_ent, NULL, - H5G_TARGET_NORMAL, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)>=0) - HGOTO_ERROR (H5E_SYM, H5E_EXISTS, FAIL, "already exists"); - H5E_clear_stack (NULL); /*it's okay that we didn't find it*/ - rest = H5G_component (rest, &nchars); - - /* - * There should be one component left. Make sure it's null - * terminated and that `rest' points to it. - */ - assert(!rest[nchars]); - - /* - * Add the link-value to the local heap for the symbol table which - * will contain the link. - */ - if (NULL==H5O_read (&grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id)) - HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to determine local heap address"); - if ((size_t)(-1)==(offset=H5HL_insert (grp_ent.file, dxpl_id, - stab_mesg.heap_addr, HDstrlen(norm_cur_name)+1, norm_cur_name))) - HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to write link value to local heap"); - H5O_reset (H5O_STAB_ID, &stab_mesg); - - /* - * Create a symbol table entry for the link. The object header is - * undefined and the cache contains the link-value offset. - */ - H5G_ent_reset(&cur_obj); - cur_obj.file = grp_ent.file; - cur_obj.type = H5G_CACHED_SLINK; - cur_obj.cache.slink.lval_offset = offset; - cur_obj_init=1; /* Indicate that the cur_obj struct is initialized */ - - /* - * Insert the link head in the symbol table. This shouldn't ever - * fail because we've already checked that the link head doesn't - * exist and the file is writable (because the local heap is - * writable). But if it does, the only side effect is that the local - * heap has some extra garbage in it. - * - * Note: We don't increment the link count of the destination object - */ - if (H5G_stab_insert (&grp_ent, rest, &cur_obj, FALSE, dxpl_id)<0) - HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object"); + /* Construct link information for eventual insertion */ + lnk.type = H5G_LINK_SOFT; + lnk.u.soft.name = norm_cur_name; + + /* Set up user data for creating soft link */ + udata.file = NULL; /* no file info necessary for soft link */ break; case H5G_LINK_HARD: - if (H5G_namei(cur_loc, norm_cur_name, NULL, NULL, &cur_obj, namei_flags, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found"); - cur_obj_init=1; /* Indicate that the cur_obj struct is initialized */ - if (H5G_insert (new_loc, norm_new_name, &cur_obj, dxpl_id, NULL)<0) - HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object"); + { + H5O_loc_t obj_oloc; /* Location of object to link to */ + + /* Get object location for object pointed to */ + if(H5G_obj_find(cur_loc, norm_cur_name, traverse_flags, &obj_oloc, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found") + + /* Construct link information for eventual insertion */ + lnk.type = H5G_LINK_HARD; + lnk.u.hard.addr = obj_oloc.addr; + + /* Set up user data for creating hard link */ + udata.file = obj_oloc.file; + } /* end case */ break; default: - HGOTO_ERROR (H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type"); + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type") + } /* end switch */ + + /* Set up common link data */ +#ifdef H5_HAVE_GETTIMEOFDAY + { + struct timeval now_tv; + + HDgettimeofday(&now_tv, NULL); + lnk.ctime = now_tv.tv_sec; } +#else /* H5_HAVE_GETTIMEOFDAY */ + lnk.ctime = HDtime(NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + lnk.cset = H5T_CSET_ASCII; /* XXX: Allow user to set this */ + /* lnk.name = name; */ /* This will be set in callback */ -done: - /* Free the group's ID to name buffer, if creating a soft link */ - if(type == H5G_LINK_SOFT) - H5G_free_ent_name(&grp_ent); + /* Set up common user data */ + udata.lnk = &lnk; + udata.dxpl_id = dxpl_id; - /* Free the ID to name buffer */ - if(cur_obj_init) - H5G_free_ent_name(&cur_obj); + /* Traverse the destination path & create new link */ + if(H5G_traverse(new_loc, norm_new_name, H5G_TARGET_NORMAL, H5G_link_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert link") +done: /* Free the normalized path names */ if(norm_cur_name) H5MM_xfree(norm_cur_name); if(norm_new_name) H5MM_xfree(norm_new_name); - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_link() */ /*------------------------------------------------------------------------- - * Function: H5G_get_type - * - * Purpose: Returns the type of object pointed to by `ent'. + * Function: H5G_get_objinfo_cb * - * Return: Success: An object type defined in H5Gpublic.h + * Purpose: Callback for retrieving info about an object. This routine + * gets the info * - * Failure: H5G_UNKNOWN - * - * Programmer: Robb Matzke - * Wednesday, November 4, 1998 + * Return: Non-negative on success/Negative on failure * - * Modifications: + * Programmer: Quincey Koziol + * Tuesday, September 20, 2005 * *------------------------------------------------------------------------- */ -H5G_obj_t -H5G_get_type(H5G_entry_t *ent, hid_t dxpl_id) +static herr_t +H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/) { - htri_t isa; - size_t i; - H5G_obj_t ret_value=H5G_UNKNOWN; /* Return value */ - - FUNC_ENTER_NOAPI(H5G_get_type, H5G_UNKNOWN); - - for (i=H5G_ntypes_g; i>0; --i) { - if ((isa=(H5G_type_g[i-1].isa)(ent, dxpl_id))<0) { - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type"); - } else if (isa) { - HGOTO_DONE(H5G_type_g[i-1].type); - } - } - - if (0==i) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type"); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} + H5G_trav_ud4_t *udata = (H5G_trav_ud4_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ - -/*------------------------------------------------------------------------- - * Function: H5G_get_objinfo - * - * Purpose: Returns information about an object. - * - * Return: Success: Non-negative with info about the object - * returned through STATBUF if it isn't the null - * pointer. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Monday, April 13, 1998 - * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002 - * Added `id to name' support. - * - * John Mainzer - 6/8/05 - * Modified function to use the new dirtied parmeter of - * H5AC_unprotect(), which allows management of the is_dirty - * field of the cache info to be moved into the cache code. - * - *------------------------------------------------------------------------- - */ -herr_t -H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link, - H5G_stat_t *statbuf/*out*/, hid_t dxpl_id) -{ - H5G_entry_t grp_ent, obj_ent; - herr_t ret_value=SUCCEED; /* Return value */ + FUNC_ENTER_NOAPI_NOINIT(H5G_get_objinfo_cb) - FUNC_ENTER_NOAPI(H5G_get_objinfo, FAIL); + /* Check if the name in this group resolved to a valid link */ + if(lnk == NULL && obj_loc == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") - assert (loc); - assert (name && *name); - if (statbuf) HDmemset (statbuf, 0, sizeof *statbuf); + /* Only modify user's buffer if it's available */ + if(udata->statbuf) { + H5G_stat_t *statbuf = udata->statbuf; /* Convenience pointer for statbuf */ - /* Find the object's symbol table entry */ - if (H5G_namei(loc, name, NULL, &grp_ent/*out*/, &obj_ent/*out*/, - (unsigned)(follow_link?H5G_TARGET_NORMAL:H5G_TARGET_SLINK), NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)<0) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to stat object"); + /* Reset buffer */ + HDmemset(statbuf, 0, sizeof(H5G_stat_t)); - /* - * Initialize the stat buf. Symbolic links aren't normal objects and - * therefore don't have much of the normal info. However, the link value - * length is specific to symbolic links. - */ - if (statbuf) { /* Common code to retrieve the file's fileno */ - if(H5F_get_fileno(obj_ent.file,&statbuf->fileno)<0) - HGOTO_ERROR (H5E_FILE, H5E_BADVALUE, FAIL, "unable to read fileno"); - - /* Retrieve information specific to each type of entry */ - if (H5G_CACHED_SLINK==obj_ent.type) { - H5O_stab_t stab_mesg; /* Symbol table message info */ - const char *s; /* Pointer to link value */ - const H5HL_t *heap; /* Pointer to local heap for group */ - - /* Named object is a symbolic link */ - if (NULL == H5O_read(&grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id)) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read symbolic link value") + /* (Use the object location's file info, if it's available) */ + if(H5F_get_fileno((obj_loc ? obj_loc : grp_loc)->oloc->file, &statbuf->fileno) < 0) + HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "unable to read fileno") + + /* Get common info from link */ + if(lnk != NULL) { + statbuf->cset = lnk->cset; + statbuf->ctime = lnk->ctime; + } /* end if */ + else { + /* lookup must be on '.' */ + HDassert(HDstrcmp(name, ".") == 0); - /* Lock the local heap */ - if (NULL == (heap = H5HL_protect(grp_ent.file, dxpl_id, stab_mesg.heap_addr))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value") + /* Set "fake" hard link info */ + statbuf->cset = H5T_CSET_ASCII; + statbuf->ctime = 0; + } /* end else */ - s = H5HL_offset_into(grp_ent.file, heap, obj_ent.cache.slink.lval_offset); + /* Get info for soft link */ + /* (If we don't follow the link, we can retrieve info about the soft link itself) */ + if(!udata->follow_link && lnk && lnk->type == H5G_LINK_SOFT) { + /* Set object type */ + statbuf->type = H5G_LINK; - statbuf->u.slink.linklen = HDstrlen(s) + 1; /*count the null terminator*/ + /* Get length of link value */ + statbuf->u.slink.linklen = HDstrlen(lnk->u.soft.name) + 1; /*count the null terminator*/ + } /* end if */ + /* Get info for hard link */ + else { + /* Get object type */ + statbuf->type = H5O_obj_type(obj_loc->oloc, udata->dxpl_id); + if(statbuf->type == H5G_UNKNOWN) + H5E_clear_stack(NULL); /* clear any errors resulting from checking type */ - /* Release the local heap */ - if (H5HL_unprotect(grp_ent.file, dxpl_id, heap, stab_mesg.heap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") + /* Get basic info for object */ + statbuf->u.obj.objno = obj_loc->oloc->addr; + statbuf->u.obj.nlink = H5O_link(obj_loc->oloc, 0, udata->dxpl_id); - /* Set object type */ - statbuf->type = H5G_LINK; - } else { - /* Some other type of object */ - statbuf->u.obj.objno = obj_ent.header; - statbuf->u.obj.nlink = H5O_link (&obj_ent, 0, dxpl_id); - if (NULL==H5O_read(&obj_ent, H5O_MTIME_ID, 0, &(statbuf->u.obj.mtime), dxpl_id)) { + /* Get creation time for object */ + if(NULL == H5O_read(obj_loc->oloc, H5O_MTIME_ID, 0, &(statbuf->u.obj.mtime), udata->dxpl_id)) { H5E_clear_stack(NULL); - if (NULL==H5O_read(&obj_ent, H5O_MTIME_NEW_ID, 0, &(statbuf->u.obj.mtime), dxpl_id)) { + if(NULL == H5O_read(obj_loc->oloc, H5O_MTIME_NEW_ID, 0, &(statbuf->u.obj.mtime), udata->dxpl_id)) { H5E_clear_stack(NULL); statbuf->u.obj.mtime = 0; - } - } - /* Get object type */ - statbuf->type = H5G_get_type(&obj_ent, dxpl_id); - H5E_clear_stack(NULL); /*clear errors resulting from checking type*/ + } /* end if */ + } /* end if */ /* Get object header information */ - if(H5O_get_info(&obj_ent, &(statbuf->u.obj.ohdr), dxpl_id)<0) + if(H5O_get_info(obj_loc->oloc, &(statbuf->u.obj.ohdr), udata->dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object header information") - } + } /* end else */ } /* end if */ done: - /* Free the ID to name buffers */ - H5G_free_ent_name(&grp_ent); - H5G_free_ent_name(&obj_ent); + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_get_objinfo_cb() */ /*------------------------------------------------------------------------- - * Function: H5G_get_num_objs + * Function: H5G_get_objinfo * - * Purpose: Private function for H5Gget_num_objs. Returns the number - * of objects in the group. It iterates all B-tree leaves - * and sum up total number of group members. + * Purpose: Returns information about an object. * - * Return: Success: Non-negative + * Return: Success: Non-negative with info about the object + * returned through STATBUF if it isn't the null + * pointer. * * Failure: Negative * - * Programmer: Raymond Lu - * Nov 20, 2002 - * - * Modifications: + * Programmer: Robb Matzke + * Monday, April 13, 1998 * *------------------------------------------------------------------------- */ -static herr_t -H5G_get_num_objs(H5G_entry_t *loc, hsize_t *num_objs, hid_t dxpl_id) +herr_t +H5G_get_objinfo(H5G_loc_t *loc, const char *name, hbool_t follow_link, + H5G_stat_t *statbuf/*out*/, hid_t dxpl_id) { - H5O_stab_t stab_mesg; /*info about B-tree */ - herr_t ret_value; - - FUNC_ENTER_NOAPI_NOINIT(H5G_get_num_objs); - - /* Sanity check */ - assert(loc); - assert(num_objs); - - /* Reset the number of objects in the group */ - *num_objs = 0; - - /* Get the B-tree info */ - if (NULL==H5O_read (loc, H5O_STAB_ID, 0, &stab_mesg, dxpl_id)) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address"); - - /* Iterate over the group members */ - if ((ret_value = H5B_iterate (loc->file, dxpl_id, H5B_SNODE, - H5G_node_sumup, stab_mesg.btree_addr, num_objs))<0) - HERROR (H5E_SYM, H5E_CANTINIT, "iteration operator failed"); + H5G_trav_ud4_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ -done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_ENTER_NOAPI(H5G_get_objinfo, FAIL) - -/*------------------------------------------------------------------------- - * Function: H5G_get_objname_by_idx - * - * Purpose: Private function for H5Gget_objname_by_idx. - * Returns the name of objects in the group by giving index. - * - * Return: Success: Non-negative - * - * Failure: Negative - * - * Programmer: Raymond Lu - * Nov 20, 2002 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static ssize_t -H5G_get_objname_by_idx(H5G_entry_t *loc, hsize_t idx, char* name, size_t size, hid_t dxpl_id) -{ - H5O_stab_t stab; /*info about local heap & B-tree */ - H5G_bt_it_ud2_t udata; /* Iteration information */ - ssize_t ret_value; /* Return value */ + HDassert(loc); + HDassert(name && *name); - FUNC_ENTER_NOAPI_NOINIT(H5G_get_objname_by_idx); + /* Set up user data for retrieving information */ + udata.statbuf = statbuf; + udata.follow_link = follow_link; + udata.dxpl_id = dxpl_id; - /* Sanity check */ - assert(loc); - - /* Get the B-tree & local heap info */ - if (NULL==H5O_read (loc, H5O_STAB_ID, 0, &stab, dxpl_id)) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address"); - - /* Set iteration information */ - udata.idx = idx; - udata.num_objs = 0; - udata.heap_addr = stab.heap_addr; - udata.name = NULL; - - /* Iterate over the group members */ - if ((ret_value = H5B_iterate (loc->file, dxpl_id, H5B_SNODE, - H5G_node_name, stab.btree_addr, &udata))<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed"); - - /* If we don't know the name now, we almost certainly went out of bounds */ - if(udata.name==NULL) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound"); - - /* Get the length of the name */ - ret_value = (ssize_t)HDstrlen(udata.name); - - /* Copy the name into the user's buffer, if given */ - if(name) { - HDstrncpy(name, udata.name, MIN((size_t)(ret_value+1),size)); - if((size_t)ret_value >= size) - name[size-1]='\0'; - } /* end if */ + /* Traverse the group hierarchy to locate the object to get info about */ + if(H5G_traverse(loc, name, (unsigned)(follow_link ? H5G_TARGET_NORMAL : H5G_TARGET_SLINK), + H5G_get_objinfo_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") done: - /* Free the duplicated name */ - if(udata.name!=NULL) - H5MM_xfree(udata.name); - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_get_objinfo() */ /*------------------------------------------------------------------------- - * Function: H5G_get_objtype_by_idx - * - * Purpose: Private function for H5Gget_objtype_by_idx. - * Returns the type of objects in the group by giving index. - * - * Return: Success: H5G_GROUP(1), H5G_DATASET(2), H5G_TYPE(3) + * Function: H5G_linkval_cb * - * Failure: UNKNOWN + * Purpose: Callback for retrieving soft link value for an object. * - * Programmer: Raymond Lu - * Nov 20, 2002 + * Return: Non-negative on success/Negative on failure * - * Modifications: + * Programmer: Quincey Koziol + * Tuesday, September 20, 2005 * *------------------------------------------------------------------------- */ -static H5G_obj_t -H5G_get_objtype_by_idx(H5G_entry_t *loc, hsize_t idx, hid_t dxpl_id) +static herr_t +H5G_linkval_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, + H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/) { - H5O_stab_t stab_mesg; /*info about local heap & B-tree */ - H5G_bt_it_ud3_t udata; /* User data for B-tree callback */ - H5G_obj_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_get_objtype_by_idx); + H5G_trav_ud5_t *udata = (H5G_trav_ud5_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ - /* Sanity check */ - assert(loc); - - /* Get the B-tree & local heap info */ - if (NULL==H5O_read (loc, H5O_STAB_ID, 0, &stab_mesg, dxpl_id)) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address"); + FUNC_ENTER_NOAPI_NOINIT(H5G_linkval_cb) - /* Set iteration information */ - udata.idx = idx; - udata.num_objs = 0; - udata.type = H5G_UNKNOWN; + /* Check if the name in this group resolved to a valid link */ + if(lnk == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") - /* Iterate over the group members */ - if (H5B_iterate (loc->file, dxpl_id, H5B_SNODE, - H5G_node_type, stab_mesg.btree_addr, &udata)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "iteration operator failed"); + if(H5G_LINK_SOFT != lnk->type) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object is not a symbolic link") - /* If we don't know the type now, we almost certainly went out of bounds */ - if(udata.type==H5G_UNKNOWN) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "index out of bound"); - - ret_value = udata.type; + /* Copy to output buffer */ + if(udata->size > 0 && udata->buf) { + HDstrncpy(udata->buf, lnk->u.soft.name, udata->size); + if(HDstrlen(lnk->u.soft.name) >= udata->size) + udata->buf[udata->size - 1] = '\0'; + } /* end if */ done: - FUNC_LEAVE_NOAPI(ret_value); -} + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_linkval_cb() */ /*------------------------------------------------------------------------- @@ -3131,65 +2373,27 @@ done: * Programmer: Robb Matzke * Monday, April 13, 1998 * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002 - * Added `id to name' support. - * - * John Mainzer - 6/8/05 - * Modified function to use the new dirtied parmeter of - * H5AC_unprotect(), which allows management of the is_dirty - * field of the cache info to be moved into the cache code. - * *------------------------------------------------------------------------- */ static herr_t -H5G_linkval (H5G_entry_t *loc, const char *name, size_t size, char *buf/*out*/, hid_t dxpl_id) +H5G_linkval(H5G_loc_t *loc, const char *name, size_t size, char *buf/*out*/, hid_t dxpl_id) { - const char *s = NULL; - H5G_entry_t grp_ent, obj_ent; - H5O_stab_t stab_mesg; - const H5HL_t *heap; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_linkval); - - /* - * Get the symbol table entry for the link head and the symbol table - * entry for the group in which the link head appears. - */ - if (H5G_namei(loc, name, NULL, &grp_ent/*out*/, &obj_ent/*out*/, - H5G_TARGET_SLINK, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)<0) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "symbolic link was not found"); - if (H5G_CACHED_SLINK!=obj_ent.type) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "object is not a symbolic link"); - - /* - * Get the address of the local heap for the link value and a pointer - * into that local heap. - */ - if (NULL==H5O_read (&grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id)) - HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to determine local heap address"); + H5G_trav_ud5_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ - if (NULL == (heap = H5HL_protect(grp_ent.file, dxpl_id, stab_mesg.heap_addr))) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value") + FUNC_ENTER_NOAPI_NOINIT(H5G_linkval) - s = H5HL_offset_into(grp_ent.file, heap, obj_ent.cache.slink.lval_offset); + /* Set up user data for retrieving information */ + udata.size = size; + udata.buf = buf; - /* Copy to output buffer */ - if (size>0 && buf) - HDstrncpy (buf, s, size); - - if (H5HL_unprotect(grp_ent.file, dxpl_id, heap, stab_mesg.heap_addr, H5AC__NO_FLAGS_SET) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") + /* Traverse the group hierarchy to locate the object to get info about */ + if(H5G_traverse(loc, name, H5G_TARGET_SLINK, H5G_linkval_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") done: - /* Free the ID to name buffers */ - H5G_free_ent_name(&grp_ent); - H5G_free_ent_name(&obj_ent); - - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* H5G_linkval() */ /*------------------------------------------------------------------------- @@ -3202,44 +2406,36 @@ done: * Programmer: Robb Matzke * Monday, July 20, 1998 * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002 - * Added `id to name' support. - * *------------------------------------------------------------------------- */ static herr_t -H5G_set_comment(H5G_entry_t *loc, const char *name, const char *buf, hid_t dxpl_id) +H5G_set_comment(H5G_loc_t *loc, const char *name, const char *buf, hid_t dxpl_id) { - H5G_entry_t obj_ent; + H5O_loc_t obj_oloc; /* Object's location */ H5O_name_t comment; - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_set_comment); + FUNC_ENTER_NOAPI_NOINIT(H5G_set_comment) /* Get the symbol table entry for the object */ - if (H5G_find(loc, name, &obj_ent/*out*/, dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found"); + if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, &obj_oloc/*out*/, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") /* Remove the previous comment message if any */ - if (H5O_remove(&obj_ent, H5O_NAME_ID, 0, TRUE, dxpl_id)<0) + if(H5O_remove(&obj_oloc, H5O_NAME_ID, 0, TRUE, dxpl_id) < 0) H5E_clear_stack(NULL); /* Add the new message */ - if (buf && *buf) { - comment.s = H5MM_xstrdup(buf); - if (H5O_modify(&obj_ent, H5O_NAME_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, &comment, dxpl_id)<0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to set comment object header message"); - H5O_reset(H5O_NAME_ID, &comment); - } + if(buf && *buf) { + /* Casting away const OK -QAK */ + comment.s = (char *)buf; + if(H5O_modify(&obj_oloc, H5O_NAME_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, &comment, dxpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to set comment object header message") + } /* end if */ done: - /* Free the ID to name buffer */ - H5G_free_ent_name(&obj_ent); - - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_set_comment() */ /*------------------------------------------------------------------------- @@ -3256,30 +2452,25 @@ done: * Programmer: Robb Matzke * Monday, July 20, 1998 * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002 - * Added `id to name' support. - * *------------------------------------------------------------------------- */ static int -H5G_get_comment(H5G_entry_t *loc, const char *name, size_t bufsize, char *buf, hid_t dxpl_id) +H5G_get_comment(H5G_loc_t *loc, const char *name, size_t bufsize, char *buf, hid_t dxpl_id) { H5O_name_t comment; - H5G_entry_t obj_ent; - int ret_value; + H5O_loc_t obj_oloc; /* Object's location */ + int ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_get_comment); + FUNC_ENTER_NOAPI_NOINIT(H5G_get_comment) /* Get the symbol table entry for the object */ - if (H5G_find(loc, name, &obj_ent/*out*/, dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found"); + if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, &obj_oloc/*out*/, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") /* Get the message */ comment.s = NULL; - if (NULL==H5O_read(&obj_ent, H5O_NAME_ID, 0, &comment, dxpl_id)) { - if (buf && bufsize>0) + if(NULL == H5O_read(&obj_oloc, H5O_NAME_ID, 0, &comment, dxpl_id)) { + if(buf && bufsize > 0) buf[0] = '\0'; ret_value = 0; } else { @@ -3287,14 +2478,57 @@ H5G_get_comment(H5G_entry_t *loc, const char *name, size_t bufsize, char *buf, h HDstrncpy(buf, comment.s, bufsize); ret_value = (int)HDstrlen(comment.s); H5O_reset(H5O_NAME_ID, &comment); - } + } /* end else */ done: - /* Free the ID to name buffer */ - H5G_free_ent_name(&obj_ent); + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_get_comment() */ - FUNC_LEAVE_NOAPI(ret_value); -} + +/*------------------------------------------------------------------------- + * Function: H5G_unlink_cb + * + * Purpose: Callback for unlinking an object. This routine + * deletes the link + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, September 19, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_unlink_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/) +{ + H5G_trav_ud6_t *udata = (H5G_trav_ud6_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_unlink_cb) + + /* Check if the name in this group resolved to a valid link */ + if(obj_loc == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + + /* Check for removing '.' */ + if(lnk == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't delete self") + + /* Remove the link from the group */ + if(H5G_loc_remove(grp_loc, name, obj_loc, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to unlink name from group") + +done: + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_unlink_cb() */ /*------------------------------------------------------------------------- @@ -3307,68 +2541,92 @@ done: * Programmer: Robb Matzke * Thursday, September 17, 1998 * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002 - * Added `id to name' support. - * *------------------------------------------------------------------------- */ static herr_t -H5G_unlink(H5G_entry_t *loc, const char *name, hid_t dxpl_id) +H5G_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id) { - H5G_entry_t grp_ent, obj_ent; - const char *base=NULL; + H5G_trav_ud6_t udata; /* User data for callback */ char *norm_name = NULL; /* Pointer to normalized name */ - H5G_obj_t obj_type; /* Object type */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_unlink); + FUNC_ENTER_NOAPI_NOINIT(H5G_unlink) /* Sanity check */ - assert(loc); - assert(name && *name); + HDassert(loc); + HDassert(name && *name); /* Get normalized copy of the name */ - if((norm_name=H5G_normalize(name))==NULL) - HGOTO_ERROR (H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name"); - - /* Reset the group entries to known values in a portable way */ - H5G_ent_reset(&grp_ent); - H5G_ent_reset(&obj_ent); - - /* Get the entry for the group that contains the object to be unlinked */ - if (H5G_namei(loc, norm_name, NULL, &grp_ent, &obj_ent, - H5G_TARGET_SLINK|H5G_TARGET_MOUNT, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found"); - if (!H5F_addr_defined(grp_ent.header)) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "no containing group specified"); - if (NULL==(base=H5G_basename(norm_name, NULL)) || '/'==*base) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "problems obtaining object base name"); - - /* Get object type before unlink */ - if((obj_type = H5G_get_type(&obj_ent, dxpl_id)) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't determine object type"); - - /* Remove the name from the symbol table */ - if (H5G_stab_remove(&grp_ent, base, dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to unlink name from symbol table"); - - /* Search the open IDs and replace names for unlinked object */ - if (H5G_replace_name(obj_type, &obj_ent, NULL, NULL, NULL, NULL, OP_UNLINK )<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to replace name"); + if((norm_name = H5G_normalize(name)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") -done: - /* Free the ID to name buffers */ - H5G_free_ent_name(&grp_ent); - H5G_free_ent_name(&obj_ent); + /* Set up user data for creating soft link */ + udata.dxpl_id = dxpl_id; + + if(H5G_traverse(loc, norm_name, H5G_TARGET_SLINK|H5G_TARGET_MOUNT, H5G_unlink_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") +done: /* Free the normalized path name */ if(norm_name) H5MM_xfree(norm_name); - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_unlink() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_move_cb + * + * Purpose: Callback for moving an object. This routine replaces the + * names of open objects with the moved object in the path + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, September 19, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_move_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/) +{ + H5G_trav_ud2_t *udata = (H5G_trav_ud2_t *)_udata; /* User data passed in */ + H5RS_str_t *src_name_r = NULL; /* Ref-counted version of src name */ + H5RS_str_t *dst_name_r = NULL; /* Ref-counted version of dest name */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_move_cb) + + /* Check if the name in this group resolved to a valid link */ + if(obj_loc == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + + /* Fix names up */ + src_name_r = H5RS_wrap(udata->src_name); + HDassert(src_name_r); + dst_name_r = H5RS_wrap(udata->dst_name); + HDassert(dst_name_r); + if(H5G_name_replace(udata->type, obj_loc, src_name_r, udata->src_loc, dst_name_r, udata->dst_loc, OP_MOVE) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name ") + +done: + /* Cleanup */ + if(src_name_r) + H5RS_decr(src_name_r); + if(dst_name_r) + H5RS_decr(dst_name_r); + + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_move_cb() */ /*------------------------------------------------------------------------- @@ -3381,87 +2639,102 @@ done: * Programmer: Robb Matzke * Friday, September 25, 1998 * - * Modifications: - * - * Raymond Lu - * Thursday, April 18, 2002 - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002 - * Added `id to name' support. - * *------------------------------------------------------------------------- */ static herr_t -H5G_move(H5G_entry_t *src_loc, const char *src_name, H5G_entry_t *dst_loc, +H5G_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, const char *dst_name, hid_t dxpl_id) { - H5G_stat_t sb; - char *linkval=NULL; - size_t lv_size=32; - H5G_entry_t obj_ent; /* Object entry for object being moved */ - H5RS_str_t *src_name_r; /* Ref-counted version of src name */ - H5RS_str_t *dst_name_r; /* Ref-counted version of dest name */ - herr_t ret_value=SUCCEED; /* Return value */ + H5G_stat_t sb; /* Object info for link to move */ + H5G_trav_ud2_t udata; /* User data for traversal */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5G_move); + FUNC_ENTER_NOAPI_NOINIT(H5G_move) /* Sanity check */ - assert(src_loc); - assert(dst_loc); - assert(src_name && *src_name); - assert(dst_name && *dst_name); - - if (H5G_get_objinfo(src_loc, src_name, FALSE, &sb, dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found"); - if (H5G_LINK==sb.type) { + HDassert(src_loc); + HDassert(dst_loc); + HDassert(src_name && *src_name); + HDassert(dst_name && *dst_name); + + if(H5G_get_objinfo(src_loc, src_name, FALSE, &sb, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") + if(H5G_LINK == sb.type) { + char *linkval = NULL; + /* * When renaming a symbolic link we rename the link but don't change * the value of the link. */ - do { - if (NULL==(linkval=H5MM_realloc(linkval, 2*lv_size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate space for symbolic link value"); - linkval[lv_size-1] = '\0'; - if (H5G_linkval(src_loc, src_name, lv_size, linkval, dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read symbolic link value"); - } while (linkval[lv_size-1]); - if (H5G_link(src_loc, linkval, dst_loc, dst_name, H5G_LINK_SOFT, - H5G_TARGET_NORMAL, dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to rename symbolic link"); + if(NULL == (linkval = H5MM_malloc(sb.u.slink.linklen))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate space for symbolic link value") + if(H5G_linkval(src_loc, src_name, sb.u.slink.linklen, linkval, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read symbolic link value") + if(H5G_link(src_loc, linkval, dst_loc, dst_name, H5G_LINK_SOFT, H5G_TARGET_NORMAL, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to rename symbolic link") H5MM_xfree(linkval); - } else { /* * Rename the object. */ - if (H5G_link(src_loc, src_name, dst_loc, dst_name, H5G_LINK_HARD, - H5G_TARGET_MOUNT, dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object"); - } + if(H5G_link(src_loc, src_name, dst_loc, dst_name, H5G_LINK_HARD, H5G_TARGET_MOUNT, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object") + } /* end else */ + + /* Set up user data for name replacement */ + udata.type = sb.type; + udata.src_name = src_name; + udata.src_loc = src_loc; + udata.dst_name = dst_name; + udata.dst_loc = dst_loc; /* Search the open ID list and replace names for the move operation - * This has to be done here because H5G_link and H5G_unlink have - * internal object entries, and do not modify the entries list - */ - if (H5G_namei(src_loc, src_name, NULL, NULL, &obj_ent, H5G_TARGET_NORMAL|H5G_TARGET_SLINK, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)) - HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link"); - src_name_r=H5RS_wrap(src_name); - assert(src_name_r); - dst_name_r=H5RS_wrap(dst_name); - assert(dst_name_r); - if (H5G_replace_name(sb.type, &obj_ent, src_name_r, src_loc, dst_name_r, dst_loc, OP_MOVE )<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name "); - H5RS_decr(src_name_r); - H5RS_decr(dst_name_r); - H5G_free_ent_name(&obj_ent); + */ + if(H5G_traverse(src_loc, src_name, H5G_TARGET_NORMAL|H5G_TARGET_SLINK, H5G_move_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link") /* Remove the old name */ - if (H5G_unlink(src_loc, src_name, dxpl_id)<0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to deregister old object name"); + if(H5G_unlink(src_loc, src_name, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to deregister old object name") done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_move() */ + + +/*------------------------------------------------------------------------- + * Function: H5G_insertion_file_cb + * + * Purpose: Callback for finding insertion file. This routine sets the + * correct information for the file pointer to return. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, September 19, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/) +{ + H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5G_insertion_file_cb) + + /* Check if the name in this group resolves to a valid location */ + /* (which is not what we want) */ + if(obj_loc != NULL) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name already exists") + + /* Get file pointer for location */ + udata->file = grp_loc->oloc->file; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_insertion_file_cb() */ /*------------------------------------------------------------------------- @@ -3478,65 +2751,43 @@ done: * Programmer: Robb Matzke * Wednesday, October 14, 1998 * - * Modifications: - * - * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002 - * Added `id to name' support. - * *------------------------------------------------------------------------- */ H5F_t * -H5G_insertion_file(H5G_entry_t *loc, const char *name, hid_t dxpl_id) +H5G_insertion_file(H5G_loc_t *loc, const char *name, hid_t dxpl_id) { H5F_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5G_insertion_file, NULL); + FUNC_ENTER_NOAPI(H5G_insertion_file, NULL) - assert(loc); - assert(name && *name); + HDassert(loc); + HDassert(name && *name); /* Check if the location the object will be inserted into is part of a * file mounting chain (either a parent or a child) and perform a more * rigorous determination of the location's file (which traverses into * mounted files, etc.). */ - if(H5F_has_mount(loc->file) || H5F_is_mount(loc->file)) { - const char *rest; - H5G_entry_t grp_ent; - size_t size; + if(H5F_has_mount(loc->oloc->file) || H5F_is_mount(loc->oloc->file)) { + H5G_trav_ud1_t udata; /* User data for traversal */ /* * Look up the name to get the containing group and to make sure the name * doesn't already exist. */ - if (H5G_namei(loc, name, &rest, &grp_ent, NULL, H5G_TARGET_NORMAL, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)>=0) { - H5G_free_ent_name(&grp_ent); - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, NULL, "name already exists"); - } /* end if */ - H5E_clear_stack(NULL); - - /* Make sure only the last component wasn't resolved */ - rest = H5G_component(rest, &size); - assert(*rest && size>0); - rest = H5G_component(rest+size, NULL); - if (*rest) { - H5G_free_ent_name(&grp_ent); - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "insertion point not found"); - } /* end if */ + if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_insertion_file_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, NULL, "name already exists") /* Set return value */ - ret_value=grp_ent.file; - - /* Free the ID to name buffer */ - H5G_free_ent_name(&grp_ent); + ret_value = udata.file; } /* end if */ else /* Use the location's file */ - ret_value=loc->file; + ret_value = loc->oloc->file; done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_insertion_file() */ /*------------------------------------------------------------------------- @@ -3552,630 +2803,25 @@ done: * * Comments: Used now only on the root group close, in H5F_close() * - * Modifications: - * *------------------------------------------------------------------------- */ herr_t H5G_free_grp_name(H5G_t *grp) { - H5G_entry_t *ent; /* Group object's entry */ - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5G_free_grp_name, FAIL); - - /* Check args */ - assert(grp && grp->shared); - assert(grp->shared->fo_count > 0); - - /* Get the entry for the group */ - if (NULL==( ent = H5G_entof(grp))) - HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "cannot get entry"); - - /* Free the entry */ - H5G_free_ent_name(ent); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5G_free_ent_name - * - * Purpose: Free the 'ID to name' buffers. - * - * Return: Success - * - * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu - * - * Date: August 22, 2002 - * - * Comments: - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5G_free_ent_name(H5G_entry_t *ent) -{ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5G_free_ent_name, FAIL); + FUNC_ENTER_NOAPI(H5G_free_grp_name, FAIL) /* Check args */ - assert(ent); - - if(ent->user_path_r) { - H5RS_decr(ent->user_path_r); - ent->user_path_r=NULL; - } /* end if */ - if(ent->canon_path_r) { - H5RS_decr(ent->canon_path_r); - ent->canon_path_r=NULL; - } /* end if */ - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5G_replace_name - * - * Purpose: Search the list of open IDs and replace names according to a - * particular operation. The operation occured on the LOC - * entry, which had SRC_NAME previously. The new name (if there - * is one) is DST_NAME. Additional entry location information - * (currently only needed for the 'move' operation) is passed - * in SRC_LOC and DST_LOC. - * - * Return: Success: 0, Failure: -1 - * - * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu - * - * Date: June 11, 2002 - * - * Comments: - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5G_replace_name(H5G_obj_t type, H5G_entry_t *loc, - H5RS_str_t *src_name, H5G_entry_t *src_loc, - H5RS_str_t *dst_name, H5G_entry_t *dst_loc, H5G_names_op_t op ) -{ - H5G_names_t names; /* Structure to hold operation information for callback */ - unsigned search_group=0; /* Flag to indicate that groups are to be searched */ - unsigned search_dataset=0; /* Flag to indicate that datasets are to be searched */ - unsigned search_datatype=0; /* Flag to indicate that datatypes are to be searched */ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(H5G_replace_name, FAIL); - - /* Set up common information for callback */ - names.src_name=src_name; - names.dst_name=dst_name; - names.loc=loc; - names.src_loc=src_loc; - names.dst_loc=dst_loc; - names.op=op; - - /* Determine which types of IDs need to be operated on */ - switch(type) { - /* Object is a group */ - case H5G_GROUP: - /* Search and replace names through group IDs */ - search_group=1; - break; - - /* Object is a dataset */ - case H5G_DATASET: - /* Search and replace names through dataset IDs */ - search_dataset=1; - break; - - /* Object is a named datatype */ - case H5G_TYPE: - /* Search and replace names through datatype IDs */ - search_datatype=1; - break; - - case H5G_UNKNOWN: /* We pass H5G_UNKNOWN as object type when we need to search all IDs */ - case H5G_LINK: /* Symbolic links might resolve to any object, so we need to search all IDs */ - /* Check if we will need to search groups */ - if(H5I_nmembers(H5I_GROUP)>0) - search_group=1; - - /* Check if we will need to search datasets */ - if(H5I_nmembers(H5I_DATASET)>0) - search_dataset=1; - - /* Check if we will need to search datatypes */ - if(H5I_nmembers(H5I_DATATYPE)>0) - search_datatype=1; - break; - - default: - HGOTO_ERROR (H5E_DATATYPE, H5E_BADTYPE, FAIL, "not valid object type"); - } /* end switch */ - - /* Search through group IDs */ - if(search_group) - H5I_search(H5I_GROUP, H5G_replace_ent, &names); - - /* Search through dataset IDs */ - if(search_dataset) - H5I_search(H5I_DATASET, H5G_replace_ent, &names); - - /* Search through datatype IDs */ - if(search_datatype) - H5I_search(H5I_DATATYPE, H5G_replace_ent, &names); - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5G_common_path - * - * Purpose: Determine if one path is a valid prefix of another path - * - * Return: TRUE for valid prefix, FALSE for not a valid prefix, FAIL - * on error - * - * Programmer: Quincey Koziol, koziol@ncsa.uiuc.edu - * - * Date: September 24, 2002 - * - * Comments: - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static htri_t -H5G_common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r) -{ - const char *fullpath; /* Pointer to actual fullpath string */ - const char *prefix; /* Pointer to actual prefix string */ - size_t nchars1,nchars2; /* Number of characters in components */ - htri_t ret_value=FALSE; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_common_path); - - /* Get component of each name */ - fullpath=H5RS_get_str(fullpath_r); - assert(fullpath); - fullpath=H5G_component(fullpath,&nchars1); - assert(fullpath); - prefix=H5RS_get_str(prefix_r); - assert(prefix); - prefix=H5G_component(prefix,&nchars2); - assert(prefix); - - /* Check if we have a real string for each component */ - while(*fullpath && *prefix) { - /* Check that the components we found are the same length */ - if(nchars1==nchars2) { - /* Check that the two components are equal */ - if(HDstrncmp(fullpath,prefix,nchars1)==0) { - /* Advance the pointers in the names */ - fullpath+=nchars1; - prefix+=nchars2; - - /* Get next component of each name */ - fullpath=H5G_component(fullpath,&nchars1); - assert(fullpath); - prefix=H5G_component(prefix,&nchars2); - assert(prefix); - } /* end if */ - else - HGOTO_DONE(FALSE); - } /* end if */ - else - HGOTO_DONE(FALSE); - } /* end while */ - - /* If we reached the end of the prefix path to check, it must be a valid prefix */ - if(*prefix=='\0') - ret_value=TRUE; - -done: - FUNC_LEAVE_NOAPI(ret_value); -} - - -/*------------------------------------------------------------------------- - * Function: H5G_build_fullpath - * - * Purpose: Build a full path from a prefix & base pair of reference counted - * strings - * - * Return: Pointer to reference counted string on success, NULL on error - * - * Programmer: Quincey Koziol, koziol@ncsa.uiuc.edu - * - * Date: August 19, 2005 - * - * Comments: - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static H5RS_str_t * -H5G_build_fullpath(const H5RS_str_t *prefix_r, const H5RS_str_t *name_r) -{ - const char *prefix; /* Pointer to raw string of prefix */ - const char *name; /* Pointer to raw string of name */ - char *full_path; /* Full user path built */ - size_t path_len; /* Length of the path */ - unsigned need_sep; /* Flag to indicate if separator is needed */ - H5RS_str_t *ret_value; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_build_fullpath) - - /* Get the pointer to the prefix */ - prefix=H5RS_get_str(prefix_r); - - /* Get the length of the prefix */ - path_len=HDstrlen(prefix); - - /* Determine if there is a trailing separator in the name */ - if(prefix[path_len-1]=='/') - need_sep=0; - else - need_sep=1; - - /* Get the pointer to the raw src user path */ - name=H5RS_get_str(name_r); - - /* Add in the length needed for the '/' separator and the relative path */ - path_len+=HDstrlen(name)+need_sep; - - /* Allocate space for the path */ - if(NULL==(full_path = H5FL_BLK_MALLOC(str_buf,path_len+1))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - - /* Build full path */ - HDstrcpy(full_path,prefix); - if(need_sep) - HDstrcat(full_path,"/"); - HDstrcat(full_path,name); - - /* Create reference counted string for path */ - ret_value=H5RS_own(full_path); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_build_fullpath() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_replace_ent - * - * Purpose: H5I_search callback function to replace group entry names - * - * Return: Success: 0, Failure: -1 - * - * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu - * - * Date: June 5, 2002 - * - * Comments: - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -static int -H5G_replace_ent(void *obj_ptr, hid_t obj_id, void *key) -{ - const H5G_names_t *names = (const H5G_names_t *)key; /* Get operation's information */ - H5G_entry_t *ent = NULL; /* Group entry for object that the ID refers to */ - H5F_t *top_ent_file; /* Top file in entry's mounted file chain */ - H5F_t *top_loc_file; /* Top file in location's mounted file chain */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_replace_ent); - - assert(obj_ptr); - - /* Get the symbol table entry */ - switch(H5I_get_type(obj_id)) { - case H5I_GROUP: - ent = H5G_entof((H5G_t*)obj_ptr); - break; - - case H5I_DATASET: - ent = H5D_entof((H5D_t*)obj_ptr); - break; - - case H5I_DATATYPE: - /* Avoid non-named datatypes */ - if(!H5T_is_named((H5T_t*)obj_ptr)) - HGOTO_DONE(SUCCEED); /* Do not exit search over IDs */ - - ent = H5T_entof((H5T_t*)obj_ptr); - break; - - default: - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object"); - } /* end switch */ - assert(ent); - - switch(names->op) { - /*------------------------------------------------------------------------- - * OP_MOUNT - *------------------------------------------------------------------------- - */ - case OP_MOUNT: - if(ent->user_path_r) { - if(ent->file->mtab.parent && H5RS_cmp(ent->user_path_r,ent->canon_path_r)) { - /* Find the "top" file in the chain of mounted files */ - top_ent_file=ent->file->mtab.parent; - while(top_ent_file->mtab.parent!=NULL) - top_ent_file=top_ent_file->mtab.parent; - } /* end if */ - else - top_ent_file=ent->file; - - /* Check for entry being in correct file (or mounted file) */ - if(top_ent_file->shared == names->loc->file->shared) { - /* Check if the source is along the entry's path */ - /* (But not actually the entry itself) */ - if(H5G_common_path(ent->user_path_r,names->src_name) && - H5RS_cmp(ent->user_path_r,names->src_name)!=0) { - /* Hide the user path */ - ent->user_path_hidden++; - } /* end if */ - } /* end if */ - } /* end if */ - break; - - /*------------------------------------------------------------------------- - * OP_UNMOUNT - *------------------------------------------------------------------------- - */ - case OP_UNMOUNT: - if(ent->user_path_r) { - if(ent->file->mtab.parent) { - /* Find the "top" file in the chain of mounted files for the entry */ - top_ent_file=ent->file->mtab.parent; - while(top_ent_file->mtab.parent!=NULL) - top_ent_file=top_ent_file->mtab.parent; - } /* end if */ - else - top_ent_file=ent->file; - - if(names->loc->file->mtab.parent) { - /* Find the "top" file in the chain of mounted files for the location */ - top_loc_file=names->loc->file->mtab.parent; - while(top_loc_file->mtab.parent!=NULL) - top_loc_file=top_loc_file->mtab.parent; - } /* end if */ - else - top_loc_file=names->loc->file; - - /* If the ID's entry is not in the file we operated on, skip it */ - if(top_ent_file->shared == top_loc_file->shared) { - if(ent->user_path_hidden) { - if(H5G_common_path(ent->user_path_r,names->src_name)) { - /* Un-hide the user path */ - ent->user_path_hidden--; - } /* end if */ - } /* end if */ - else { - if(H5G_common_path(ent->user_path_r,names->src_name)) { - /* Free user path */ - H5RS_decr(ent->user_path_r); - ent->user_path_r=NULL; - } /* end if */ - } /* end else */ - } /* end if */ - } /* end if */ - break; - - /*------------------------------------------------------------------------- - * OP_UNLINK - *------------------------------------------------------------------------- - */ - case OP_UNLINK: - /* If the ID's entry is not in the file we operated on, skip it */ - if(ent->file->shared == names->loc->file->shared && - names->loc->canon_path_r && ent->canon_path_r && ent->user_path_r) { - /* Check if we are referring to the same object */ - if(H5F_addr_eq(ent->header, names->loc->header)) { - /* Check if the object was opened with the same canonical path as the one being moved */ - if(H5RS_cmp(ent->canon_path_r,names->loc->canon_path_r)==0) { - /* Free user path */ - H5RS_decr(ent->user_path_r); - ent->user_path_r=NULL; - } /* end if */ - } /* end if */ - else { - /* Check if the location being unlinked is in the canonical path for the current object */ - if(H5G_common_path(ent->canon_path_r,names->loc->canon_path_r)) { - /* Free user path */ - H5RS_decr(ent->user_path_r); - ent->user_path_r=NULL; - } /* end if */ - } /* end else */ - } /* end if */ - break; - - /*------------------------------------------------------------------------- - * OP_MOVE - *------------------------------------------------------------------------- - */ - case OP_MOVE: /* H5Gmove case, check for relative names case */ - /* If the ID's entry is not in the file we operated on, skip it */ - if(ent->file->shared == names->loc->file->shared) { - if(ent->user_path_r && names->loc->user_path_r && - names->src_loc->user_path_r && names->dst_loc->user_path_r) { - H5RS_str_t *src_path_r; /* Full user path of source name */ - H5RS_str_t *dst_path_r; /* Full user path of destination name */ - H5RS_str_t *canon_src_path_r; /* Copy of canonical part of source path */ - H5RS_str_t *canon_dst_path_r; /* Copy of canonical part of destination path */ - - /* Sanity check */ - HDassert(names->src_name); - HDassert(names->dst_name); - - /* Make certain that the source and destination names are full (not relative) paths */ - if(*(H5RS_get_str(names->src_name))!='/') { - /* Create reference counted string for full src path */ - if((src_path_r = H5G_build_fullpath(names->src_loc->user_path_r, names->src_name)) == NULL) - HGOTO_ERROR (H5E_SYM, H5E_PATH, FAIL, "can't build source path name") - } /* end if */ - else - src_path_r=H5RS_dup(names->src_name); - if(*(H5RS_get_str(names->dst_name))!='/') { - /* Create reference counted string for full dst path */ - if((dst_path_r = H5G_build_fullpath(names->dst_loc->user_path_r, names->dst_name)) == NULL) - HGOTO_ERROR (H5E_SYM, H5E_PATH, FAIL, "can't build destination path name") - } /* end if */ - else - dst_path_r=H5RS_dup(names->dst_name); - - /* Get the canonical parts of the source and destination names */ - - /* Check if the object being moved was accessed through a mounted file */ - if(H5RS_cmp(names->loc->user_path_r,names->loc->canon_path_r)!=0) { - size_t non_canon_name_len; /* Length of non-canonical part of name */ - - /* Get current string lengths */ - non_canon_name_len=H5RS_len(names->loc->user_path_r)-H5RS_len(names->loc->canon_path_r); - - canon_src_path_r=H5RS_create(H5RS_get_str(src_path_r)+non_canon_name_len); - canon_dst_path_r=H5RS_create(H5RS_get_str(dst_path_r)+non_canon_name_len); - } /* end if */ - else { - canon_src_path_r=H5RS_dup(src_path_r); - canon_dst_path_r=H5RS_dup(dst_path_r); - } /* end else */ - - /* Check if the link being changed in the file is along the canonical path for this object */ - if(H5G_common_path(ent->canon_path_r,canon_src_path_r)) { - size_t user_dst_len; /* Length of destination user path */ - size_t canon_dst_len; /* Length of destination canonical path */ - const char *old_user_path; /* Pointer to previous user path */ - char *new_user_path; /* Pointer to new user path */ - char *new_canon_path; /* Pointer to new canonical path */ - const char *tail_path; /* Pointer to "tail" of path */ - size_t tail_len; /* Pointer to "tail" of path */ - char *src_canon_prefix; /* Pointer to source canonical path prefix of component which is moving */ - size_t src_canon_prefix_len;/* Length of the source canonical path prefix */ - char *dst_canon_prefix; /* Pointer to destination canonical path prefix of component which is moving */ - size_t dst_canon_prefix_len;/* Length of the destination canonical path prefix */ - char *user_prefix; /* Pointer to user path prefix of component which is moving */ - size_t user_prefix_len; /* Length of the user path prefix */ - char *src_comp; /* The source name of the component which is actually changing */ - char *dst_comp; /* The destination name of the component which is actually changing */ - const char *canon_src_path; /* pointer to canonical part of source path */ - const char *canon_dst_path; /* pointer to canonical part of destination path */ - - /* Get the pointers to the raw strings */ - canon_src_path=H5RS_get_str(canon_src_path_r); - canon_dst_path=H5RS_get_str(canon_dst_path_r); - - /* Get the source & destination components */ - src_comp=HDstrrchr(canon_src_path,'/'); - assert(src_comp); - dst_comp=HDstrrchr(canon_dst_path,'/'); - assert(dst_comp); - - /* Find the canonical prefixes for the entry */ - src_canon_prefix_len=HDstrlen(canon_src_path)-HDstrlen(src_comp); - if(NULL==(src_canon_prefix = H5MM_malloc(src_canon_prefix_len+1))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - HDstrncpy(src_canon_prefix,canon_src_path,src_canon_prefix_len); - src_canon_prefix[src_canon_prefix_len]='\0'; - - dst_canon_prefix_len=HDstrlen(canon_dst_path)-HDstrlen(dst_comp); - if(NULL==(dst_canon_prefix = H5MM_malloc(dst_canon_prefix_len+1))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - HDstrncpy(dst_canon_prefix,canon_dst_path,dst_canon_prefix_len); - dst_canon_prefix[dst_canon_prefix_len]='\0'; - - /* Hold this for later use */ - old_user_path=H5RS_get_str(ent->user_path_r); - - /* Find the user prefix for the entry */ - user_prefix_len=HDstrlen(old_user_path)-H5RS_len(ent->canon_path_r); - if(NULL==(user_prefix = H5MM_malloc(user_prefix_len+1))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - HDstrncpy(user_prefix,old_user_path,user_prefix_len); - user_prefix[user_prefix_len]='\0'; - - /* Set the tail path info */ - tail_path=old_user_path+user_prefix_len+src_canon_prefix_len+HDstrlen(src_comp); - tail_len=HDstrlen(tail_path); - - /* Get the length of the destination paths */ - user_dst_len=user_prefix_len+dst_canon_prefix_len+HDstrlen(dst_comp)+tail_len; - canon_dst_len=dst_canon_prefix_len+HDstrlen(dst_comp)+tail_len; - - /* Allocate space for the new user path */ - if(NULL==(new_user_path = H5FL_BLK_MALLOC(str_buf,user_dst_len+1))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - - /* Allocate space for the new canonical path */ - if(NULL==(new_canon_path = H5FL_BLK_MALLOC(str_buf,canon_dst_len+1))) - HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - - /* Create the new names */ - HDstrcpy(new_user_path,user_prefix); - HDstrcat(new_user_path,dst_canon_prefix); - HDstrcat(new_user_path,dst_comp); - HDstrcat(new_user_path,tail_path); - HDstrcpy(new_canon_path,dst_canon_prefix); - HDstrcat(new_canon_path,dst_comp); - HDstrcat(new_canon_path,tail_path); - - /* Release the old user & canonical paths */ - H5RS_decr(ent->user_path_r); - H5RS_decr(ent->canon_path_r); - - /* Take ownership of the new user & canonical paths */ - ent->user_path_r=H5RS_own(new_user_path); - ent->canon_path_r=H5RS_own(new_canon_path); - - /* Free the extra paths allocated */ - H5MM_xfree(src_canon_prefix); - H5MM_xfree(dst_canon_prefix); - H5MM_xfree(user_prefix); - } /* end if */ - - - /* Free the extra paths allocated */ - H5RS_decr(src_path_r); - H5RS_decr(dst_path_r); - H5RS_decr(canon_src_path_r); - H5RS_decr(canon_dst_path_r); - } /* end if */ - else { - /* Release the old user path */ - if(ent->user_path_r) { - H5RS_decr(ent->user_path_r); - ent->user_path_r = NULL; - } /* end if */ - } /* end else */ - } /* end if */ - break; + HDassert(grp && grp->shared); + HDassert(grp->shared->fo_count > 0); - default: - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid call"); - } /* end switch */ + /* Free the path */ + H5G_name_free(&(grp->path)); done: - FUNC_LEAVE_NOAPI(ret_value); -} + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5G_free_grp_name() */ /*------------------------------------------------------------------------- @@ -4279,44 +2925,49 @@ H5G_unmount(H5G_t *grp) *------------------------------------------------------------------------- */ static herr_t -H5G_copy(H5G_entry_t *ent_src, H5G_entry_t *loc_dst, +H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *name_dst, hid_t plist_id) { H5P_genplist_t *oc_plist; /* Property list created */ hid_t dxpl_id = H5AC_dxpl_id; - H5G_entry_t ent_new; + H5G_name_t new_path; /* Copied object group hier. path */ + H5O_loc_t new_oloc; /* Copied object object location */ + H5G_loc_t new_loc; /* Group location of object copied */ hbool_t entry_inserted = FALSE; /* Flag to indicate that the new entry was inserted into a group */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5G_copy, FAIL); - HDassert(ent_src); - HDassert(ent_src->file); - HDassert(loc_dst); - HDassert(loc_dst->file); + HDassert(src_loc); + HDassert(src_loc->oloc->file); + HDassert(dst_loc); + HDassert(dst_loc->oloc->file); HDassert(name_dst); /* Get the property list */ if(NULL == (oc_plist = H5I_object(plist_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - /* Reset group entry for new object */ - H5G_ent_reset(&ent_new); - ent_new.file = loc_dst->file; + /* Set up copied object location to fill in */ + new_loc.oloc = &new_oloc; + new_loc.path = &new_path; + H5G_loc_reset(&new_loc); + new_oloc.file = dst_loc->oloc->file; /* copy the object from the source file to the destination file */ - if(H5O_copy_header(ent_src, &ent_new, dxpl_id) < 0) + if(H5O_copy_header(src_loc->oloc, &new_oloc, dxpl_id) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") /* Insert the new object in the destination file's group */ - if(H5G_insert(loc_dst, name_dst, &ent_new, dxpl_id, oc_plist) < 0) + if(H5G_insert(dst_loc, name_dst, &new_loc, dxpl_id, oc_plist) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert the name") entry_inserted = TRUE; done: /* Free the ID to name buffers */ if(entry_inserted) - H5G_free_ent_name(&ent_new); + H5G_loc_free(&new_loc); FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_copy() */ + |