summaryrefslogtreecommitdiffstats
path: root/src/H5Lexternal.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2010-07-28 12:33:13 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2010-07-28 12:33:13 (GMT)
commit73ee20aeb7724483d3e95fbcd81ab1589f481572 (patch)
tree04664ea9aac0bfa453053b06049c59714135d40e /src/H5Lexternal.c
parentf99e0b9f75df7b9964c650b0ac0a0378dbb1a209 (diff)
downloadhdf5-73ee20aeb7724483d3e95fbcd81ab1589f481572.zip
hdf5-73ee20aeb7724483d3e95fbcd81ab1589f481572.tar.gz
hdf5-73ee20aeb7724483d3e95fbcd81ab1589f481572.tar.bz2
[svn-r19134] Description:
Bring r19133 from trunk to 1.8 branch: Correct traversal of user-defined links (including external links) to retain path information of object, allowing H5Iget_name() queries to work quickly (without searching entire destination file). This required some refactoring and addition of a mechanism to detect if a "fast" query was performed (for the tests). Minor code cleanups, etc. Tested on: FreeBSD/32 6.3 (duty) in debug mode FreeBSD/64 6.3 (liberty) w/C++ & FORTRAN, in debug mode (h5committest performed on trunk)
Diffstat (limited to 'src/H5Lexternal.c')
-rw-r--r--src/H5Lexternal.c52
1 files changed, 25 insertions, 27 deletions
diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c
index c5ae92f..d98a843 100644
--- a/src/H5Lexternal.c
+++ b/src/H5Lexternal.c
@@ -53,6 +53,9 @@ const H5L_class_t H5L_EXTERN_LINK_CLASS[1] = {{
/* Valid flags for external links */
#define H5L_EXT_FLAGS_ALL 0
+/* Size of local link name buffer for traversing external links */
+#define H5L_EXT_TRAVERSE_BUF_SIZE 256
+
/*--------------------------------------------------------------------------
NAME
@@ -205,7 +208,8 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group,
H5L_elink_cb_t cb_info; /* Callback info struct */
hid_t fapl_id = -1; /* File access property list for external link's file */
hid_t ext_obj = -1; /* ID for external link's object */
- char *temp_group_name = NULL;/* Temporary pointer to group name */
+ char *parent_group_name = NULL;/* Temporary pointer to group name */
+ char local_group_name[H5L_EXT_TRAVERSE_BUF_SIZE]; /* Local buffer to hold group name */
char *temp_file_name = NULL; /* Temporary pointer to file name */
char *actual_file_name = NULL; /* Parent file's actual name */
H5P_genplist_t *fa_plist; /* File access property list pointer */
@@ -264,41 +268,34 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group,
/* Make callback if it exists */
if(cb_info.func) {
const char *parent_file_name; /* Parent file name */
- const char *parent_group_name; /* Parent group name */
+ ssize_t group_name_len; /* Length of parent group name */
/* Get parent file name */
parent_file_name = H5F_OPEN_NAME(loc.oloc->file);
+ /* Query length of parent group name */
+ if((group_name_len = H5G_get_name(&loc, NULL, (size_t) 0, NULL, lapl_id, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve length of group name")
+
+ /* Account for null terminator */
+ group_name_len++;
+
+ /* Check if we need to allocate larger buffer */
+ if((size_t)group_name_len > sizeof(local_group_name)) {
+ if(NULL == (parent_group_name = (char *)H5MM_malloc((size_t)group_name_len)))
+ HGOTO_ERROR(H5E_LINK, H5E_CANTALLOC, FAIL, "can't allocate buffer to hold group name, group_name_len = %Zu", group_name_len)
+ } /* end if */
+ else
+ parent_group_name = local_group_name;
+
/* Get parent group name */
- if(loc.path->user_path_r != NULL && loc.path->obj_hidden == 0)
- /* Use user_path_r if possible */
- parent_group_name = H5RS_get_str(loc.path->user_path_r);
- else {
- /* Otherwise use H5G_get_name */
- ssize_t group_name_len; /* Length of parent group name */
-
- /* Get length of parent group name */
- if((group_name_len = H5G_get_name(cur_group, NULL, (size_t) 0, lapl_id, H5AC_ind_dxpl_id)) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve length of group name")
-
- /* account for null terminator */
- group_name_len++;
-
- /* Copy parent group name */
- if(NULL == (temp_group_name = (char *)H5MM_malloc((size_t)group_name_len)))
- HGOTO_ERROR(H5E_LINK, H5E_NOSPACE, FAIL, "memory allocation failed")
- if(H5G_get_name(cur_group, temp_group_name, (size_t) group_name_len, lapl_id, H5AC_ind_dxpl_id) < 0)
- HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve group name")
- parent_group_name = temp_group_name;
- } /* end else */
+ if(H5G_get_name(&loc, parent_group_name, (size_t) group_name_len, NULL, lapl_id, H5AC_ind_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "unable to retrieve group name")
/* Make callback */
if((cb_info.func)(parent_file_name, parent_group_name, file_name, obj_name, &intent, fapl_id, cb_info.user_data) < 0)
HGOTO_ERROR(H5E_LINK, H5E_CALLBACK, FAIL, "traversal operator failed")
- /* Free temp_group_name */
- temp_group_name = (char *)H5MM_xfree(temp_group_name);
-
/* Check access flags */
if((intent & H5F_ACC_TRUNC) || (intent & H5F_ACC_EXCL))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags")
@@ -460,8 +457,9 @@ done:
HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list")
if(ext_file && H5F_try_close(ext_file) < 0)
HDONE_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, FAIL, "problem closing external file")
+ if(parent_group_name && parent_group_name != local_group_name)
+ parent_group_name = (char *)H5MM_xfree(parent_group_name);
full_name = (char *)H5MM_xfree(full_name);
- temp_group_name = (char *)H5MM_xfree(temp_group_name);
temp_file_name = (char *)H5MM_xfree(temp_file_name);
actual_file_name = (char *)H5MM_xfree(actual_file_name);