diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5Doh.c | 168 | ||||
-rw-r--r-- | src/H5G.c | 237 | ||||
-rw-r--r-- | src/H5Goh.c | 88 | ||||
-rw-r--r-- | src/H5Gprivate.h | 3 | ||||
-rw-r--r-- | src/H5Gpublic.h | 10 | ||||
-rw-r--r-- | src/H5O.c | 383 | ||||
-rw-r--r-- | src/H5Ocopy.c | 502 | ||||
-rw-r--r-- | src/H5Opkg.h | 10 | ||||
-rw-r--r-- | src/H5Oprivate.h | 5 | ||||
-rw-r--r-- | src/H5Opublic.h | 12 | ||||
-rwxr-xr-x | src/H5Pocpl.c | 26 | ||||
-rw-r--r-- | src/H5Toh.c | 88 | ||||
-rwxr-xr-x | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/Makefile.in | 5 |
14 files changed, 925 insertions, 614 deletions
diff --git a/src/H5Doh.c b/src/H5Doh.c index ff42659..6781e25 100644 --- a/src/H5Doh.c +++ b/src/H5Doh.c @@ -22,8 +22,10 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ +#include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5FLprivate.h" /* Free lists */ +#include "H5Iprivate.h" /* IDs */ #include "H5Opkg.h" /* Object headers */ /****************/ @@ -37,9 +39,11 @@ /********************/ /* Local Prototypes */ /********************/ -static htri_t H5O_dset_isa(H5O_t *loc); static void *H5O_dset_get_copy_file_udata(void); static void H5O_dset_free_copy_file_udata(void *); +static htri_t H5O_dset_isa(H5O_t *loc); +static hid_t H5O_dset_open(H5G_loc_t *obj_loc, hid_t dxpl_id); +static H5O_loc_t *H5O_dset_get_oloc(hid_t obj_id); /*********************/ /* Package Variables */ @@ -59,7 +63,9 @@ const H5O_obj_class_t H5O_OBJ_DATASET[1] = {{ "dataset", /* object name, for debugging */ H5O_dset_get_copy_file_udata, /* get 'copy file' user data */ H5O_dset_free_copy_file_udata, /* free 'copy file' user data */ - H5O_dset_isa /* "isa" message */ + H5O_dset_isa, /* "isa" message */ + H5O_dset_open, /* open an object of this class */ + H5O_dset_get_oloc /* get an object header location for an object */ }}; /* Declare a free list to manage the H5D_copy_file_ud_t struct */ @@ -67,6 +73,79 @@ H5FL_DEFINE(H5D_copy_file_ud_t); /*------------------------------------------------------------------------- + * Function: H5O_dset_get_copy_file_udata + * + * Purpose: Allocates the user data needed for copying a dataset's + * object header from file to file. + * + * Return: Success: Non-NULL pointer to user data + * + * Failure: NULL + * + * Programmer: Quincey Koziol + * Monday, November 21, 2005 + * + *------------------------------------------------------------------------- + */ +static void * +H5O_dset_get_copy_file_udata(void) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_dset_get_copy_file_udata) + + /* Allocate space for the 'copy file' user data for copying datasets */ + if(NULL == (ret_value = H5FL_CALLOC(H5D_copy_file_ud_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_dset_get_copy_file_udata() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_dset_free_copy_file_udata + * + * Purpose: Release the user data needed for copying a dataset's + * object header from file to file. + * + * Return: <none> + * + * Programmer: Quincey Koziol + * Monday, November 21, 2005 + * + * Modifications: Peter Cao + * Tuesday, December 27, 2005 + * Free filter pipeline for copying a dataset + * + *------------------------------------------------------------------------- + */ +static void +H5O_dset_free_copy_file_udata(void *_udata) +{ + H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_dset_free_copy_file_udata) + + /* Sanity check */ + HDassert(udata); + + /* Release copy of dataset's datatype, if it was set */ + if(udata->src_dtype) + H5T_close(udata->src_dtype); + + /* Release copy of dataset's filter pipeline, if it was set */ + if (udata->src_pline) + H5O_free(H5O_PLINE_ID, udata->src_pline); + + /* Release space for 'copy file' user data */ + H5FL_FREE(H5D_copy_file_ud_t, udata); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5O_dset_free_copy_file_udata() */ + + +/*------------------------------------------------------------------------- * Function: H5O_dset_isa * * Purpose: Determines if an object has the requisite messages for being @@ -111,74 +190,75 @@ done: /*------------------------------------------------------------------------- - * Function: H5O_dset_get_copy_file_udata + * Function: H5O_dset_open * - * Purpose: Allocates the user data needed for copying a dataset's - * object header from file to file. + * Purpose: Open a dataset at a particular location * - * Return: Success: Non-NULL pointer to user data - * - * Failure: NULL + * Return: Success: Open object identifier + * Failure: Negative * * Programmer: Quincey Koziol - * Monday, November 21, 2005 + * Monday, November 6, 2006 * *------------------------------------------------------------------------- */ -static void * -H5O_dset_get_copy_file_udata(void) +static hid_t +H5O_dset_open(H5G_loc_t *obj_loc, hid_t dxpl_id) { - void *ret_value; /* Return value */ + H5D_t *dset = NULL; /* Dataset opened */ + hid_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5O_dset_get_copy_file_udata) + FUNC_ENTER_NOAPI_NOINIT(H5O_dset_open) - /* Allocate space for the 'copy file' user data for copying datasets */ - if(NULL == (ret_value = H5FL_CALLOC(H5D_copy_file_ud_t))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + HDassert(obj_loc); + + /* Open the dataset */ + if((dset = H5D_open(obj_loc, dxpl_id)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open dataset") + + /* Register an ID for the dataset */ + if((ret_value = H5I_register(H5I_DATASET, dset)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataset") done: + if(ret_value < 0) + if(dset != NULL) + H5D_close(dset); + FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_dset_get_copy_file_udata() */ +} /* end H5O_dset_open() */ /*------------------------------------------------------------------------- - * Function: H5O_dset_free_copy_file_udata + * Function: H5O_dset_get_oloc * - * Purpose: Release the user data needed for copying a dataset's - * object header from file to file. + * Purpose: Retrieve the object header location for an open object * - * Return: <none> + * Return: Success: Pointer to object header location + * Failure: NULL * * Programmer: Quincey Koziol - * Monday, November 21, 2005 - * - * Modifications: Peter Cao - * Tuesday, December 27, 2005 - * Free filter pipeline for copying a dataset + * Monday, November 6, 2006 * *------------------------------------------------------------------------- */ -static void -H5O_dset_free_copy_file_udata(void *_udata) +static H5O_loc_t * +H5O_dset_get_oloc(hid_t obj_id) { - H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_dset_free_copy_file_udata) + H5D_t *dset; /* Dataset opened */ + H5O_loc_t *ret_value; /* Return value */ - /* Sanity check */ - HDassert(udata); + FUNC_ENTER_NOAPI_NOINIT(H5O_dset_get_oloc) - /* Release copy of dataset's datatype, if it was set */ - if(udata->src_dtype) - H5T_close(udata->src_dtype); + /* Get the dataset */ + if((dset = H5I_object(obj_id)) == NULL) + HGOTO_ERROR(H5E_OHDR, H5E_BADATOM, NULL, "couldn't get object from ID") - /* Release copy of dataset's filter pipeline, if it was set */ - if (udata->src_pline) - H5O_free(H5O_PLINE_ID, udata->src_pline); + /* Get the dataset's object header location */ + if((ret_value = H5D_oloc(dset)) == NULL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to get object location from object") - /* Release space for 'copy file' user data */ - H5FL_FREE(H5D_copy_file_ud_t, udata); - - FUNC_LEAVE_NOAPI_VOID -} /* end H5O_dset_free_copy_file_udata() */ +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_dset_get_oloc() */ @@ -145,8 +145,6 @@ static int H5G_get_comment(H5G_loc_t *loc, const char *name, static herr_t H5G_insertion_loc_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/, H5G_own_loc_t *own_loc/*out*/); -static herr_t H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, - hid_t ocpypl_id, hid_t lcpl_id); /*------------------------------------------------------------------------- @@ -952,175 +950,6 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Gget_create_plist() */ - -/*------------------------------------------------------------------------- - * Function: H5Gcopy - * - * Purpose: Copy an object (group or dataset) to destination location - * within a file or cross files. PLIST_ID is a property list - * which is used to pass user options and properties to the - * copy. The name, dst_name, must not already be taken by some - * other object in the destination group. - * - * H5Gcopy() will fail if the name of the destination object - * exists in the destination group. For example, - * H5Gcopy(fid_src, "/dset", fid_dst, "/dset", ...) - * will fail if "/dset" exists in the destination file - * - * OPTIONS THAT HAVE BEEN IMPLEMENTED. - * H5G_COPY_SHALLOW_HIERARCHY_FLAG - * If this flag is specified, only immediate members of - * the group are copied. Otherwise (default), it will - * recursively copy all objects below the group - * H5G_COPY_EXPAND_SOFT_LINK_FLAG - * If this flag is specified, it will copy the objects - * pointed by the soft links. Otherwise (default), it - * will copy the soft link as they are - * H5G_COPY_WITHOUT_ATTR_FLAG - * If this flag is specified, it will copy object without - * copying attributes. Otherwise (default), it will - * copy object along with all its attributes - * H5G_COPY_EXPAND_REFERENCE_FLAG - * 1) Copy object between two different files: - * When this flag is specified, it will copy objects that - * are pointed by the references and update the values of - * references in the destination file. Otherwise (default) - * the values of references in the destination will set to - * zero - * The current implementation does not handle references - * inside of other datatype structure. For example, if - * a member of compound datatype is reference, H5Gcopy() - * will copy that field as it is. It will not set the - * value to zero as default is used nor copy the object - * pointed by that field the flag is set - * 2) Copy object within the same file: - * This flag does not have any effect to the H5Gcopy(). - * Datasets or attributes of references are copied as they - * are, i.e. values of references of the destination object - * are the same as the values of the source object - * - * OPTIONS THAT MAY APPLY TO COPY IN THE FUTURE. - * H5G_COPY_EXPAND_EXT_LINK_FLAG - * If this flag is specified, it will expand the external links - * into new objects, Otherwise (default), it will keep external - * links as they are (default) - * - * PROPERTIES THAT MAY APPLY TO COPY IN FUTURE - * Change data layout such as chunk size - * Add filter such as data compression. - * Add an attribute to the copied object(s) that say the date/time - * for the copy or other information about the source file. - * - * The intermediate group creation property should be passed in - * using the lcpl instead of the ocpypl. - * - * Usage: H5Gcopy(src_loc_id, src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id) - * hid_t src_loc_id IN: Source file or group identifier. - * const char *src_name IN: Name of the source object to be copied - * hid_t dst_loc_id IN: Destination file or group identifier - * const char *dst_name IN: Name of the destination object - * hid_t ocpypl_id IN: Properties which apply to the copy - * hid_t lcpl_id IN: Properties which apply to the new hard link - * - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Peter Cao - * June 4, 2005 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Gcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, - const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id) -{ - H5G_loc_t loc; /* Source group group location */ - H5G_loc_t src_loc; /* Source object group location */ - H5G_loc_t dst_loc; /* Destination group location */ - - /* for opening the destination object */ - H5G_name_t src_path; /* Opened source object hier. path */ - H5O_loc_t src_oloc; /* Opened source object object location */ - hbool_t loc_found = FALSE; /* Location at 'name' found */ - hbool_t obj_open = FALSE; /* Entry at 'name' found */ - - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Gcopy, FAIL) - H5TRACE6("e","isisii",src_loc_id,src_name,dst_loc_id,dst_name,ocpypl_id, - lcpl_id); - - /* Check arguments */ - if(H5G_loc(src_loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(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 source name specified") - if(!dst_name || !*dst_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified") - - /* check if destination name already exists */ - { - H5G_name_t tmp_path; - H5O_loc_t tmp_oloc; - H5G_loc_t tmp_loc; - - /* Set up group location */ - tmp_loc.oloc = &tmp_oloc; - tmp_loc.path = &tmp_path; - H5G_loc_reset(&tmp_loc); - - /* Check if object already exists in destination */ - if(H5G_loc_find(&dst_loc, dst_name, &tmp_loc, H5P_DEFAULT, H5AC_dxpl_id) >= 0) { - H5G_name_free(&tmp_path); - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "destination object already exists") - } /* end if */ - } - - /* Set up opened group location to fill in */ - src_loc.oloc = &src_oloc; - src_loc.path = &src_path; - H5G_loc_reset(&src_loc); - - /* Find the source object to copy */ - if(H5G_loc_find(&loc, src_name, &src_loc/*out*/, H5P_DEFAULT, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found") - loc_found = TRUE; - - if(H5O_open(&src_oloc) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object") - obj_open = TRUE; - - /* Get correct property lists */ - if(H5P_DEFAULT == lcpl_id) { - if((lcpl_id = H5L_get_default_lcpl()) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to get default lcpl") - } /* end if */ - else - if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list") - - if(H5P_DEFAULT == ocpypl_id) - ocpypl_id = H5P_OBJECT_COPY_DEFAULT; - else - if(TRUE != H5P_isa_class(ocpypl_id, H5P_OBJECT_COPY)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not object copy property list") - - if(H5G_copy(&src_loc, &dst_loc, dst_name, ocpypl_id, lcpl_id) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - -done: - if(loc_found) { - if(H5G_loc_free(&src_loc) < 0) - HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") - } - if (obj_open) - H5O_close(&src_oloc); - - FUNC_LEAVE_API(ret_value) -} /* end H5Gcopy() */ - /* *------------------------------------------------------------------------- *------------------------------------------------------------------------- @@ -1128,6 +957,7 @@ done: *------------------------------------------------------------------------- *------------------------------------------------------------------------- */ + /*------------------------------------------------------------------------- * Function: H5G_init_interface @@ -2315,68 +2145,3 @@ H5G_unmount(H5G_t *grp) FUNC_LEAVE_NOAPI(SUCCEED); } /* end H5G_unmount() */ - -/*------------------------------------------------------------------------- - * Function: H5G_copy - * - * Purpose: Copy an object to destination location - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Peter Cao - * June 4, 2005 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, - hid_t ocpypl_id, hid_t lcpl_id) -{ - H5P_genplist_t *gcpy_plist=NULL; /* Group copy property list created */ - hid_t dxpl_id=H5AC_dxpl_id; - 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 */ - unsigned cpy_option = 0; /* Copy options */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5G_copy, FAIL); - - HDassert(src_loc); - HDassert(src_loc->oloc->file); - HDassert(dst_loc); - HDassert(dst_loc->oloc->file); - HDassert(dst_name); - - /* Get the copy property list */ - if(NULL == (gcpy_plist = H5I_object(ocpypl_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - - /* Retrieve the copy parameters */ - if(H5P_get(gcpy_plist, H5G_CPY_OPTION_NAME, &cpy_option) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object copy flag") - - /* 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(src_loc->oloc, &new_oloc, dxpl_id, cpy_option) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - - /* Insert the new object in the destination file's group */ - if(H5L_link(dst_loc, dst_name, &new_loc, lcpl_id, H5P_DEFAULT, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link") - entry_inserted = TRUE; - -done: - /* Free the ID to name buffers */ - if(entry_inserted) - H5G_loc_free(&new_loc); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_copy() */ - diff --git a/src/H5Goh.c b/src/H5Goh.c index c51a493..d1d25b3 100644 --- a/src/H5Goh.c +++ b/src/H5Goh.c @@ -23,29 +23,37 @@ /***********/ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ #include "H5Opkg.h" /* Object headers */ /****************/ /* Local Macros */ /****************/ + /******************/ /* Local Typedefs */ /******************/ + /********************/ /* Local Prototypes */ /********************/ + static htri_t H5O_group_isa(H5O_t *loc); +static hid_t H5O_group_open(H5G_loc_t *obj_loc, hid_t dxpl_id); +static H5O_loc_t *H5O_group_get_oloc(hid_t obj_id); /*********************/ /* Package Variables */ /*********************/ + /*****************************/ /* Library Private Variables */ /*****************************/ + /*******************/ /* Local Variables */ /*******************/ @@ -56,7 +64,9 @@ const H5O_obj_class_t H5O_OBJ_GROUP[1] = {{ "group", /* object name, for debugging */ NULL, /* get 'copy file' user data */ NULL, /* free 'copy file' user data */ - H5O_group_isa /* "isa" message */ + H5O_group_isa, /* "isa" message */ + H5O_group_open, /* open an object of this class */ + H5O_group_get_oloc /* get an object header location for an object */ }}; @@ -77,7 +87,7 @@ const H5O_obj_class_t H5O_OBJ_GROUP[1] = {{ * *------------------------------------------------------------------------- */ -htri_t +static htri_t H5O_group_isa(struct H5O_t *oh) { htri_t stab_exists; /* Whether the 'stab' message is in the object header */ @@ -100,3 +110,77 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_group_isa() */ + +/*------------------------------------------------------------------------- + * Function: H5O_group_open + * + * Purpose: Open a group at a particular location + * + * Return: Success: Open object identifier + * Failure: Negative + * + * Programmer: Quincey Koziol + * Monday, November 6, 2006 + * + *------------------------------------------------------------------------- + */ +static hid_t +H5O_group_open(H5G_loc_t *obj_loc, hid_t dxpl_id) +{ + H5G_t *grp = NULL; /* Group opened */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_group_open) + + HDassert(obj_loc); + + /* 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 ID for the 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) + H5G_close(grp); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_group_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_group_get_oloc + * + * Purpose: Retrieve the object header location for an open object + * + * Return: Success: Pointer to object header location + * Failure: NULL + * + * Programmer: Quincey Koziol + * Monday, November 6, 2006 + * + *------------------------------------------------------------------------- + */ +static H5O_loc_t * +H5O_group_get_oloc(hid_t obj_id) +{ + H5G_t *grp; /* Group opened */ + H5O_loc_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_group_get_oloc) + + /* Get the group */ + if((grp = H5I_object(obj_id)) == NULL) + HGOTO_ERROR(H5E_OHDR, H5E_BADATOM, NULL, "couldn't get object from ID") + + /* Get the group's object header location */ + if((ret_value = H5G_oloc(grp)) == NULL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to get object location from object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_group_get_oloc() */ + diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index 22013cf..6ca2b68 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -96,9 +96,6 @@ H5G_CRT_GINFO_EST_NUM_ENTRIES, \ H5G_CRT_GINFO_EST_NAME_LEN} -/* ========= Object Copy properties ============ */ -#define H5G_CPY_OPTION_NAME "copy object" /* Copy options */ - /* Type of operation being performed for call to H5G_name_replace() */ typedef enum { diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index 2e18d38..4f0117a 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -44,14 +44,6 @@ #define H5G_NUSERTYPES (H5G_NTYPES-H5G_NLIBTYPES) #define H5G_USERTYPE(X) (8+(X)) /* User defined types */ -/* Flags for object copy (H5Gcopy) */ -#define H5G_COPY_SHALLOW_HIERARCHY_FLAG (0x0001u) /* Copy only immediate members */ -#define H5G_COPY_EXPAND_SOFT_LINK_FLAG (0x0002u) /* Expand soft links into new objects */ -#define H5G_COPY_EXPAND_EXT_LINK_FLAG (0x0004u) /* Expand external links into new objects */ -#define H5G_COPY_EXPAND_REFERENCE_FLAG (0x0008u) /* Copy objects that are pointed by references */ -#define H5G_COPY_WITHOUT_ATTR_FLAG (0x0010u) /* Copy object without copying attributes */ -#define H5G_COPY_ALL (0x001Fu) /* All object copying flags (for internal checking) */ - /* Deprecated macros, for backward compatibility */ #define H5G_LINK_ERROR H5L_TYPE_ERROR #define H5G_LINK_HARD H5L_TYPE_HARD @@ -135,8 +127,6 @@ H5_DLL herr_t H5Gset_comment(hid_t loc_id, const char *name, const char *comment H5_DLL int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf); H5_DLL hid_t H5Gget_create_plist(hid_t group_id); -H5_DLL herr_t H5Gcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, - const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id); /* Functions and variables defined for compatibility with previous versions * of the HDF5 API. @@ -18,7 +18,7 @@ * Aug 5 1997 * Robb Matzke <matzke@llnl.gov> * - * Purpose: Object header virtual functions. + * Purpose: Object header routines. * *------------------------------------------------------------------------- */ @@ -34,13 +34,10 @@ /* Headers */ /***********/ #include "H5private.h" /* Generic Functions */ -#include "H5Dprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Fpkg.h" /* File access */ #include "H5FLprivate.h" /* Free lists */ -#include "H5HGprivate.h" /* Global Heaps */ #include "H5Iprivate.h" /* IDs */ -#include "H5Lprivate.h" /* Links */ #include "H5MFprivate.h" /* File memory management */ #include "H5MMprivate.h" /* Memory management */ #include "H5Opkg.h" /* Object headers */ @@ -110,14 +107,6 @@ typedef struct H5O_typeinfo_t { char *desc; /*description of object type */ } H5O_typeinfo_t; -/* Node in skip list to map addresses from one file to another during object header copy */ -typedef struct H5O_addr_map_t { - haddr_t src_addr; /* Address of object in source file */ - haddr_t dst_addr; /* Address of object in destination file */ - hbool_t is_locked; /* Indicate that the destination object is locked currently */ - hsize_t inc_ref_count; /* Number of deferred increments to reference count */ -} H5O_addr_map_t; - /********************/ /* Package Typedefs */ @@ -178,15 +167,14 @@ static herr_t H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_msg_class_t *typ unsigned * oh_flags_ptr); static herr_t H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, H5AC_protect_t prot, hbool_t internal, H5O_mesg_operator_t op, void *op_data, hid_t dxpl_id); +static const H5O_obj_class_t *H5O_obj_class(H5O_loc_t *loc, hid_t dxpl_id); static H5G_obj_t H5O_obj_type_real(H5O_t *oh); -static const H5O_obj_class_t *H5O_obj_class(H5O_t *oh); +static const H5O_obj_class_t *H5O_obj_class_real(H5O_t *oh); static void * H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src, void *mesg_src, H5F_t *file_dst, hid_t dxpl_id, H5O_copy_t *cpy_info, void *udata); static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5O_copy_t *cpy_info); static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data); -static herr_t H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id, - H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info); /*********************/ /* Package Variables */ @@ -259,7 +247,7 @@ H5FL_EXTERN(time_t); H5FL_EXTERN(H5O_cont_t); /* Declare a free list to manage the H5O_addr_map_t struct */ -H5FL_DEFINE_STATIC(H5O_addr_map_t); +H5FL_EXTERN(H5O_addr_map_t); @@ -430,7 +418,7 @@ H5Oclose(hid_t object_id) FUNC_ENTER_API(H5Oclose, FAIL) H5TRACE1("e","i",object_id); - /* Get the type of the object and open it in the correct way */ + /* Get the type of the object and close it in the correct way */ switch(H5I_get_type(object_id)) { case(H5I_GROUP): @@ -539,9 +527,6 @@ done: * * 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 * @@ -553,62 +538,23 @@ done: 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; + const H5O_obj_class_t *obj_class; /* Class of object for location */ + hid_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5O_open_by_loc, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5O_open_by_loc) 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") + /* Get the object class for this location */ + if(NULL == (obj_class = H5O_obj_class(obj_loc->oloc, dxpl_id))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, FAIL, "unable to determine object class") - /* 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; + /* Call the object's 'open' routine */ + HDassert(obj_class->open); + if((ret_value = obj_class->open(obj_loc, dxpl_id)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object") - 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) } /* end H5O_open_by_loc() */ @@ -629,38 +575,29 @@ done: 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; + H5O_loc_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5O_get_oloc, NULL) + FUNC_ENTER_NOAPI_NOINIT(H5O_get_oloc) 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; + if(NULL == (ret_value = H5O_OBJ_GROUP->get_oloc(object_id))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, 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; + if(NULL == (ret_value = H5O_OBJ_DATASET->get_oloc(object_id))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, 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; + if(NULL == (ret_value = H5O_OBJ_DATATYPE->get_oloc(object_id))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to get object location from datatype ID") + break; default: - HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, NULL, "invalid object type") + HGOTO_ERROR(H5E_OHDR, H5E_BADTYPE, NULL, "invalid object type") } /* end switch */ done: @@ -1083,7 +1020,7 @@ H5O_free_real(const H5O_msg_class_t *type, void *msg_native) if (NULL!=(type->free)) (type->free)(msg_native); else - H5MM_xfree (msg_native); + H5MM_xfree(msg_native); } /* end if */ FUNC_LEAVE_NOAPI(NULL) @@ -4576,8 +4513,8 @@ done: H5G_obj_t H5O_obj_type(H5O_loc_t *loc, hid_t dxpl_id) { - H5O_t *oh = NULL; /* Object header for location */ - H5G_obj_t ret_value = H5G_UNKNOWN; /* Return value */ + H5O_t *oh = NULL; /* Object header for location */ + H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_obj_type, H5G_UNKNOWN) @@ -4602,8 +4539,6 @@ done: * * Purpose: Returns the type of object pointed to by `oh'. * - * Note: Same algorithm as H5O_obj_class() - * * Return: Success: An object type defined in H5Gpublic.h * Failure: H5G_UNKNOWN * @@ -4615,27 +4550,20 @@ done: static H5G_obj_t H5O_obj_type_real(H5O_t *oh) { - size_t i; /* Local index variable */ - H5G_obj_t ret_value = H5G_UNKNOWN; /* Return value */ + const H5O_obj_class_t *obj_class; /* Class of object for header */ + H5G_obj_t ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_obj_type_real) /* Sanity check */ HDassert(oh); - /* Test whether entry qualifies as a particular type of object */ - /* (Note: loop is in reverse order, to test specific objects first) */ - for(i = NELMTS(H5O_obj_class_g); i > 0; --i) { - htri_t isa; /* Is entry a particular type? */ - - if((isa = (H5O_obj_class_g[i - 1]->isa)(oh)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type") - else if(isa) - HGOTO_DONE(H5O_obj_class_g[i - 1]->type) - } /* end for */ + /* Look up class for object header */ + if(NULL == (obj_class = H5O_obj_class_real(oh))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, H5G_UNKNOWN, "unable to determine object type") - if(0 == i) - HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type") + /* Set return value */ + ret_value = obj_class->type; done: FUNC_LEAVE_NOAPI(ret_value) @@ -4645,9 +4573,44 @@ done: /*------------------------------------------------------------------------- * Function: H5O_obj_class * - * Purpose: Returns the class of object pointed to by `oh'. + * Purpose: Returns the class of object pointed to by `loc'. + * + * Return: Success: An object class + * Failure: NULL * - * Note: Same algorithm as H5O_obj_type_real() + * Programmer: Quincey Koziol + * Monday, November 6, 2006 + * + *------------------------------------------------------------------------- + */ +static const H5O_obj_class_t * +H5O_obj_class(H5O_loc_t *loc, hid_t dxpl_id) +{ + H5O_t *oh = NULL; /* Object header for location */ + const H5O_obj_class_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_obj_class) + + /* Load the object header */ + if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header") + + /* Test whether entry qualifies as a particular type of object */ + if(NULL == (ret_value = H5O_obj_class_real(oh))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to determine object type") + +done: + if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) != SUCCEED) + HDONE_ERROR(H5E_OHDR, H5E_PROTECT, NULL, "unable to release object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_obj_class() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_obj_class_real + * + * Purpose: Returns the class of object pointed to by `oh'. * * Return: Success: An object class * Failure: NULL @@ -4658,12 +4621,12 @@ done: *------------------------------------------------------------------------- */ static const H5O_obj_class_t * -H5O_obj_class(H5O_t *oh) +H5O_obj_class_real(H5O_t *oh) { size_t i; /* Local index variable */ const H5O_obj_class_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5O_obj_class) + FUNC_ENTER_NOAPI_NOINIT(H5O_obj_class_real) /* Sanity check */ HDassert(oh); @@ -4684,7 +4647,7 @@ H5O_obj_class(H5O_t *oh) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_obj_class() */ +} /* end H5O_obj_class_real() */ /*------------------------------------------------------------------------- @@ -4922,7 +4885,7 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") /* Get pointer to object class for this object */ - if(NULL == (obj_class = H5O_obj_class(oh_src))) + if(NULL == (obj_class = H5O_obj_class_real(oh_src))) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type") /* Retrieve user data for particular type of object to copy */ @@ -5323,20 +5286,20 @@ H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, /* Convert copy flags into copy struct */ HDmemset(&cpy_info, 0, sizeof(H5O_copy_t)); - if((cpy_option & H5G_COPY_SHALLOW_HIERARCHY_FLAG) > 0) { + if((cpy_option & H5O_COPY_SHALLOW_HIERARCHY_FLAG) > 0) { cpy_info.copy_shallow = TRUE; cpy_info.max_depth = 1; } /* end if */ else cpy_info.max_depth = -1; /* Current default is for full, recursive hier. copy */ cpy_info.curr_depth = 0; - if((cpy_option & H5G_COPY_EXPAND_SOFT_LINK_FLAG) > 0) + if((cpy_option & H5O_COPY_EXPAND_SOFT_LINK_FLAG) > 0) cpy_info.expand_soft_link = TRUE; - if((cpy_option & H5G_COPY_EXPAND_EXT_LINK_FLAG) > 0) + if((cpy_option & H5O_COPY_EXPAND_EXT_LINK_FLAG) > 0) cpy_info.expand_ext_link = TRUE; - if((cpy_option & H5G_COPY_EXPAND_REFERENCE_FLAG) > 0) + if((cpy_option & H5O_COPY_EXPAND_REFERENCE_FLAG) > 0) cpy_info.expand_ref = TRUE; - if((cpy_option & H5G_COPY_WITHOUT_ATTR_FLAG) > 0) + if((cpy_option & H5O_COPY_WITHOUT_ATTR_FLAG) > 0) cpy_info.copy_without_attr = TRUE; /* Create a skip list to keep track of which objects are copied */ @@ -5354,186 +5317,6 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_copy_header() */ - -/*------------------------------------------------------------------------- - * Function: H5O_copy_obj_by_ref - * - * Purpose: Copy the object pointed by _src_ref. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Peter Cao - * Aug 7 2006 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id, H5O_loc_t *dst_oloc, - H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info) -{ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(H5O_copy_obj_by_ref, FAIL) - - HDassert(src_oloc); - HDassert(dst_oloc); - - /* Perform the copy, or look up existing copy */ - if((ret_value = H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, FALSE)) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - - /* Check if a new valid object is copied to the destination */ - if(H5F_addr_defined(dst_oloc->addr) && (ret_value > SUCCEED)) { - char tmp_obj_name[80]; - H5G_name_t new_path; - H5O_loc_t new_oloc; - H5G_loc_t new_loc; - - /* Set up group location for new object */ - new_loc.oloc = &new_oloc; - new_loc.path = &new_path; - H5G_loc_reset(&new_loc); - new_oloc.file = dst_oloc->file; - new_oloc.addr = dst_oloc->addr; - - /* Pick a default name for the new object */ - sprintf(tmp_obj_name, "~obj_pointed_by_%llu", (unsigned long_long)dst_oloc->addr); - - /* Create a link to the newly copied object */ - if(H5L_link(dst_root_loc, tmp_obj_name, &new_loc, H5P_DEFAULT, H5P_DEFAULT, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link") - - H5G_loc_free(&new_loc); - } /* if (H5F_addr_defined(dst_oloc.addr)) */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_copy_obj_by_ref() */ - - -/*------------------------------------------------------------------------- - * Function: H5O_copy_expand_ref - * - * Purpose: Copy the object pointed by _src_ref. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Peter Cao - * Aug 7 2006 - * - *------------------------------------------------------------------------- - */ -herr_t -H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id, - H5F_t *file_dst, void *_dst_ref, size_t ref_count, H5R_type_t ref_type, - H5O_copy_t *cpy_info) -{ - H5O_loc_t dst_oloc; /* Copied object object location */ - H5O_loc_t src_oloc; /* Temporary object location for source object */ - H5G_loc_t dst_root_loc; /* The location of root group of the destination file */ - uint8_t *p; /* Pointer to OID to store */ - size_t i; /* Local index variable */ - herr_t ret_value = SUCCEED; - - FUNC_ENTER_NOAPI(H5O_copy_expand_ref, FAIL) - - /* Sanity checks */ - HDassert(file_src); - HDassert(_src_ref); - HDassert(file_dst); - HDassert(_dst_ref); - HDassert(ref_count); - HDassert(cpy_info); - - /* Initialize object locations */ - H5O_loc_reset(&src_oloc); - H5O_loc_reset(&dst_oloc); - src_oloc.file = file_src; - dst_oloc.file = file_dst; - - /* Set up the root group in the destination file */ - if(NULL == (dst_root_loc.oloc = H5G_oloc(H5G_rootof(file_dst)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group") - if(NULL == (dst_root_loc.path = H5G_nameof(H5G_rootof(file_dst)))) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group") - - /* Copy object references */ - if(H5R_OBJECT == ref_type) { - hobj_ref_t *src_ref = (hobj_ref_t *)_src_ref; - hobj_ref_t *dst_ref = (hobj_ref_t *)_dst_ref; - - /* Making equivalent references in the destination file */ - for(i = 0; i < ref_count; i++) { - /* Set up for the object copy for the reference */ - p = (uint8_t *)(&src_ref[i]); - H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(src_oloc.addr)); - dst_oloc.addr = HADDR_UNDEF; - - /* Attempt to copy object from source to destination file */ - if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - - /* Set the object reference info for the destination file */ - p = (uint8_t *)(&dst_ref[i]); - H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr); - } /* end for */ - } /* end if */ - /* Copy region references */ - else if(H5R_DATASET_REGION == ref_type) { - hdset_reg_ref_t *src_ref = (hdset_reg_ref_t *)_src_ref; - hdset_reg_ref_t *dst_ref = (hdset_reg_ref_t *)_dst_ref; - uint8_t *buf; /* Buffer to store serialized selection in */ - H5HG_t hobjid; /* Heap object ID */ - size_t buf_size; /* Length of object in heap */ - - /* Making equivalent references in the destination file */ - for(i = 0; i < ref_count; i++) { - /* Get the heap ID for the dataset region */ - p = (uint8_t *)(&src_ref[i]); - H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(hobjid.addr)); - INT32DECODE(p, hobjid.idx); - - /* Get the dataset region from the heap (allocate inside routine) */ - if((buf = H5HG_read(src_oloc.file, dxpl_id, &hobjid, NULL, &buf_size)) == NULL) - HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") - - /* Get the object oid for the dataset */ - p = (uint8_t *)buf; - H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(src_oloc.addr)); - dst_oloc.addr = HADDR_UNDEF; - - /* copy the object pointed by the ref to the destination */ - if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) { - H5MM_xfree(buf); - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") - } /* end if */ - - /* Serialize object ID */ - p = (uint8_t *)buf; - H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr); - - /* Save the serialized buffer to the destination */ - if(H5HG_insert(dst_oloc.file, dxpl_id, buf_size, buf, &hobjid) < 0) { - H5MM_xfree(buf); - HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to write dataset region information") - } /* end if */ - - /* Set the dataset region reference info for the destination file */ - p = (uint8_t *)(&dst_ref[i]); - H5F_addr_encode(dst_oloc.file, &p, hobjid.addr); - INT32ENCODE(p, hobjid.idx); - - /* Free the buffer allocated in H5HG_read() */ - H5MM_xfree(buf); - } /* end for */ - } /* end if */ - else - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_copy_expand_ref() */ - #ifdef H5O_DEBUG /*------------------------------------------------------------------------- diff --git a/src/H5Ocopy.c b/src/H5Ocopy.c new file mode 100644 index 0000000..df2ef56 --- /dev/null +++ b/src/H5Ocopy.c @@ -0,0 +1,502 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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: H5Ocopy.c + * Nov 6 2006 + * Quincey Koziol <koziol@hdfgroup.org> + * + * Purpose: Object copying routines. + * + *------------------------------------------------------------------------- + */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5O_PACKAGE /*suppress error about including H5Opkg */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5HGprivate.h" /* Global Heaps */ +#include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ +#include "H5Opkg.h" /* Object headers */ +#include "H5Pprivate.h" /* Property lists */ + +/****************/ +/* Local Macros */ +/****************/ + + +/******************/ +/* Local Typedefs */ +/******************/ + + +/********************/ +/* Package Typedefs */ +/********************/ + + +/********************/ +/* Local Prototypes */ +/********************/ + +static herr_t H5O_copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, + const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id); +static herr_t H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id, + H5O_loc_t *dst_oloc, H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info); + +/*********************/ +/* Package Variables */ +/*********************/ + +/* Declare a free list to manage the H5O_addr_map_t struct */ +H5FL_DEFINE(H5O_addr_map_t); + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/*******************/ +/* Local Variables */ +/*******************/ + + + +/*------------------------------------------------------------------------- + * Function: H5Ocopy + * + * Purpose: Copy an object (group or dataset) to destination location + * within a file or cross files. PLIST_ID is a property list + * which is used to pass user options and properties to the + * copy. The name, dst_name, must not already be taken by some + * other object in the destination group. + * + * H5Ocopy() will fail if the name of the destination object + * exists in the destination group. For example, + * H5Ocopy(fid_src, "/dset", fid_dst, "/dset", ...) + * will fail if "/dset" exists in the destination file + * + * OPTIONS THAT HAVE BEEN IMPLEMENTED. + * H5O_COPY_SHALLOW_HIERARCHY_FLAG + * If this flag is specified, only immediate members of + * the group are copied. Otherwise (default), it will + * recursively copy all objects below the group + * H5O_COPY_EXPAND_SOFT_LINK_FLAG + * If this flag is specified, it will copy the objects + * pointed by the soft links. Otherwise (default), it + * will copy the soft link as they are + * H5O_COPY_WITHOUT_ATTR_FLAG + * If this flag is specified, it will copy object without + * copying attributes. Otherwise (default), it will + * copy object along with all its attributes + * H5O_COPY_EXPAND_REFERENCE_FLAG + * 1) Copy object between two different files: + * When this flag is specified, it will copy objects that + * are pointed by the references and update the values of + * references in the destination file. Otherwise (default) + * the values of references in the destination will set to + * zero + * The current implementation does not handle references + * inside of other datatype structure. For example, if + * a member of compound datatype is reference, H5Ocopy() + * will copy that field as it is. It will not set the + * value to zero as default is used nor copy the object + * pointed by that field the flag is set + * 2) Copy object within the same file: + * This flag does not have any effect to the H5Ocopy(). + * Datasets or attributes of references are copied as they + * are, i.e. values of references of the destination object + * are the same as the values of the source object + * + * OPTIONS THAT MAY APPLY TO COPY IN THE FUTURE. + * H5O_COPY_EXPAND_EXT_LINK_FLAG + * If this flag is specified, it will expand the external links + * into new objects, Otherwise (default), it will keep external + * links as they are (default) + * + * PROPERTIES THAT MAY APPLY TO COPY IN FUTURE + * Change data layout such as chunk size + * Add filter such as data compression. + * Add an attribute to the copied object(s) that say the date/time + * for the copy or other information about the source file. + * + * The intermediate group creation property should be passed in + * using the lcpl instead of the ocpypl. + * + * Usage: H5Ocopy(src_loc_id, src_name, dst_loc_id, dst_name, ocpypl_id, lcpl_id) + * hid_t src_loc_id IN: Source file or group identifier. + * const char *src_name IN: Name of the source object to be copied + * hid_t dst_loc_id IN: Destination file or group identifier + * const char *dst_name IN: Name of the destination object + * hid_t ocpypl_id IN: Properties which apply to the copy + * hid_t lcpl_id IN: Properties which apply to the new hard link + * + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * June 4, 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, + const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id) +{ + H5G_loc_t loc; /* Source group group location */ + H5G_loc_t src_loc; /* Source object group location */ + H5G_loc_t dst_loc; /* Destination group location */ + + /* for opening the destination object */ + H5G_name_t src_path; /* Opened source object hier. path */ + H5O_loc_t src_oloc; /* Opened source object object location */ + hbool_t loc_found = FALSE; /* Location at 'name' found */ + hbool_t obj_open = FALSE; /* Entry at 'name' found */ + + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Ocopy, FAIL) + H5TRACE6("e","isisii",src_loc_id,src_name,dst_loc_id,dst_name,ocpypl_id, + lcpl_id); + + /* Check arguments */ + if(H5G_loc(src_loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(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 source name specified") + if(!dst_name || !*dst_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified") + + /* check if destination name already exists */ + { + H5G_name_t tmp_path; + H5O_loc_t tmp_oloc; + H5G_loc_t tmp_loc; + + /* Set up group location */ + tmp_loc.oloc = &tmp_oloc; + tmp_loc.path = &tmp_path; + H5G_loc_reset(&tmp_loc); + + /* Check if object already exists in destination */ + if(H5G_loc_find(&dst_loc, dst_name, &tmp_loc, H5P_DEFAULT, H5AC_dxpl_id) >= 0) { + H5G_name_free(&tmp_path); + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "destination object already exists") + } /* end if */ + } + + /* Set up opened group location to fill in */ + src_loc.oloc = &src_oloc; + src_loc.path = &src_path; + H5G_loc_reset(&src_loc); + + /* Find the source object to copy */ + if(H5G_loc_find(&loc, src_name, &src_loc/*out*/, H5P_DEFAULT, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found") + loc_found = TRUE; + + /* Open source object's object header */ + if(H5O_open(&src_oloc) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object") + obj_open = TRUE; + + /* Get correct property lists */ + if(H5P_DEFAULT == lcpl_id) { + if((lcpl_id = H5L_get_default_lcpl()) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to get default lcpl") + } /* end if */ + else + if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list") + + /* Get object copy property list */ + if(H5P_DEFAULT == ocpypl_id) + ocpypl_id = H5P_OBJECT_COPY_DEFAULT; + else + if(TRUE != H5P_isa_class(ocpypl_id, H5P_OBJECT_COPY)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not object copy property list") + + /* Do the actual copying of the object */ + if(H5O_copy_obj(&src_loc, &dst_loc, dst_name, ocpypl_id, lcpl_id) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + +done: + if(loc_found) { + if(H5G_loc_free(&src_loc) < 0) + HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location") + } + if(obj_open) + H5O_close(&src_oloc); + + FUNC_LEAVE_API(ret_value) +} /* end H5Ocopy() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_copy_obj + * + * Purpose: Copy an object to destination location + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * June 4, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_copy_obj(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, + hid_t ocpypl_id, hid_t lcpl_id) +{ + H5P_genplist_t *ocpy_plist=NULL; /* Object copy property list created */ + hid_t dxpl_id=H5AC_dxpl_id; + 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 */ + unsigned cpy_option = 0; /* Copy options */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_copy_obj, FAIL) + + HDassert(src_loc); + HDassert(src_loc->oloc->file); + HDassert(dst_loc); + HDassert(dst_loc->oloc->file); + HDassert(dst_name); + + /* Get the copy property list */ + if(NULL == (ocpy_plist = H5I_object(ocpypl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + /* Retrieve the copy parameters */ + if(H5P_get(ocpy_plist, H5O_CPY_OPTION_NAME, &cpy_option) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object copy flag") + + /* 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(src_loc->oloc, &new_oloc, dxpl_id, cpy_option) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + + /* Insert the new object in the destination file's group */ + if(H5L_link(dst_loc, dst_name, &new_loc, lcpl_id, H5P_DEFAULT, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link") + entry_inserted = TRUE; + +done: + /* Free the ID to name buffers */ + if(entry_inserted) + H5G_loc_free(&new_loc); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_copy_obj() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_copy_obj_by_ref + * + * Purpose: Copy the object pointed by _src_ref. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * Aug 7 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_copy_obj_by_ref(H5O_loc_t *src_oloc, hid_t dxpl_id, H5O_loc_t *dst_oloc, + H5G_loc_t *dst_root_loc, H5O_copy_t *cpy_info) +{ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(H5O_copy_obj_by_ref, FAIL) + + HDassert(src_oloc); + HDassert(dst_oloc); + + /* Perform the copy, or look up existing copy */ + if((ret_value = H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, cpy_info, FALSE)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + + /* Check if a new valid object is copied to the destination */ + if(H5F_addr_defined(dst_oloc->addr) && (ret_value > SUCCEED)) { + char tmp_obj_name[80]; + H5G_name_t new_path; + H5O_loc_t new_oloc; + H5G_loc_t new_loc; + + /* Set up group location for new object */ + new_loc.oloc = &new_oloc; + new_loc.path = &new_path; + H5G_loc_reset(&new_loc); + new_oloc.file = dst_oloc->file; + new_oloc.addr = dst_oloc->addr; + + /* Pick a default name for the new object */ + sprintf(tmp_obj_name, "~obj_pointed_by_%llu", (unsigned long_long)dst_oloc->addr); + + /* Create a link to the newly copied object */ + if(H5L_link(dst_root_loc, tmp_obj_name, &new_loc, H5P_DEFAULT, H5P_DEFAULT, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link") + + H5G_loc_free(&new_loc); + } /* if (H5F_addr_defined(dst_oloc.addr)) */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_copy_obj_by_ref() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_copy_expand_ref + * + * Purpose: Copy the object pointed by _src_ref. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * Aug 7 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5O_copy_expand_ref(H5F_t *file_src, void *_src_ref, hid_t dxpl_id, + H5F_t *file_dst, void *_dst_ref, size_t ref_count, H5R_type_t ref_type, + H5O_copy_t *cpy_info) +{ + H5O_loc_t dst_oloc; /* Copied object object location */ + H5O_loc_t src_oloc; /* Temporary object location for source object */ + H5G_loc_t dst_root_loc; /* The location of root group of the destination file */ + uint8_t *p; /* Pointer to OID to store */ + size_t i; /* Local index variable */ + herr_t ret_value = SUCCEED; + + FUNC_ENTER_NOAPI(H5O_copy_expand_ref, FAIL) + + /* Sanity checks */ + HDassert(file_src); + HDassert(_src_ref); + HDassert(file_dst); + HDassert(_dst_ref); + HDassert(ref_count); + HDassert(cpy_info); + + /* Initialize object locations */ + H5O_loc_reset(&src_oloc); + H5O_loc_reset(&dst_oloc); + src_oloc.file = file_src; + dst_oloc.file = file_dst; + + /* Set up the root group in the destination file */ + if(NULL == (dst_root_loc.oloc = H5G_oloc(H5G_rootof(file_dst)))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get object location for root group") + if(NULL == (dst_root_loc.path = H5G_nameof(H5G_rootof(file_dst)))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group") + + /* Copy object references */ + if(H5R_OBJECT == ref_type) { + hobj_ref_t *src_ref = (hobj_ref_t *)_src_ref; + hobj_ref_t *dst_ref = (hobj_ref_t *)_dst_ref; + + /* Making equivalent references in the destination file */ + for(i = 0; i < ref_count; i++) { + /* Set up for the object copy for the reference */ + p = (uint8_t *)(&src_ref[i]); + H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(src_oloc.addr)); + dst_oloc.addr = HADDR_UNDEF; + + /* Attempt to copy object from source to destination file */ + if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + + /* Set the object reference info for the destination file */ + p = (uint8_t *)(&dst_ref[i]); + H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr); + } /* end for */ + } /* end if */ + /* Copy region references */ + else if(H5R_DATASET_REGION == ref_type) { + hdset_reg_ref_t *src_ref = (hdset_reg_ref_t *)_src_ref; + hdset_reg_ref_t *dst_ref = (hdset_reg_ref_t *)_dst_ref; + uint8_t *buf; /* Buffer to store serialized selection in */ + H5HG_t hobjid; /* Heap object ID */ + size_t buf_size; /* Length of object in heap */ + + /* Making equivalent references in the destination file */ + for(i = 0; i < ref_count; i++) { + /* Get the heap ID for the dataset region */ + p = (uint8_t *)(&src_ref[i]); + H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(hobjid.addr)); + INT32DECODE(p, hobjid.idx); + + /* Get the dataset region from the heap (allocate inside routine) */ + if((buf = H5HG_read(src_oloc.file, dxpl_id, &hobjid, NULL, &buf_size)) == NULL) + HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information") + + /* Get the object oid for the dataset */ + p = (uint8_t *)buf; + H5F_addr_decode(src_oloc.file, (const uint8_t **)&p, &(src_oloc.addr)); + dst_oloc.addr = HADDR_UNDEF; + + /* copy the object pointed by the ref to the destination */ + if(H5O_copy_obj_by_ref(&src_oloc, dxpl_id, &dst_oloc, &dst_root_loc, cpy_info) < 0) { + H5MM_xfree(buf); + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object") + } /* end if */ + + /* Serialize object ID */ + p = (uint8_t *)buf; + H5F_addr_encode(dst_oloc.file, &p, dst_oloc.addr); + + /* Save the serialized buffer to the destination */ + if(H5HG_insert(dst_oloc.file, dxpl_id, buf_size, buf, &hobjid) < 0) { + H5MM_xfree(buf); + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "Unable to write dataset region information") + } /* end if */ + + /* Set the dataset region reference info for the destination file */ + p = (uint8_t *)(&dst_ref[i]); + H5F_addr_encode(dst_oloc.file, &p, hobjid.addr); + INT32ENCODE(p, hobjid.idx); + + /* Free the buffer allocated in H5HG_read() */ + H5MM_xfree(buf); + } /* end for */ + } /* end if */ + else + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_copy_expand_ref() */ + diff --git a/src/H5Opkg.h b/src/H5Opkg.h index b2a5dd6..30b55c7 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -205,8 +205,18 @@ typedef struct H5O_obj_class_t { void *(*get_copy_file_udata)(void); /*retrieve user data for 'copy file' operation */ void (*free_copy_file_udata)(void *); /*free user data for 'copy file' operation */ htri_t (*isa)(H5O_t *); /*if a header matches an object class */ + hid_t (*open)(H5G_loc_t *, hid_t ); /*open an object of this class */ + H5O_loc_t *(*get_oloc)(hid_t ); /*get the object header location for an object */ } H5O_obj_class_t; +/* Node in skip list to map addresses from one file to another during object header copy */ +typedef struct H5O_addr_map_t { + haddr_t src_addr; /* Address of object in source file */ + haddr_t dst_addr; /* Address of object in destination file */ + hbool_t is_locked; /* Indicate that the destination object is locked currently */ + hsize_t inc_ref_count; /* Number of deferred increments to reference count */ +} H5O_addr_map_t; + /* H5O inherits cache-like properties from H5AC */ H5_DLLVAR const H5AC_class_t H5AC_OHDR[1]; diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 2912ff1..434e805 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -32,6 +32,7 @@ /* Public headers needed by this file */ #include "H5Dpublic.h" /* Dataset functions */ +#include "H5Lpublic.h" /* Link functions */ #include "H5Spublic.h" /* Dataspace functions */ /* Private headers needed by this file */ @@ -39,7 +40,6 @@ #include "H5SLprivate.h" /* Skip lists */ #include "H5Tprivate.h" /* Datatype functions */ #include "H5Zprivate.h" /* I/O pipeline filters */ -#include "H5Lpublic.h" /* Link functions */ /* Forward references of package typedefs */ typedef struct H5O_msg_class_t H5O_msg_class_t; @@ -60,6 +60,9 @@ typedef struct H5O_t H5O_t; #define H5O_UPDATE_TIME 0x01u #define H5O_UPDATE_DATA_ONLY 0x02u +/* ========= Object Copy properties ============ */ +#define H5O_CPY_OPTION_NAME "copy object" /* Copy options */ + /* The object location information for an object */ typedef struct H5O_loc_t { H5F_t *file; /* File that object header is located within */ diff --git a/src/H5Opublic.h b/src/H5Opublic.h index 9fe00cb..8671299 100644 --- a/src/H5Opublic.h +++ b/src/H5Opublic.h @@ -32,6 +32,14 @@ #include "H5public.h" #include "H5Ipublic.h" +/* Flags for object copy (H5Ocopy) */ +#define H5O_COPY_SHALLOW_HIERARCHY_FLAG (0x0001u) /* Copy only immediate members */ +#define H5O_COPY_EXPAND_SOFT_LINK_FLAG (0x0002u) /* Expand soft links into new objects */ +#define H5O_COPY_EXPAND_EXT_LINK_FLAG (0x0004u) /* Expand external links into new objects */ +#define H5O_COPY_EXPAND_REFERENCE_FLAG (0x0008u) /* Copy objects that are pointed by references */ +#define H5O_COPY_WITHOUT_ATTR_FLAG (0x0010u) /* Copy object without copying attributes */ +#define H5O_COPY_ALL (0x001Fu) /* All object copying flags (for internal checking) */ + typedef struct H5O_stat_t { hsize_t size; /* Total size of object header in file */ hsize_t free; /* Free space within object header */ @@ -45,9 +53,11 @@ extern "C" { H5_DLL hid_t H5Oopen(hid_t loc_id, const char *name, hid_t lapl_id); H5_DLL hid_t H5Oopen_by_addr(hid_t loc_id, haddr_t addr); -H5_DLL herr_t H5Oclose(hid_t object_id); H5_DLL herr_t H5Oincr_refcount(hid_t object_id); H5_DLL herr_t H5Odecr_refcount(hid_t object_id); +H5_DLL herr_t H5Ocopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, + const char *dst_name, hid_t ocpypl_id, hid_t lcpl_id); +H5_DLL herr_t H5Oclose(hid_t object_id); #ifdef __cplusplus } diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c index b080fb1..339dc21 100755 --- a/src/H5Pocpl.c +++ b/src/H5Pocpl.c @@ -44,8 +44,8 @@ /* ========= Object Copy properties ============ */ /* Definitions for copy options */ -#define H5G_CPY_OPTION_SIZE sizeof(unsigned) -#define H5G_CPY_OPTION_DEF 0 +#define H5O_CPY_OPTION_SIZE sizeof(unsigned) +#define H5O_CPY_OPTION_DEF 0 /******************/ @@ -111,13 +111,13 @@ const H5P_libclass_t H5P_CLS_OCPY[1] = {{ herr_t H5P_ocpy_reg_prop(H5P_genclass_t *pclass) { - unsigned ocpy_option = H5G_CPY_OPTION_DEF; /* Default object copy flags */ + unsigned ocpy_option = H5O_CPY_OPTION_DEF; /* Default object copy flags */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5P_ocpy_reg_prop, FAIL) /* Register copy options property */ - if(H5P_register(pclass, H5G_CPY_OPTION_NAME, H5G_CPY_OPTION_SIZE, + if(H5P_register(pclass, H5O_CPY_OPTION_NAME, H5O_CPY_OPTION_SIZE, &ocpy_option, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") @@ -135,11 +135,11 @@ done: * Usage: H5Pset_copy_group(plist_id, cpy_option) * hid_t plist_id; IN: Property list to copy object * unsigned cpy_option; IN: Options to copy object such as - * H5G_COPY_SHALLOW_HIERARCHY_FLAG -- Copy only immediate members - * H5G_COPY_EXPAND_SOFT_LINK_FLAG -- Expand soft links into new objects/ - * H5G_COPY_EXPAND_EXT_LINK_FLAG -- Expand external links into new objects - * H5G_COPY_EXPAND_REFERENCE_FLAG -- Copy objects that are pointed by references - * H5G_COPY_WITHOUT_ATTR_FLAG -- Copy object without copying attributes + * H5O_COPY_SHALLOW_HIERARCHY_FLAG -- Copy only immediate members + * H5O_COPY_EXPAND_SOFT_LINK_FLAG -- Expand soft links into new objects/ + * H5O_COPY_EXPAND_EXT_LINK_FLAG -- Expand external links into new objects + * H5O_COPY_EXPAND_REFERENCE_FLAG -- Copy objects that are pointed by references + * H5O_COPY_WITHOUT_ATTR_FLAG -- Copy object without copying attributes * * Return: Non-negative on success/Negative on failure * @@ -157,7 +157,7 @@ H5Pset_copy_object(hid_t plist_id, unsigned cpy_option) H5TRACE2("e","iIu",plist_id,cpy_option); /* Check parameters */ - if(cpy_option & ~H5G_COPY_ALL) + if(cpy_option & ~H5O_COPY_ALL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unknown option specified") /* Get the plist structure */ @@ -165,7 +165,7 @@ H5Pset_copy_object(hid_t plist_id, unsigned cpy_option) HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") /* Set value */ - if(H5P_set(plist, H5G_CPY_OPTION_NAME, &cpy_option) < 0) + if(H5P_set(plist, H5O_CPY_OPTION_NAME, &cpy_option) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set copy object flag") done: @@ -176,7 +176,7 @@ done: /*------------------------------------------------------------------------- * Function: H5Pget_copy_object * - * Purpose: Returns the cpy_option, which is set for H5Gcopy(hid_t loc_id, + * Purpose: Returns the cpy_option, which is set for H5Ocopy(hid_t loc_id, * const char* name, ... ) for copying objects * * Return: Non-negative on success/Negative on failure @@ -200,7 +200,7 @@ H5Pget_copy_object(hid_t plist_id, unsigned *cpy_option /*out*/) /* Get values */ if(cpy_option) - if(H5P_get(plist, H5G_CPY_OPTION_NAME, cpy_option) < 0) + if(H5P_get(plist, H5O_CPY_OPTION_NAME, cpy_option) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get object copy flag") done: diff --git a/src/H5Toh.c b/src/H5Toh.c index 5e86c30..bfca641 100644 --- a/src/H5Toh.c +++ b/src/H5Toh.c @@ -23,29 +23,39 @@ /***********/ #include "H5private.h" /* Generic Functions */ #include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ #include "H5Opkg.h" /* Object headers */ + /****************/ /* Local Macros */ /****************/ + /******************/ /* Local Typedefs */ /******************/ + /********************/ /* Local Prototypes */ /********************/ + static htri_t H5O_dtype_isa(H5O_t *loc); +static hid_t H5O_dtype_open(H5G_loc_t *obj_loc, hid_t dxpl_id); +static H5O_loc_t *H5O_dtype_get_oloc(hid_t obj_id); + /*********************/ /* Package Variables */ /*********************/ + /*****************************/ /* Library Private Variables */ /*****************************/ + /*******************/ /* Local Variables */ /*******************/ @@ -56,7 +66,9 @@ const H5O_obj_class_t H5O_OBJ_DATATYPE[1] = {{ "named datatype", /* object name, for debugging */ NULL, /* get 'copy file' user data */ NULL, /* free 'copy file' user data */ - H5O_dtype_isa /* "isa" */ + H5O_dtype_isa, /* "isa" */ + H5O_dtype_open, /* open an object of this class */ + H5O_dtype_get_oloc /* get an object header location for an object */ }}; @@ -93,3 +105,77 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_dtype_isa() */ + +/*------------------------------------------------------------------------- + * Function: H5O_dtype_open + * + * Purpose: Open a datatype at a particular location + * + * Return: Success: Open object identifier + * Failure: Negative + * + * Programmer: Quincey Koziol + * Monday, November 6, 2006 + * + *------------------------------------------------------------------------- + */ +static hid_t +H5O_dtype_open(H5G_loc_t *obj_loc, hid_t dxpl_id) +{ + H5T_t *type = NULL; /* Datatype opened */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_dtype_open) + + HDassert(obj_loc); + + /* Open the datatype */ + if((type = H5T_open(obj_loc, dxpl_id)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open datatype") + + /* Register an ID for the datatype */ + if((ret_value = H5I_register(H5I_DATATYPE, type)) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype") + +done: + if(ret_value < 0) + if(type != NULL) + H5T_close(type); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_dtype_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_dtype_get_oloc + * + * Purpose: Retrieve the object header location for an open object + * + * Return: Success: Pointer to object header location + * Failure: NULL + * + * Programmer: Quincey Koziol + * Monday, November 6, 2006 + * + *------------------------------------------------------------------------- + */ +static H5O_loc_t * +H5O_dtype_get_oloc(hid_t obj_id) +{ + H5T_t *type; /* Datatype opened */ + H5O_loc_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_dtype_get_oloc) + + /* Get the datatype */ + if((type = H5I_object(obj_id)) == NULL) + HGOTO_ERROR(H5E_OHDR, H5E_BADATOM, NULL, "couldn't get object from ID") + + /* Get the datatype's object header location */ + if((ret_value = H5T_oloc(type)) == NULL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTGET, NULL, "unable to get object location from object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_dtype_get_oloc() */ + diff --git a/src/Makefile.am b/src/Makefile.am index 364ba6b..fa24970 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -57,7 +57,7 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \ H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \ H5MP.c H5MPtest.c H5L.c H5Lexternal.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \ - H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Oginfo.c H5Olayout.c \ + H5Ocont.c H5Ocopy.c H5Odtype.c H5Oefl.c H5Ofill.c H5Oginfo.c H5Olayout.c \ H5Olinfo.c H5Olink.c H5Omtime.c \ H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c H5Oshared.c H5Ostab.c \ H5P.c H5Pacpl.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 3bb42ad..2110b6d 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -101,7 +101,7 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5HFtiny.lo H5HG.lo H5HGdbg.lo H5HL.lo H5HLdbg.lo H5HP.lo \ H5I.lo H5MF.lo H5MM.lo H5MP.lo H5MPtest.lo H5L.lo \ H5Lexternal.lo H5O.lo H5Oattr.lo H5Obogus.lo H5Ocache.lo \ - H5Ocont.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Oginfo.lo \ + H5Ocont.lo H5Ocopy.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Oginfo.lo \ H5Olayout.lo H5Olinfo.lo H5Olink.lo H5Omtime.lo H5Oname.lo \ H5Onull.lo H5Opline.lo H5Osdspace.lo H5Oshared.lo H5Ostab.lo \ H5P.lo H5Pacpl.lo H5Pdcpl.lo H5Pdxpl.lo H5Pfapl.lo H5Pfcpl.lo \ @@ -408,7 +408,7 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5HFspace.c H5HFstat.c H5HFtest.c H5HFtiny.c \ H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \ H5MP.c H5MPtest.c H5L.c H5Lexternal.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \ - H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Oginfo.c H5Olayout.c \ + H5Ocont.c H5Ocopy.c H5Odtype.c H5Oefl.c H5Ofill.c H5Oginfo.c H5Olayout.c \ H5Olinfo.c H5Olink.c H5Omtime.c \ H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c H5Oshared.c H5Ostab.c \ H5P.c H5Pacpl.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pfmpl.c \ @@ -650,6 +650,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Obogus.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ocache.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ocont.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ocopy.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Odtype.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Oefl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ofill.Plo@am__quote@ |