summaryrefslogtreecommitdiffstats
path: root/src/H5O.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5O.c')
-rw-r--r--src/H5O.c400
1 files changed, 399 insertions, 1 deletions
diff --git a/src/H5O.c b/src/H5O.c
index e035ed4..878e73a 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -33,6 +33,7 @@
#include "H5Fpkg.h" /* File access */
#include "H5FLprivate.h" /* Free lists */
#include "H5MFprivate.h" /* File memory management */
+#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
@@ -175,6 +176,8 @@ H5FL_EXTERN(H5O_cont_t);
H5FL_DEFINE_STATIC(H5O_addr_map_t);
/* PRIVATE PROTOTYPES */
+static hid_t H5O_open_by_loc(H5G_loc_t *obj_loc, hid_t dxpl_id);
+static H5O_loc_t * H5O_get_oloc(hid_t id);
static herr_t H5O_new(H5F_t *f, hid_t dxpl_id, size_t size_hint,
H5O_loc_t *loc/*out*/, haddr_t header);
static herr_t H5O_reset_real(const H5O_msg_class_t *type, void *native);
@@ -229,6 +232,401 @@ static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data);
/*-------------------------------------------------------------------------
+ * Function: H5Oopen
+ *
+ * Purpose: Opens an object within an HDF5 file.
+ *
+ * This function opens an object in the same way that H5Gopen,
+ * H5Topen, and H5Dopen do. However, H5Oopen doesn't require
+ * the type of object to be known beforehand. This can be
+ * useful in user-defined links, for instance, when only a
+ * path is known.
+ *
+ * The opened object should be closed again with H5Oclose
+ * or H5Gclose, H5Tclose, or H5Dclose.
+ * Return: Success: An open object identifier
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * July 14 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id)
+{
+ H5G_loc_t loc;
+ H5G_loc_t obj_loc; /* Location used to open group */
+ H5G_name_t obj_path; /* Opened object group hier. path */
+ H5O_loc_t obj_oloc; /* Opened object object location */
+ hbool_t ent_found = FALSE; /* Entry at 'name' found */
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER_API(H5Oopen, FAIL)
+ H5TRACE3("i","isi",loc_id,name,lapl_id);
+
+ /* Check args */
+ 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 */
+ obj_loc.oloc = &obj_oloc;
+ obj_loc.path = &obj_path;
+ H5G_loc_reset(&obj_loc);
+
+ /* Find the object's location */
+ if(H5G_loc_find(&loc, name, &obj_loc/*out*/, lapl_id, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
+ ent_found = TRUE;
+
+ if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
+
+done:
+ if(ret_value < 0) {
+ if(ent_found)
+ H5G_name_free(&obj_path);
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oopen_by_addr
+ *
+ * Purpose: Warning! This function is EXTREMELY DANGEROUS!
+ * Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA,
+ * and other VERY BAD THINGS!
+ *
+ * This function opens an object using its address within the
+ * HDF5 file, similar to an HDF5 hard link. The open object
+ * is identical to an object opened with H5Oopen() and should
+ * be closed with H5Oclose() or a type-specific closing
+ * function (such as H5Gclose() ).
+ *
+ * This function is very dangerous if called on an invalid
+ * address. For this reason, H5Oincr_refcount() should be
+ * used to prevent HDF5 from deleting any object that is
+ * referenced by address (e.g. by a user-defined link).
+ * H5Odecr_refcount() should be used when the object is
+ * no longer being referenced by address (e.g. when the UD link
+ * is deleted).
+ *
+ * The address of the HDF5 file on disk has no effect on
+ * H5Oopen_by_addr(), nor does the use of any unusual file
+ * drivers. The "address" is really the offset within the
+ * HDF5 file, and HDF5's file drivers will transparently
+ * map this to an address on disk for the filesystem.
+ *
+ * Return: Success: An open object identifier
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * July 14 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Oopen_by_addr(hid_t loc_id, haddr_t addr)
+{
+ H5G_loc_t loc;
+ H5G_loc_t obj_loc; /* Location used to open group */
+ H5G_name_t obj_path; /* Opened object group hier. path */
+ H5O_loc_t obj_oloc; /* Opened object object location */
+ hbool_t ent_found = FALSE; /* Entry at 'name' found */
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER_API(H5Oopen_by_addr, FAIL)
+ H5TRACE2("i","ia",loc_id,addr);
+
+ /* Check args */
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(addr == 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no address supplied")
+
+ /* Set up opened group location to fill in */
+ obj_loc.oloc = &obj_oloc;
+ obj_loc.path = &obj_path;
+ H5G_loc_reset(&obj_loc);
+ obj_loc.oloc->addr = addr;
+ obj_loc.oloc->file = loc.oloc->file;
+ H5G_name_reset(obj_loc.path);
+
+ if((ret_value = H5O_open_by_loc(&obj_loc, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object")
+
+done:
+ if(ret_value < 0) {
+ if(ent_found)
+ H5G_name_free(&obj_path);
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oclose
+ *
+ * Purpose: Close an open file object.
+ *
+ * This is the companion to H5Oopen. It is used to close any
+ * open object in an HDF5 file (but not IDs are that not file
+ * objects, such as property lists and dataspaces). It has
+ * the same effect as calling H5Gclose, H5Dclose, or H5Tclose.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * July 14 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Oclose(hid_t object_id)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_API(H5Oclose, FAIL)
+ H5TRACE1("e","i",object_id);
+
+ /* Get the type of the object and open it in the correct way */
+ switch(H5I_get_type(object_id))
+ {
+ case(H5I_GROUP):
+ case(H5I_DATATYPE):
+ case(H5I_DATASET):
+ if( H5I_object(object_id) == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object");
+ if (H5I_dec_ref(object_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTRELEASE, FAIL, "unable to close object");
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTRELEASE, FAIL, "not a valid file object ID (dataset, group, or datatype)");
+ break;
+ }
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Oincr_refcount
+ *
+ * Purpose: Warning! This function is EXTREMELY DANGEROUS!
+ * Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA,
+ * and other VERY BAD THINGS!
+ *
+ * This function increments the "hard link" reference count
+ * for an object. It should be used a user-defined link
+ * that references an object by address is deleted. When the
+ * link is deleted, H5Odecr_refcount should be used.
+ *
+ * Return: Success: The object's new refcount
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * July 14 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5Oincr_refcount(hid_t object_id)
+{
+ H5O_loc_t *oloc;
+ int ret_value;
+ FUNC_ENTER_API(H5Oincr_refcount, FAIL)
+ H5TRACE1("Is","i",object_id);
+
+ /* Get the object's oloc so we can adjust its link count */
+ if((oloc = H5O_get_oloc(object_id)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID")
+
+ ret_value = H5O_link(oloc, 1, H5AC_dxpl_id);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Odecr_refcount
+ *
+ * Purpose: Warning! This function is EXTREMELY DANGEROUS!
+ * Improper use can lead to FILE CORRUPTION, INACCESSIBLE DATA,
+ * and other VERY BAD THINGS!
+ *
+ * This function decrements the "hard link" reference count
+ * for an object. It should be used when user-defined links
+ * that reference an object by address are deleted, and only
+ * after H5Oincr_refcount has already been used.
+ *
+ * Return: Success: The object's new refcount
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * July 14 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+int H5Odecr_refcount(hid_t object_id)
+{
+ H5O_loc_t *oloc;
+ int ret_value;
+
+ FUNC_ENTER_API(H5Odecr_refcount, FAIL)
+
+ /* Get the object's oloc so we can adjust its link count */
+ if((oloc = H5O_get_oloc(object_id)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADVALUE, FAIL, "unable to get object location from ID")
+
+ ret_value = H5O_link(oloc, -1, H5AC_dxpl_id);
+
+done:
+ FUNC_LEAVE_API(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_open_by_loc
+ *
+ * Purpose: Opens an object and returns an ID given its group loction.
+ *
+ * This functions simply invokes H5G_open, H5T_open, or
+ * H5D_open depending on the object type.
+ *
+ * Return: Success: Open object identifier
+ * Failure: Negative
+ *
+ * Programmer: James Laird
+ * July 25 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5O_open_by_loc(H5G_loc_t *obj_loc, hid_t dxpl_id)
+{
+ H5G_t *grp = NULL;
+ H5D_t *dset = NULL;
+ H5T_t *type = NULL;
+ hid_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5O_open_by_loc, FAIL)
+
+ HDassert(obj_loc);
+
+ /* Get the type of the object and open it in the correct way */
+ switch(H5O_obj_type(obj_loc->oloc, dxpl_id))
+ {
+ case(H5G_GROUP):
+ /* Open the group */
+ if((grp = H5G_open(obj_loc, 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")
+ break;
+
+ case(H5G_DATASET):
+ /* Open the group */
+ if((dset = H5D_open(obj_loc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open dataset")
+ /* Register an atom for the group */
+ if((ret_value = H5I_register(H5I_DATASET, dset)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataset")
+ break;
+
+ case(H5G_TYPE):
+ /* Open the group */
+ if((type = H5T_open(obj_loc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open datatype")
+ /* Register an atom for the group */
+ if((ret_value = H5I_register(H5I_DATATYPE, type)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype")
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "invalid object type")
+ }
+
+done:
+ if(ret_value < 0) {
+ if(grp != NULL)
+ H5G_close(grp);
+ else if(dset != NULL)
+ H5D_close(dset);
+ else if(type != NULL)
+ H5T_close(type);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_get_oloc
+ *
+ * Purpose: Gets the oloc for an object given its ID.
+ *
+ * Return: Success: Pointer to H5O_loc_t
+ * Failure: NULL
+ *
+ * Programmer: James Laird
+ * July 25 2006
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5O_loc_t *
+H5O_get_oloc(hid_t object_id)
+{
+ H5G_t *grp = NULL;
+ H5D_t *dset = NULL;
+ H5T_t *type = NULL;
+ H5O_loc_t *ret_value;
+
+ FUNC_ENTER_NOAPI(H5O_get_oloc, NULL)
+
+ switch(H5I_get_type(object_id))
+ {
+ case(H5I_GROUP):
+ if((grp = H5I_object(object_id)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "couldn't get group from ID")
+ if((ret_value = H5G_oloc(grp)) == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get object location from group ID")
+ break;
+
+ case(H5I_DATASET):
+ if((dset = H5I_object(object_id)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "couldn't get dataset from ID")
+ if((ret_value = H5D_oloc(dset)) == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get object location from dataset ID")
+ break;
+
+ case(H5I_DATATYPE):
+ if((type = H5I_object(object_id)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, NULL, "couldn't get type from ID")
+ if((ret_value = H5T_oloc(type)) == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get object location from datatype ID")
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, NULL, "invalid object type")
+ }
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_create
*
* Purpose: Creates a new object header. Allocates space for it and
@@ -1604,7 +2002,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_msg_class_t *orig_t
/* Increment any links in message */
if((*new_type)->link && ((*new_type)->link)(f,dxpl_id,(*new_mesg)) < 0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, UFAIL, "unable to adjust shared object link count");
+ HGOTO_ERROR (H5E_OHDR, H5E_LINKCOUNT, UFAIL, "unable to adjust shared object link count");
done:
FUNC_LEAVE_NOAPI(ret_value);