summaryrefslogtreecommitdiffstats
path: root/src/H5Gloc.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2005-11-15 02:55:39 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2005-11-15 02:55:39 (GMT)
commita1708eb023f2c8f8ac6c2c17bf1e598c8dff956e (patch)
tree34c87a3753b36c4c8d689d58bf456eaf261cd235 /src/H5Gloc.c
parentbea1e576c5ef5500678f7ce913d835341b625e8f (diff)
downloadhdf5-a1708eb023f2c8f8ac6c2c17bf1e598c8dff956e.zip
hdf5-a1708eb023f2c8f8ac6c2c17bf1e598c8dff956e.tar.gz
hdf5-a1708eb023f2c8f8ac6c2c17bf1e598c8dff956e.tar.bz2
[svn-r11712] Purpose:
New feature Description: Check in baseline for compact group revisions, which radically revises the source code for managing groups and object headers. WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! This initiates the "unstable" phase of the 1.7.x branch, leading up to the 1.8.0 release. Please test this code, but do _NOT_ keep files created with it - the format will change again before the release and you will not be able to read your old files!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! WARNING!!!! Solution: There's too many changes to really describe them all, but some of them include: - Stop abusing the H5G_entry_t structure and split it into two separate structures for non-symbol table node use within the library: H5O_loc_t for object locations in a file and H5G_name_t to store the path to an opened object. H5G_entry_t is now only used for storing symbol table entries on disk. - Retire H5G_namei() in favor of a more general mechanism for traversing group paths and issuing callbacks on objects located. This gets us out of the business of hacking H5G_namei() for new features, generally. - Revised H5O* routines to take a H5O_loc_t instead of H5G_entry_t - Lots more... Platforms tested: h5committested and maybe another dozen configurations.... :-)
Diffstat (limited to 'src/H5Gloc.c')
-rw-r--r--src/H5Gloc.c469
1 files changed, 469 insertions, 0 deletions
diff --git a/src/H5Gloc.c b/src/H5Gloc.c
new file mode 100644
index 0000000..e2a293f
--- /dev/null
+++ b/src/H5Gloc.c
@@ -0,0 +1,469 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5Gloc.c
+ * Sep 13 2005
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Functions for working with group "locations"
+ *
+ *-------------------------------------------------------------------------
+ */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+
+/* Packages needed by this file... */
+#include "H5private.h" /* Generic Functions */
+#include "H5Aprivate.h" /* Attributes */
+#include "H5Dprivate.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Gpkg.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+
+/* Private typedefs */
+
+/* User data for looking up an object in a group */
+typedef struct {
+ H5G_loc_t *loc; /* Group location to set */
+} H5G_loc_ud1_t;
+
+/* Private macros */
+
+/* Local variables */
+
+/* PRIVATE PROTOTYPES */
+static herr_t H5G_loc_find_cb(H5G_loc_t *grp_loc, const char *name,
+ const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc
+ *
+ * Purpose: Given an object ID return a location for the object.
+ *
+ * Return: Success: Group pointer.
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc(hid_t loc_id, H5G_loc_t *loc)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc, FAIL)
+
+ switch(H5I_get_type(loc_id)) {
+ case H5I_FILE:
+ {
+ H5F_t *f;
+
+ if(NULL == (f = H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file ID")
+ if(NULL == (loc->oloc = H5G_oloc(H5G_rootof(f))))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry for root group")
+ if(NULL == (loc->path = H5G_nameof(H5G_rootof(f))))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path 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(!H5F_is_mount(f))
+ loc->oloc->file = f;
+ } /* end case */
+ break;
+
+ case H5I_GENPROP_CLS:
+ case H5I_GENPROP_LST:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of property list")
+
+ case H5I_ERROR_CLASS:
+ case H5I_ERROR_MSG:
+ case H5I_ERROR_STACK:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of error class, message or stack")
+
+ case H5I_GROUP:
+ {
+ H5G_t *group;
+
+ if(NULL == (group = H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid group ID")
+ if(NULL == (loc->oloc = H5G_oloc(group)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of group")
+ if(NULL == (loc->path = H5G_nameof(group)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of group")
+ } /* end case */
+ break;
+
+ case H5I_DATATYPE:
+ {
+ H5T_t *dt;
+
+ if(NULL == (dt = H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid type ID")
+ if(NULL == (loc->oloc = H5T_oloc(dt)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of datatype")
+ if(NULL == (loc->path = H5T_nameof(dt)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of datatype")
+ } /* end case */
+ break;
+
+ case H5I_DATASPACE:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of dataspace")
+
+ case H5I_DATASET:
+ {
+ H5D_t *dset;
+
+ if(NULL == (dset = H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid data ID")
+ if(NULL == (loc->oloc = H5D_oloc(dset)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of dataset")
+ if(NULL == (loc->path = H5D_nameof(dset)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of dataset")
+ } /* end case */
+ break;
+
+ case H5I_ATTR:
+ {
+ H5A_t *attr;
+
+ if(NULL == (attr = H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid attribute ID")
+ if(NULL == (loc->oloc = H5A_oloc(attr)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of attribute")
+ if(NULL == (loc->path = H5A_nameof(attr)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of attribute")
+ } /* end case */
+ break;
+
+ case H5I_REFERENCE:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of reference")
+
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object ID")
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_copy
+ *
+ * Purpose: Copy over information for a location
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_copy(H5G_loc_t *dst, H5G_loc_t *src, H5G_copy_depth_t depth)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_copy, FAIL)
+
+ /* Check args. */
+ HDassert(dst);
+ HDassert(src);
+
+ /* Copy components of the location */
+ if(H5O_loc_copy(dst->oloc, src->oloc, (depth == H5G_COPY_SHALLOW ? H5O_COPY_SHALLOW : H5O_COPY_DEEP)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
+ if(H5G_name_copy(dst->path, src->path, depth) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to copy path")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_reset
+ *
+ * Purpose: Reset information for a location
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_reset(H5G_loc_t *loc)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_reset, FAIL)
+
+ /* Check args. */
+ HDassert(loc);
+
+ /* Reset components of the location */
+ if(H5O_loc_reset(loc->oloc) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to reset entry")
+ if(H5G_name_reset(loc->path) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to reset path")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_reset() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_free
+ *
+ * Purpose: Free information for a location
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_free(H5G_loc_t *loc)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_free, FAIL)
+
+ /* Check args. */
+ HDassert(loc);
+
+ /* Reset components of the location */
+#ifdef NOT_YET
+ if(H5G_ent_free(loc->ent) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to free entry")
+#endif /* NOT_YET */
+ if(H5G_name_free(loc->path) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to free path")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_find_cb
+ *
+ * Purpose: Callback for retrieving object location for an object in a group
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, October 17, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_loc_find_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_loc_ud1_t *udata = (H5G_loc_ud1_t *)_udata; /* User data passed in */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_loc_find_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")
+
+ /* Take ownership of the object's group location */
+ /* (Group traversal callbacks are responsible for either taking ownership
+ * of the group location for the object, or freeing it. - QAK)
+ */
+ H5G_loc_copy(udata->loc, obj_loc, H5O_COPY_SHALLOW);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_find_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_find
+ *
+ * Purpose: Find a symbol from a location
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_find(H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc/*out*/,
+ hid_t dxpl_id)
+{
+ H5G_loc_ud1_t udata; /* User data for traversal callback */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_find, FAIL)
+
+ /* Check args. */
+ HDassert(loc);
+ HDassert(name && *name);
+ HDassert(obj_loc);
+
+ /* Set up user data for locating object */
+ udata.loc = obj_loc;
+
+ /* Traverse group hierarchy to locate object */
+ if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_find_cb, &udata, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_find() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_insert
+ *
+ * Purpose: Insert an object at a location
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_insert(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc,
+ hbool_t inc_link, hid_t dxpl_id)
+{
+ H5O_link_t lnk; /* Link for object to insert */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_insert, FAIL)
+
+ /* Check args. */
+ HDassert(grp_loc);
+ HDassert(name && *name);
+ HDassert(obj_loc);
+
+ /* "Translate" object location into link object */
+ lnk.type = H5G_LINK_HARD;
+#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 */
+ /* Casting away const OK -QAK */
+ lnk.name = (char *)name;
+ lnk.u.hard.addr = obj_loc->oloc->addr;
+
+ /* Insert new group into current group's symbol table */
+ if(H5G_obj_insert(grp_loc->oloc, name, &lnk, inc_link, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert object")
+
+ /* Set the name of the object location */
+ if(H5G_name_set(grp_loc->path, obj_loc->path, name) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot set name")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_insert() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_exists
+ *
+ * Purpose: Check if a symbol exists in a location
+ *
+ * Return: Non-negative if object exists/Negative if object doesn't exist
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_exists(const H5G_loc_t *loc, const char *name, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_exists, FAIL)
+
+ /* Check args. */
+ HDassert(loc);
+ HDassert(name && *name);
+
+ /* Get information for object in current group */
+ if(H5G_obj_lookup(loc->oloc, name, NULL, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_exists() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_remove
+ *
+ * Purpose: Remove a link from a group
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_remove(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc, hid_t dxpl_id)
+{
+ H5G_obj_t obj_type; /* Type of object removed */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_remove, FAIL)
+
+ /* Check args. */
+ HDassert(grp_loc);
+ HDassert(name && *name);
+
+ /* Remove object from group */
+ if(H5G_obj_remove(grp_loc->oloc, name, &obj_type, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found")
+
+ /* Search the open IDs and replace names for unlinked object */
+ if(H5G_name_replace(obj_type, obj_loc, NULL, NULL, NULL, NULL, OP_UNLINK) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to replace name")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_remove() */
+