diff options
author | James Laird <jlaird@hdfgroup.org> | 2006-07-05 19:01:50 (GMT) |
---|---|---|
committer | James Laird <jlaird@hdfgroup.org> | 2006-07-05 19:01:50 (GMT) |
commit | 801ca2f9cb803b368b36a6c280684c1f6624f169 (patch) | |
tree | ed2543e9bc1f2beb9857f442fc8b52b3c371299f /src | |
parent | d582c7bc8ac8679911e4787f5f92cc37b1c9989c (diff) | |
download | hdf5-801ca2f9cb803b368b36a6c280684c1f6624f169.zip hdf5-801ca2f9cb803b368b36a6c280684c1f6624f169.tar.gz hdf5-801ca2f9cb803b368b36a6c280684c1f6624f169.tar.bz2 |
[svn-r12452] Purpose:
Feature
Description:
Revised Link APIs.
Solution:
New link APIs use H5L*
H5*create_expand do not create links to the objects created; this must
be done manually with H5Llink.
Added APIs to link an object given its ID (H5Llink), to copy links (H5Lcopy),
and changed creation APIs (H5Lcreate_hard and H5Lcreate_soft) and query
API (H5Lget_linkinfo instead of H5Gget_objinfo).
All old APIs are still supported in H5Gdeprec.c .
Platforms tested:
sol, mir, copper
Misc. update:
Forgot to update MANIFEST and release docs. Will do after checkin.
Diffstat (limited to 'src')
43 files changed, 2556 insertions, 1346 deletions
@@ -1872,16 +1872,16 @@ H5_trace (const double *returning, const char *func, const char *type, ...) fprintf(out, "NULL"); } } else { - H5G_link_t link_type = va_arg (ap, H5G_link_t); /*lint !e64 Type mismatch not really occuring */ + H5L_link_t link_type = va_arg (ap, H5L_link_t); /*lint !e64 Type mismatch not really occuring */ switch (link_type) { - case H5G_LINK_ERROR: - fprintf (out, "H5G_LINK_ERROR"); + case H5L_LINK_ERROR: + fprintf (out, "H5L_LINK_ERROR"); break; - case H5G_LINK_HARD: - fprintf (out, "H5G_LINK_HARD"); + case H5L_LINK_HARD: + fprintf (out, "H5L_LINK_HARD"); break; - case H5G_LINK_SOFT: - fprintf (out, "H5G_LINK_SOFT"); + case H5L_LINK_SOFT: + fprintf (out, "H5L_LINK_SOFT"); break; default: fprintf (out, "%ld", (long)link_type); @@ -1904,7 +1904,7 @@ H5_trace (const double *returning, const char *func, const char *type, ...) fprintf (out, "H5G_UNKNOWN"); break; case H5G_LINK: - fprintf (out, "H5G_LINK"); + fprintf (out, "H5L_LINK"); break; case H5G_GROUP: fprintf (out, "H5G_GROUP"); @@ -72,8 +72,6 @@ static herr_t H5A_init_interface(void) { H5P_genclass_t *crt_pclass; - size_t nprops; /* Number of properties */ - H5T_cset_t default_cset = H5A_CHAR_ENCODING_DEF; herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5A_init_interface) @@ -92,17 +90,6 @@ H5A_init_interface(void) if (NULL == (crt_pclass = H5I_object(H5P_CLS_ATTRIBUTE_CREATE_g))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") - /* Get the number of properties in the class */ - if(H5P_get_nprops_pclass(crt_pclass,&nprops,FALSE)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't query number of properties") - - /* Assume that if there are properties in the class, they are the default ones */ - if(nprops==0) { - /* Register the size of the character encoding field */ - if(H5P_register(crt_pclass,H5A_CHAR_ENCODING_NAME,H5A_CHAR_ENCODING_SIZE,&default_cset,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - } - /* Only register the default property list if it hasn't been created yet */ if(H5P_LST_ATTRIBUTE_CREATE_g==(-1)) { /* Register the default attribute creation property list */ @@ -282,7 +269,7 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, /* If the creation property list is H5P_DEFAULT, use the default character encoding */ if(acpl_id == H5P_DEFAULT) { - attr->encoding = H5A_CHAR_ENCODING_DEF; + attr->encoding = H5P_CHAR_ENCODING_DEF; } else { @@ -290,7 +277,7 @@ H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type, if (NULL == (ac_plist = H5I_object(acpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - if(H5P_get(ac_plist, H5A_CHAR_ENCODING_NAME, &(attr->encoding)) < 0) + if(H5P_get(ac_plist, H5P_CHAR_ENCODING_NAME, &(attr->encoding)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get character encoding flag") } @@ -1069,7 +1056,7 @@ H5Aget_create_plist(hid_t attr_id) HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list") /* Set the character encoding on the new property list */ - if(H5P_set(new_plist, H5A_CHAR_ENCODING_NAME, &(attr->encoding)) < 0) + if(H5P_set(new_plist, H5P_CHAR_ENCODING_NAME, &(attr->encoding)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding") ret_value = new_plist_id; diff --git a/src/H5Aprivate.h b/src/H5Aprivate.h index 7adbbe1..9b24490 100644 --- a/src/H5Aprivate.h +++ b/src/H5Aprivate.h @@ -27,11 +27,6 @@ /* Forward references of package typedefs */ typedef struct H5A_t H5A_t; -/* Attribute creation properties */ -#define H5A_CHAR_ENCODING_NAME "character_encoding" -#define H5A_CHAR_ENCODING_SIZE sizeof(H5T_cset_t) -#define H5A_CHAR_ENCODING_DEF H5F_CRT_DEFAULT_CSET - /* Library private functions in package */ H5_DLL struct H5O_loc_t *H5A_oloc(H5A_t *attr); H5_DLL H5G_name_t *H5A_nameof(H5A_t *attr); @@ -32,6 +32,7 @@ #include "H5FOprivate.h" /* File objects */ #include "H5HLprivate.h" /* Local heaps */ #include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ #include "H5Sprivate.h" /* Dataspaces */ #include "H5Vprivate.h" /* Vectors and arrays */ @@ -62,7 +63,7 @@ typedef struct { /* General stuff */ static herr_t H5D_init_storage(H5D_t *dataset, hbool_t full_overwrite, hid_t dxpl_id); static H5D_shared_t * H5D_new(hid_t dcpl_id, hbool_t creating, hbool_t vl_type); -static H5D_t * H5D_create(H5G_loc_t *loc, const char *name, hid_t type_id, +static H5D_t * H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, hid_t dxpl_id); static herr_t H5D_open_oid(H5D_t *dataset, hid_t dxpl_id); static herr_t H5D_get_space_status(H5D_t *dset, H5D_space_status_t *allocation, hid_t dxpl_id); @@ -1174,9 +1175,12 @@ H5Dcreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, hid_t dcpl_id) { H5G_loc_t loc; /* Object location to insert dataset into */ + H5G_loc_t dset_loc; /* Object location of the dataset */ + H5F_t* file; /* File in which dataset is being created */ H5D_t *new_dset = NULL; /* New dataset's info */ const H5S_t *space; /* Dataspace for dataset */ - hid_t ret_value; /* Return value */ + hid_t dset_id = -1; /* New dataset's id */ + hid_t ret_value; /* Return value */ FUNC_ENTER_API(H5Dcreate, FAIL) H5TRACE5("i","isiii",loc_id,name,type_id,space_id,dcpl_id); @@ -1196,8 +1200,108 @@ H5Dcreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id, if(TRUE != H5P_isa_class(dcpl_id, H5P_DATASET_CREATE)) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list ID") + /* What file is the dataset being added to? */ + if(NULL == (file = H5G_insertion_file(&loc, name, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to locate insertion point") + /* build and open the new dataset */ - if(NULL == (new_dset = H5D_create(&loc, name, type_id, space, dcpl_id, H5AC_dxpl_id))) + if(NULL == (new_dset = H5D_create(file, type_id, space, dcpl_id, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") + + /* Register the new dataset to get an ID for it */ + if((dset_id = H5I_register(H5I_DATASET, new_dset)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset") + + if(H5G_loc(dset_id, &dset_loc) <0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to get location for dataset") + + /* Link the new dataset */ + if( H5L_link(&loc, name, &dset_loc, H5AC_dxpl_id, H5P_DEFAULT) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to create link to dataset") + + ret_value = dset_id; + +done: + if(ret_value < 0) { + if(dset_id >= 0) + { + H5I_dec_ref(dset_id); + } + else + { + if(new_dset != NULL) { + if(H5D_close(new_dset) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset") + } /* end if */ + } /* end if-else */ + } /* end if */ + + FUNC_LEAVE_API(ret_value) +} /* end H5Dcreate() */ + + +/*------------------------------------------------------------------------- + * Function: H5Dcreate_expand + * + * Purpose: Creates a new dataset named NAME at LOC_ID, opens the + * dataset for access, and associates with that dataset constant + * and initial persistent properties including the type of each + * datapoint as stored in the file (TYPE_ID), the size of the + * dataset (SPACE_ID), and other initial miscellaneous + * properties (DCPL_ID). + * + * All arguments are copied into the dataset, so the caller is + * allowed to derive new types, data spaces, and creation + * parameters from the old ones and reuse them in calls to + * create other datasets. + * + * The resulting ID should be linked into the file with + * H5Lcreate or it will be deleted when closed. + * + * Return: Success: The object ID of the new dataset. At this + * point, the dataset is ready to receive its + * raw data. Attempting to read raw data from + * the dataset will probably return the fill + * value. The dataset should be linked into + * the group hierarchy before being closed or + * it will be deleted. The dataset should be + * closed when the caller is no longer interested + * in it. + * + * Failure: FAIL + * + * Programmer: James Laird + * Tuesday, January 24, 2006 + * + *------------------------------------------------------------------------- + */ +hid_t +H5Dcreate_expand(hid_t loc_id, hid_t type_id, hid_t space_id, + hid_t dcpl_id) +{ + H5G_loc_t loc; /* Object location to insert dataset into */ + H5D_t *new_dset = NULL; /* New dataset's info */ + const H5S_t *space; /* Dataspace for dataset */ + hid_t ret_value; /* Return value */ + + FUNC_ENTER_API(H5Dcreate_expand, FAIL) + H5TRACE4("i","iiii",loc_id,type_id,space_id,dcpl_id); + + /* Check arguments */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID") + if(H5I_DATATYPE != H5I_get_type(type_id)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype ID") + if(NULL == (space = H5I_object_verify(space_id,H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace ID") + if(H5P_DEFAULT == dcpl_id) + dcpl_id = H5P_DATASET_CREATE_DEFAULT; + else + if(TRUE != H5P_isa_class(dcpl_id, H5P_DATASET_CREATE)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not dataset create property list ID") + + /* build and open the new dataset */ + if(NULL == (new_dset = H5D_create(loc.oloc->file, type_id, space, dcpl_id, H5AC_dxpl_id))) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset") /* Register the new dataset to get an ID for it */ @@ -2030,14 +2134,13 @@ done: *------------------------------------------------------------------------- */ static H5D_t * -H5D_create(H5G_loc_t *loc, const char *name, hid_t type_id, const H5S_t *space, +H5D_create(H5F_t *file, hid_t type_id, const H5S_t *space, hid_t dcpl_id, hid_t dxpl_id) { const H5T_t *type; /* Datatype for dataset */ H5D_t *new_dset = NULL; int i, ndims; unsigned u; - H5F_t *file=NULL; unsigned chunk_ndims = 0; /* Dimensionality of chunk */ H5P_genplist_t *dc_plist=NULL; /* New Property list */ hbool_t has_vl_type=FALSE; /* Flag to indicate a VL-type for dataset */ @@ -2048,8 +2151,7 @@ H5D_create(H5G_loc_t *loc, const char *name, hid_t type_id, const H5S_t *space, FUNC_ENTER_NOAPI(H5D_create, NULL) /* check args */ - HDassert(loc); - HDassert(name && *name); + HDassert(file); HDassert(H5I_DATATYPE==H5I_get_type(type_id)); HDassert(space); HDassert(H5I_GENPROP_LST==H5I_get_type(dcpl_id)); @@ -2084,10 +2186,6 @@ H5D_create(H5G_loc_t *loc, const char *name, hid_t type_id, const H5S_t *space, if(NULL == (new_dset->shared = H5D_new(dcpl_id,TRUE,has_vl_type))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - /* What file is the dataset being added to? */ - if(NULL == (file = H5G_insertion_file(loc, name, dxpl_id))) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to locate insertion point") - /* Copy datatype for dataset */ if(H5D_init_type(file, new_dset, type_id, type)<0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy datatype") @@ -2306,18 +2404,11 @@ H5D_create(H5G_loc_t *loc, const char *name, hid_t type_id, const H5S_t *space, if (H5D_get_dcpl_cache(new_dset->shared->dcpl_id,&new_dset->shared->dcpl_cache)<0) HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't fill DCPL cache") - /* - * Give the dataset a name. That is, create and add a new object to the - * group this dataset is being initially created in. - */ - if(H5G_insert(loc, name, &dset_loc, dxpl_id, dc_plist) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to name dataset") - /* Add the dataset to the list of opened objects in the file */ if(H5FO_top_incr(new_dset->oloc.file, new_dset->oloc.addr) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, NULL, "can't incr object ref. count") - if(H5FO_insert(new_dset->oloc.file, new_dset->oloc.addr, new_dset->shared) < 0) - HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, NULL, "can't insert dataset into list of open objects") + if(H5FO_insert(new_dset->oloc.file, new_dset->oloc.addr, new_dset->shared, TRUE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, NULL, "can't insert dataset into list of open objects") new_dset->shared->fo_count = 1; @@ -2410,7 +2501,7 @@ H5D_open(const H5G_loc_t *loc, hid_t dxpl_id) HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, NULL, "not found") /* Add the dataset to the list of opened objects in the file */ - if(H5FO_insert(dataset->oloc.file, dataset->oloc.addr, dataset->shared) < 0) + if(H5FO_insert(dataset->oloc.file, dataset->oloc.addr, dataset->shared, FALSE) < 0) HGOTO_ERROR(H5E_DATASET, H5E_CANTINSERT, NULL, "can't insert dataset into list of open objects") /* Increment object count for the object in the top file */ diff --git a/src/H5Dpublic.h b/src/H5Dpublic.h index 0edabb3..45b13d8 100644 --- a/src/H5Dpublic.h +++ b/src/H5Dpublic.h @@ -111,6 +111,8 @@ H5_DLL herr_t H5Dfill(const void *fill, hid_t fill_type, void *buf, hid_t buf_type, hid_t space); H5_DLL herr_t H5Dset_extent(hid_t dset_id, const hsize_t *size); H5_DLL herr_t H5Ddebug(hid_t dset_id); +H5_DLL hid_t H5Dcreate_expand(hid_t file_id, hid_t type_id, + hid_t space_id, hid_t plist_id); #ifdef __cplusplus diff --git a/src/H5Edefin.h b/src/H5Edefin.h index f297a50..8602aca 100644 --- a/src/H5Edefin.h +++ b/src/H5Edefin.h @@ -115,7 +115,7 @@ hid_t H5E_NOENCODER_g = FAIL; /* Filter present but encoding disabled hid_t H5E_CANTOPENOBJ_g = FAIL; /* Can't open object */ hid_t H5E_CANTCLOSEOBJ_g = FAIL; /* Can't close object */ hid_t H5E_COMPLEN_g = FAIL; /* Name component is too long */ -hid_t H5E_LINK_g = FAIL; /* Link count failure */ +hid_t H5E_LINK_g = FAIL; /* Link-related failure */ hid_t H5E_SLINK_g = FAIL; /* Symbolic link error */ hid_t H5E_PATH_g = FAIL; /* Problem with path to object */ diff --git a/src/H5Einit.h b/src/H5Einit.h index aedbac3..5f95ca8 100644 --- a/src/H5Einit.h +++ b/src/H5Einit.h @@ -414,7 +414,7 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Name component is too long"))==NULL) if((H5E_COMPLEN_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") assert(H5E_LINK_g==(-1)); -if((msg = H5E_create_msg(cls, H5E_MINOR, "Link count failure"))==NULL) +if((msg = H5E_create_msg(cls, H5E_MINOR, "Link failure"))==NULL) HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed") if((H5E_LINK_g = H5I_register(H5I_ERROR_MSG, msg))<0) HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message") @@ -145,7 +145,7 @@ H5FO_opened(const H5F_t *f, haddr_t addr) H5F_t *f; IN/OUT: File's opened object info set haddr_t addr; IN: Address of object to insert void *obj; IN: Pointer to object to insert - int type; IN: Type of object being inserted + hbool_t delete_flag; IN: Whether to 'mark' this object for deletion RETURNS Returns a non-negative on success, negative on failure @@ -157,7 +157,7 @@ H5FO_opened(const H5F_t *f, haddr_t addr) REVISION LOG --------------------------------------------------------------------------*/ herr_t -H5FO_insert(const H5F_t *f, haddr_t addr, void *obj) +H5FO_insert(const H5F_t *f, haddr_t addr, void *obj, hbool_t delete_flag) { H5FO_open_obj_t *open_obj; /* Information about open object */ herr_t ret_value=SUCCEED; /* Return value */ @@ -178,7 +178,7 @@ H5FO_insert(const H5F_t *f, haddr_t addr, void *obj) /* Assign information */ open_obj->addr=addr; open_obj->obj=obj; - open_obj->deleted=0; + open_obj->deleted=delete_flag; /* Insert into container */ if(H5SL_insert(f->shared->open_objs,&open_obj->addr,open_obj)<0) @@ -289,7 +289,7 @@ H5FO_mark(const H5F_t *f, haddr_t addr, hbool_t deleted) PURPOSE Check if an object is marked to be deleted when it is closed USAGE - htri_t H5FO_mark(f,addr) + htri_t H5FO_marked(f,addr) const H5F_t *f; IN: File opened object is in haddr_t addr; IN: Address of object to delete diff --git a/src/H5FOprivate.h b/src/H5FOprivate.h index f5b7691..4fd0f38 100644 --- a/src/H5FOprivate.h +++ b/src/H5FOprivate.h @@ -37,7 +37,7 @@ typedef H5SL_t H5FO_t; /* Currently, all open objects are stored in skip l /* Private routines */ H5_DLL herr_t H5FO_create(const H5F_t *f); H5_DLL void *H5FO_opened(const H5F_t *f, haddr_t addr); -H5_DLL herr_t H5FO_insert(const H5F_t *f, haddr_t addr, void *obj); +H5_DLL herr_t H5FO_insert(const H5F_t *f, haddr_t addr, void *obj, hbool_t delete_flag); H5_DLL herr_t H5FO_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr); H5_DLL herr_t H5FO_mark(const H5F_t *f, haddr_t addr, hbool_t deleted); H5_DLL htri_t H5FO_marked(const H5F_t *f, haddr_t addr); @@ -90,6 +90,7 @@ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ +#include "H5Lprivate.h" /* Links */ /* Local macros */ #define H5G_INIT_HEAP 8192 @@ -102,20 +103,6 @@ typedef struct { H5F_t *file; /* Pointer to the file for insertion */ } H5G_trav_ud1_t; -/* User data for path traversal routine for moving a link */ -typedef struct { - H5G_obj_t type; /* Type of object being moved */ - const char *dst_name; /* Destination name for moving object */ - H5G_loc_t *dst_loc; /* Destination location for moving object */ -} H5G_trav_ud2_t; - -/* User data for path traversal callback to creating link */ -typedef struct { - H5F_t *file; /* Pointer to the file */ - hid_t dxpl_id; /* Dataset transfer property list */ - H5O_link_t *lnk; /* Pointer to link information to insert */ -} H5G_trav_ud3_t; - /* User data for path traversal routine for getting object info */ typedef struct { H5G_stat_t *statbuf; /* Stat buffer about object */ @@ -123,17 +110,6 @@ typedef struct { hid_t dxpl_id; /* Dataset transfer property list */ } H5G_trav_ud4_t; -/* User data for path traversal routine for getting soft link value */ -typedef struct { - size_t size; /* Size of user buffer */ - char *buf; /* User buffer */ -} H5G_trav_ud5_t; - -/* User data for path traversal routine for removing link (i.e. unlink) */ -typedef struct { - hid_t dxpl_id; /* Dataset transfer property list */ -} H5G_trav_ud6_t; - /* User data for path traversal routine for inserting object */ typedef struct { H5G_loc_t *obj_loc; /* Object location */ @@ -149,39 +125,18 @@ H5FL_DEFINE(H5G_t); H5FL_DEFINE(H5G_shared_t); /* Private prototypes */ -static char * H5G_normalize(const char *name); -static H5G_t *H5G_create(H5G_loc_t *loc, const char *name, hid_t dxpl_id, - hid_t gcpl_id, hid_t gapl_id); +static H5G_t *H5G_create(H5F_t *file, hid_t dxpl_id, hid_t gcpl_id, hid_t gapl_id); static herr_t H5G_open_oid(H5G_t *grp, hid_t dxpl_id); -static herr_t H5G_insert_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); static herr_t H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); -static herr_t H5G_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); -static herr_t H5G_link_real(H5G_loc_t *link_loc, const char *link_name, - H5F_t *file, H5O_link_t *lnk, hid_t dxpl_id); -static herr_t H5G_link(H5G_loc_t *cur_loc, const char *cur_name, - H5G_loc_t *link_loc, const char *link_name, H5G_link_t type, - unsigned traverse_flags, hid_t dxpl_id); -static herr_t H5G_linkval_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); -static herr_t H5G_linkval(H5G_loc_t *loc, const char *name, size_t size, - char *buf/*out*/, hid_t dxpl_id); static herr_t H5G_set_comment(H5G_loc_t *loc, const char *name, const char *buf, hid_t dxpl_id); static int H5G_get_comment(H5G_loc_t *loc, const char *name, size_t bufsize, char *buf, hid_t dxpl_id); -static herr_t H5G_unlink_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); -static herr_t H5G_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id); -static herr_t H5G_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, - const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); -static herr_t H5G_move(H5G_loc_t *src_loc, const char *src_name, - H5G_loc_t *dst_loc, const char *dst_name, hid_t dxpl_id); static herr_t H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); -static herr_t H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, hid_t plist_id); +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); /*------------------------------------------------------------------------- @@ -215,8 +170,11 @@ hid_t H5Gcreate(hid_t loc_id, const char *name, size_t size_hint) { H5G_loc_t loc; + H5G_loc_t grp_loc; H5G_t *grp = NULL; + H5F_t *file; /* File the group will be inserted into */ hid_t tmp_gcpl = (-1); /* Temporary group creation property list */ + hid_t grp_id = (-1); /* ID of group being created */ hid_t ret_value; FUNC_ENTER_API(H5Gcreate, FAIL) @@ -259,19 +217,36 @@ H5Gcreate(hid_t loc_id, const char *name, size_t size_hint) #endif /* H5_GROUP_REVISION */ tmp_gcpl = H5P_GROUP_CREATE_DEFAULT; + /* What file is the group being added to? This may not be the same file + * that loc_id is in if mounting is being used. */ + if(NULL == (file = H5G_insertion_file(&loc, name, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to locate insertion point") + /* Create the group */ - if(NULL == (grp = H5G_create(&loc, name, H5AC_dxpl_id, tmp_gcpl, H5P_DEFAULT))) + if(NULL == (grp = H5G_create(file, H5AC_dxpl_id, tmp_gcpl, H5P_DEFAULT))) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") - if((ret_value = H5I_register(H5I_GROUP, grp)) < 0) + + if((grp_id = H5I_register(H5I_GROUP, grp)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") + if(H5G_loc(grp_id, &grp_loc) <0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to get location for new group") + + /* Link the group */ + if( H5L_link(&loc, name, &grp_loc, H5AC_dxpl_id, H5P_DEFAULT) < 0) + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to create link to group") + + ret_value = grp_id; + done: if(tmp_gcpl > 0 && tmp_gcpl != H5P_GROUP_CREATE_DEFAULT) if(H5I_dec_ref(tmp_gcpl) < 0) HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release property list") if(ret_value < 0) { - if(grp!=NULL) + if(grp_id >= 0) + H5I_dec_ref(grp_id); + else if(grp!=NULL) H5G_close(grp); } /* end if */ @@ -283,12 +258,15 @@ done: /*------------------------------------------------------------------------- * Function: H5Gcreate_expand * - * Purpose: Creates a new group relative to LOC_ID and gives it the - * specified NAME, and creation property list GCPL_ID and access + * Purpose: Creates a new group relative to LOC_ID, giving it the + * specified creation property list GCPL_ID and access * property list GAPL_ID. * - * Given the default setting, H5Gcreate_expand() will have the - * same function of H5Gcreate() + * The resulting ID should be linked into the file with + * H5Lcreate or it will be deleted when closed. + * + * Given the default setting, H5Gcreate_expand() followed by + * H5Lcreate() will have the same function as H5Gcreate(). * * Usage: H5Gcreate_expand(loc_id, char *name, gcpl_id, gapl_id) * hid_t loc_id; IN: File or group identifier @@ -316,20 +294,18 @@ done: *------------------------------------------------------------------------- */ hid_t -H5Gcreate_expand(hid_t loc_id, const char *name, hid_t gcpl_id, hid_t gapl_id) +H5Gcreate_expand(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id) { H5G_loc_t loc; H5G_t *grp = NULL; hid_t ret_value; FUNC_ENTER_API(H5Gcreate_expand, FAIL) - H5TRACE4("i","isii",loc_id,name,gcpl_id,gapl_id); + H5TRACE3("i","iii",loc_id,gcpl_id,gapl_id); /* Check arguments */ if(H5G_loc(loc_id, &loc) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given") /* Check group creation property list */ if(H5P_DEFAULT == gcpl_id) @@ -347,7 +323,7 @@ H5Gcreate_expand(hid_t loc_id, const char *name, hid_t gcpl_id, hid_t gapl_id) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list") #endif /* LATER */ - if(NULL == (grp = H5G_create(&loc, name, H5AC_dxpl_id, gcpl_id, gapl_id))) + if(NULL == (grp = H5G_create(loc.oloc->file, H5AC_dxpl_id, gcpl_id, gapl_id))) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group") if((ret_value = H5I_register(H5I_GROUP, grp)) < 0) HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group") @@ -666,171 +642,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Gmove2 - * - * Purpose: Renames an object within an HDF5 file. The original name SRC - * is unlinked from the group graph and the new name DST is - * inserted as an atomic operation. Both names are interpreted - * relative to SRC_LOC_ID and DST_LOC_ID, which are either a file - * ID or a group ID. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, April 6, 1998 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Gmove2(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, - const char *dst_name) -{ - H5G_loc_t src_loc, *src_loc_p; - H5G_loc_t dst_loc, *dst_loc_p; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Gmove2, FAIL) - H5TRACE4("e","isis",src_loc_id,src_name,dst_loc_id,dst_name); - - if(src_loc_id != H5G_SAME_LOC && H5G_loc(src_loc_id, &src_loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(dst_loc_id != H5G_SAME_LOC && H5G_loc(dst_loc_id, &dst_loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(!src_name || !*src_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified") - if(!dst_name || !*dst_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified") - - /* Set up src & dst location pointers */ - src_loc_p = &src_loc; - dst_loc_p = &dst_loc; - if(src_loc_id == H5G_SAME_LOC && dst_loc_id == H5G_SAME_LOC) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not be both H5G_SAME_LOC") - else if(src_loc_id == H5G_SAME_LOC) - src_loc_p = dst_loc_p; - else if(dst_loc_id == H5G_SAME_LOC) - dst_loc_p = src_loc_p; - else if(src_loc_p->oloc->file != dst_loc_p->oloc->file) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file.") - - if(H5G_move(src_loc_p, src_name, dst_loc_p, dst_name, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to change object name") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Gmove2() */ - - -/*------------------------------------------------------------------------- - * Function: H5Glink2 - * - * Purpose: Creates a link of the specified type from NEW_NAME to - * CUR_NAME. - * - * If TYPE is H5G_LINK_HARD then CUR_NAME must name an existing - * object. CUR_NAME and NEW_NAME are interpreted relative to - * CUR_LOC_ID and NEW_LOC_ID, which is either a file ID or a - * group ID. - * - * If TYPE is H5G_LINK_SOFT then CUR_NAME can be anything and is - * interpreted at lookup time relative to the group which - * contains the final component of NEW_NAME. For instance, if - * CUR_NAME is `./foo' and NEW_NAME is `./x/y/bar' and a request - * is made for `./x/y/bar' then the actual object looked up is - * `./x/y/./foo'. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, April 6, 1998 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Glink2(hid_t cur_loc_id, const char *cur_name, H5G_link_t type, - hid_t new_loc_id, const char *new_name) -{ - H5G_loc_t cur_loc, *cur_loc_p; - H5G_loc_t new_loc, *new_loc_p; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Glink2, FAIL) - H5TRACE5("e","isGlis",cur_loc_id,cur_name,type,new_loc_id,new_name); - - /* Check arguments */ - if(cur_loc_id != H5G_SAME_LOC && H5G_loc(cur_loc_id, &cur_loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(new_loc_id != H5G_SAME_LOC && H5G_loc(new_loc_id, &new_loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(type != H5G_LINK_HARD && type != H5G_LINK_SOFT) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unrecognized link type") - if(!cur_name || !*cur_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified") - if(!new_name || !*new_name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified") - - /* Set up current & new location pointers */ - cur_loc_p = &cur_loc; - new_loc_p = &new_loc; - if(cur_loc_id == H5G_SAME_LOC && new_loc_id == H5G_SAME_LOC) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not be both H5G_SAME_LOC") - else if(cur_loc_id == H5G_SAME_LOC) - cur_loc_p = new_loc_p; - else if(new_loc_id == H5G_SAME_LOC) - new_loc_p = cur_loc_p; - else if(cur_loc_p->oloc->file != new_loc_p->oloc->file) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file.") - - if(H5G_link(cur_loc_p, cur_name, new_loc_p, new_name, type, H5G_TARGET_NORMAL, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to create link") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Glink2() */ - - -/*------------------------------------------------------------------------- - * Function: H5Gunlink - * - * Purpose: Removes the specified NAME from the group graph and - * decrements the link count for the object to which NAME - * points. If the link count reaches zero then all file-space - * associated with the object will be reclaimed (but if the - * object is open, then the reclamation of the file space is - * delayed until all handles to the object are closed). - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, April 6, 1998 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Gunlink(hid_t loc_id, const char *name) -{ - H5G_loc_t loc; - herr_t ret_value=SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Gunlink, FAIL) - H5TRACE2("e","is",loc_id,name); - - /* Check arguments */ - if(H5G_loc(loc_id, &loc) < 0) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") - - /* Unlink */ - if(H5G_unlink(&loc, name, H5AC_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to unlink object") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Gunlink() */ - - -/*------------------------------------------------------------------------- * Function: H5Gget_objinfo * * Purpose: Returns information about an object. If FOLLOW_LINK is @@ -871,46 +682,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5Gget_linkval - * - * Purpose: Returns the value of a symbolic link whose name is NAME. At - * most SIZE characters (counting the null terminator) are - * copied to the BUF result buffer. - * - * Return: Success: Non-negative with the link value in BUF. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Monday, April 13, 1998 - * - *------------------------------------------------------------------------- - */ -herr_t -H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/) -{ - H5G_loc_t loc; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Gget_linkval, FAIL) - H5TRACE4("e","iszx",loc_id,name,size,buf); - - /* Check arguments */ - if(H5G_loc(loc_id, &loc)) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") - if(!name || !*name) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") - - /* Get the link value */ - if(H5G_linkval(&loc, name, size, buf, H5AC_ind_dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Gget_linkval() */ - - -/*------------------------------------------------------------------------- * Function: H5Gset_comment * * Purpose: Gives the specified object a comment. The COMMENT string @@ -1072,9 +843,6 @@ done: * copy. * * OPTIONS THAT MAY APPLY TO COPY IN THE FUTURE. - * H5G_COPY_CREATE_INTERMEDIATE_GROUP_FLAG - * Do not create missing groups when create a group (default) - * Create missing groups when create a group * H5G_COPY_SHALLOW_HIERARCHY_FLAG * Recursively copy all objects below the group (default) * Only immediate members. @@ -1097,12 +865,16 @@ done: * Add an attribute to the copied object(s) that say the date/time * for the copy or other information about the source file. * - * Usage: H5Gcopy(src_loc_id, src_name, dst_loc_id, dst_name, plist_id) + * 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 plist_id IN: Properties which apply to the copy + * 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 @@ -1114,7 +886,7 @@ done: */ herr_t H5Gcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, - const char *dst_name, hid_t plist_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 */ @@ -1129,7 +901,8 @@ H5Gcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5Gcopy, FAIL) - H5TRACE5("e","isisi",src_loc_id,src_name,dst_loc_id,dst_name,plist_id); + 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) @@ -1155,14 +928,21 @@ H5Gcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object") obj_open = TRUE; - /* Get correct property list */ - if(H5P_DEFAULT == plist_id) - plist_id = H5P_OBJECT_COPY_DEFAULT; + /* 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") + 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(plist_id, H5P_OBJECT_COPY)) + 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, plist_id) < 0) + 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: @@ -1338,7 +1118,7 @@ H5G_component(const char *name, size_t *size_p) * *------------------------------------------------------------------------- */ -static char * +char * H5G_normalize(const char *name) { char *norm; /* Pointer to the normalized string */ @@ -1518,24 +1298,20 @@ done: *------------------------------------------------------------------------- */ static H5G_t * -H5G_create(H5G_loc_t *loc, const char *name, - hid_t dxpl_id, hid_t gcpl_id, hid_t UNUSED gapl_id) +H5G_create(H5F_t *file, hid_t dxpl_id, hid_t gcpl_id, hid_t UNUSED gapl_id) { H5G_t *grp = NULL; /*new group */ - H5F_t *file = NULL; /* File new group will be in */ H5P_genplist_t *gc_plist; /* Property list created */ #ifdef H5_GROUP_REVISION H5O_ginfo_t ginfo; /* Group info */ #endif /* H5_GROUP_REVISION */ unsigned oloc_init = 0; /* Flag to indicate that the group object location was created successfully */ - H5G_loc_t grp_loc; /* Group location wrapper structure */ H5G_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5G_create) /* check args */ - HDassert(loc); - HDassert(name && *name); + HDassert(file); HDassert(gcpl_id != H5P_DEFAULT); #ifdef LATER HDassert(gapl_id != H5P_DEFAULT); @@ -1547,10 +1323,6 @@ H5G_create(H5G_loc_t *loc, const char *name, if(NULL == (grp->shared = H5FL_CALLOC(H5G_shared_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") - /* What file is the group being added to? */ - if(NULL == (file = H5G_insertion_file(loc, name, dxpl_id))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to locate insertion point") - /* Get the property list */ if(NULL == (gc_plist = H5I_object(gcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list") @@ -1570,20 +1342,14 @@ H5G_create(H5G_loc_t *loc, const char *name, HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "unable to create group object header") oloc_init = 1; /* Indicate that the object location information is valid */ - /* Insert child name into parent */ - grp_loc.oloc = &(grp->oloc); - grp_loc.path = &(grp->path); - if(H5G_insert(loc, name, &grp_loc, dxpl_id, gc_plist) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group") - /* Add group to list of open objects in file */ if(H5FO_top_incr(grp->oloc.file, grp->oloc.addr) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINC, NULL, "can't incr object ref. count") - if(H5FO_insert(grp->oloc.file, grp->oloc.addr, grp->shared) < 0) + if(H5FO_insert(grp->oloc.file, grp->oloc.addr, grp->shared, TRUE) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group into list of open objects") grp->shared->fo_count = 1; - + /* Set return value */ ret_value = grp; @@ -1655,7 +1421,7 @@ H5G_open(H5G_loc_t *loc, hid_t dxpl_id) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "not found") /* Add group to list of open objects in file */ - if(H5FO_insert(grp->oloc.file, grp->oloc.addr, grp->shared) < 0) { + if(H5FO_insert(grp->oloc.file, grp->oloc.addr, grp->shared, FALSE) < 0) { H5FL_FREE(H5G_shared_t, grp->shared); HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group into list of open objects") } /* end if */ @@ -1955,301 +1721,6 @@ H5G_fileof(H5G_t *grp) /*------------------------------------------------------------------------- - * Function: H5G_insert_cb - * - * Purpose: Path traversal callback for inserting an object in a group. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, September 13, 2005 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_insert_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) -{ - H5G_trav_ud7_t *udata = (H5G_trav_ud7_t *)_udata; /* User data passed in */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_insert_cb) - - /* Check for object using name already */ - if(obj_loc != NULL) - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name already exists") - - /* Insert object into group */ - if(H5G_loc_insert(grp_loc, name, udata->obj_loc, TRUE, udata->dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert name") - -done: - if(ret_value < 0) { - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_insert_cb() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_insert - * - * Purpose: Inserts a symbol table entry into the group graph. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Friday, September 19, 1997 - * - *------------------------------------------------------------------------- - */ -herr_t -H5G_insert(H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc, hid_t dxpl_id, H5P_genplist_t *oc_plist) -{ - H5G_trav_ud7_t udata; /* User data for callback routine */ - unsigned target_flags = H5G_TARGET_NORMAL; - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5G_insert, FAIL) - - /* Check args. */ - HDassert(loc); - HDassert(name && *name); - HDassert(obj_loc); - - /* Check for intermediate group creation flag present */ - if(oc_plist != NULL) { - unsigned crt_intmd_group; - - if(H5P_get(oc_plist, H5G_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for creating missing groups") - - if (crt_intmd_group > 0) - target_flags |= H5G_CRT_INTMD_GROUP; - } /* end if */ - - /* Set up user data callback for path traversal */ - udata.obj_loc = obj_loc; - udata.dxpl_id = dxpl_id; - - /* - * Lookup and insert the name -- it shouldn't exist yet. - */ - if(H5G_traverse(loc, name, target_flags, H5G_insert_cb, &udata, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "can't insert object in group") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_insert() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_link_cb - * - * Purpose: Callback for creating a link to an object. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, September 19, 2005 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) -{ - char *old_link_name = NULL; /* Pointer to hold the old link name */ - hbool_t old_link_name_set = FALSE; /* Indicate that we've replaced the old link name */ - H5G_trav_ud3_t *udata = (H5G_trav_ud3_t *)_udata; /* User data passed in */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_link_cb) - - /* Check if the name in this group resolved to a valid location */ - /* (which is not what we want) */ - if(obj_loc != NULL) - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name already exists") - - /* Check for crossing file boundaries with a new hard link */ - if(udata->lnk->type == H5G_LINK_HARD) { - /* Check that both objects are in same file */ - if(grp_loc->oloc->file->shared != udata->file->shared) - HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "interfile hard links are not allowed") - } /* end if */ - - /* Set the link's name correctly */ - /* Casting away const OK -QAK */ - old_link_name = udata->lnk->name; - udata->lnk->name = name; - old_link_name_set = TRUE; - - /* Insert link into group */ - if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, (hbool_t)(udata->lnk->type == H5G_LINK_HARD ? TRUE : FALSE), udata->dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object") - -done: - if(ret_value < 0) { - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); - } /* end if */ - - /* Return the link's name to it's original value */ - if(old_link_name_set) - udata->lnk->name = old_link_name; - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_link_cb() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_link_real - * - * Purpose: Creates a link at a path location - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, December 5, 2005 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_link_real(H5G_loc_t *link_loc, const char *link_name, H5F_t *file, - H5O_link_t *lnk, hid_t dxpl_id) -{ - H5G_trav_ud3_t udata; /* User data for callback */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_link_real) - - /* Check args */ - HDassert(link_loc); - HDassert(link_name && *link_name); - HDassert(lnk); - - /* Set up user data */ - udata.file = file; - udata.lnk = lnk; - udata.dxpl_id = dxpl_id; - - /* Traverse the destination path & create new link */ - if(H5G_traverse(link_loc, link_name, H5G_TARGET_NORMAL, H5G_link_cb, &udata, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert link") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_link_real() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_link - * - * Purpose: Creates a link from NEW_NAME to CUR_NAME. See H5Glink() for - * full documentation. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Monday, April 6, 1998 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_link(H5G_loc_t *cur_loc, const char *cur_name, - H5G_loc_t *link_loc, const char *link_name, - H5G_link_t type, unsigned traverse_flags, hid_t dxpl_id) -{ - char *norm_cur_name = NULL; /* Pointer to normalized current name */ - char *norm_link_name = NULL; /* Pointer to normalized link name */ - H5F_t *link_file = NULL; /* Pointer to file to link to */ - H5O_link_t lnk; /* Link to insert */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_link) - - /* Check args */ - HDassert(cur_loc); - HDassert(link_loc); - HDassert(cur_name && *cur_name); - HDassert(link_name && *link_name); - - /* Get normalized copies of the current and new names */ - if((norm_cur_name = H5G_normalize(cur_name)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") - if((norm_link_name = H5G_normalize(link_name)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") - - switch(type) { - case H5G_LINK_HARD: - { - H5O_loc_t obj_oloc; /* Location of object to link to */ - - /* Get object location for object pointed to */ - if(H5G_obj_find(cur_loc, norm_cur_name, traverse_flags, NULL, &obj_oloc, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found") - - /* Construct link information for eventual insertion */ - lnk.u.hard.addr = obj_oloc.addr; - - /* Set destination's file information */ - link_file = obj_oloc.file; - } /* end case */ - break; - - case H5G_LINK_SOFT: - /* Construct link information for eventual insertion */ - lnk.u.soft.name = norm_cur_name; - - /* Set destination's file information */ - link_file = NULL; /* no file info necessary for soft link */ - break; - - default: - HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type") - } /* end switch */ - - /* Set up common link data */ - lnk.type = type; -#ifdef H5_HAVE_GETTIMEOFDAY - { - struct timeval now_tv; - - HDgettimeofday(&now_tv, NULL); - lnk.ctime = now_tv.tv_sec; - } -#else /* H5_HAVE_GETTIMEOFDAY */ - lnk.ctime = HDtime(NULL); -#endif /* H5_HAVE_GETTIMEOFDAY */ - lnk.cset = H5T_CSET_ASCII; /* XXX: Allow user to set this */ - /* lnk.name = name; */ /* This will be set in callback */ - - /* Create actual link to the object */ - if(H5G_link_real(link_loc, norm_link_name, link_file, &lnk, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object") - -done: - /* Free the normalized path names */ - if(norm_cur_name) - H5MM_xfree(norm_cur_name); - if(norm_link_name) - H5MM_xfree(norm_link_name); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_link() */ - - -/*------------------------------------------------------------------------- * Function: H5G_get_objinfo_cb * * Purpose: Callback for retrieving info about an object. This routine @@ -2289,7 +1760,7 @@ H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_ /* Get info for soft link */ /* (If we don't follow the link, we can retrieve info about the soft link itself) */ - if(!udata->follow_link && lnk && lnk->type == H5G_LINK_SOFT) { + if(!udata->follow_link && lnk && lnk->type == H5L_LINK_SOFT) { /* Set object type */ statbuf->type = H5G_LINK; @@ -2383,92 +1854,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_linkval_cb - * - * Purpose: Callback for retrieving soft link value for an object. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Tuesday, September 20, 2005 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_linkval_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, - H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/) -{ - H5G_trav_ud5_t *udata = (H5G_trav_ud5_t *)_udata; /* User data passed in */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_linkval_cb) - - /* Check if the name in this group resolved to a valid link */ - if(lnk == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") - - if(H5G_LINK_SOFT != lnk->type) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object is not a symbolic link") - - /* Copy to output buffer */ - if(udata->size > 0 && udata->buf) { - HDstrncpy(udata->buf, lnk->u.soft.name, udata->size); - if(HDstrlen(lnk->u.soft.name) >= udata->size) - udata->buf[udata->size - 1] = '\0'; - } /* end if */ - -done: - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_linkval_cb() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_linkval - * - * Purpose: Returns the value of a symbolic link. - * - * Return: Success: Non-negative, with at most SIZE bytes of the - * link value copied into the BUF buffer. If the - * link value is larger than SIZE characters - * counting the null terminator then the BUF - * result will not be null terminated. - * - * Failure: Negative - * - * Programmer: Robb Matzke - * Monday, April 13, 1998 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_linkval(H5G_loc_t *loc, const char *name, size_t size, char *buf/*out*/, hid_t dxpl_id) -{ - H5G_trav_ud5_t udata; /* User data for callback */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_linkval) - - /* Set up user data for retrieving information */ - udata.size = size; - udata.buf = buf; - - /* Traverse the group hierarchy to locate the object to get info about */ - if(H5G_traverse(loc, name, H5G_TARGET_SLINK, H5G_linkval_cb, &udata, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* H5G_linkval() */ - - -/*------------------------------------------------------------------------- * Function: H5G_set_comment * * Purpose: (Re)sets the comment for an object. @@ -2558,231 +1943,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_unlink_cb - * - * Purpose: Callback for unlinking an object. This routine - * deletes the link - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, September 19, 2005 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_unlink_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) -{ - H5G_trav_ud6_t *udata = (H5G_trav_ud6_t *)_udata; /* User data passed in */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_unlink_cb) - - /* Check if the name in this group resolved to a valid link */ - if(obj_loc == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") - - /* Check for removing '.' */ - if(lnk == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't delete self") - - /* Remove the link from the group */ - if(H5G_loc_remove(grp_loc, name, obj_loc, udata->dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to unlink name from group") - -done: - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_unlink_cb() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_unlink - * - * Purpose: Unlink a name from a group. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Thursday, September 17, 1998 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id) -{ - H5G_trav_ud6_t udata; /* User data for callback */ - char *norm_name = NULL; /* Pointer to normalized name */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_unlink) - - /* Sanity check */ - HDassert(loc); - HDassert(name && *name); - - /* Get normalized copy of the name */ - if((norm_name = H5G_normalize(name)) == NULL) - HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") - - /* Set up user data for creating soft link */ - udata.dxpl_id = dxpl_id; - - if(H5G_traverse(loc, norm_name, H5G_TARGET_SLINK|H5G_TARGET_MOUNT, H5G_unlink_cb, &udata, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") - -done: - /* Free the normalized path name */ - if(norm_name) - H5MM_xfree(norm_name); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_unlink() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_move_cb - * - * Purpose: Callback for moving an object. This routine replaces the - * names of open objects with the moved object in the path - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Quincey Koziol - * Monday, September 19, 2005 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_move_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk, - H5G_loc_t *obj_loc, void *_udata/*in,out*/) -{ - H5G_trav_ud2_t *udata = (H5G_trav_ud2_t *)_udata; /* User data passed in */ - H5RS_str_t *dst_name_r = NULL; /* Ref-counted version of dest name */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_move_cb) - - /* Check if the name in this group resolved to a valid link */ - if(obj_loc == NULL) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") - - /* Fix names up */ - dst_name_r = H5RS_wrap(udata->dst_name); - HDassert(dst_name_r); - if(H5G_name_replace(udata->type, obj_loc, dst_name_r, udata->dst_loc, H5G_NAME_MOVE) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name ") - -done: - /* Cleanup */ - if(dst_name_r) - H5RS_decr(dst_name_r); - - /* Release the group location for the object */ - /* (Group traversal callbacks are responsible for either taking ownership - * of the group location for the object, or freeing it. - QAK) - */ - if(obj_loc) - H5G_loc_free(obj_loc); - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_move_cb() */ - - -/*------------------------------------------------------------------------- - * Function: H5G_move - * - * Purpose: Atomically rename an object. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Friday, September 25, 1998 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5G_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, - const char *dst_name, hid_t dxpl_id) -{ - H5O_loc_t src_oloc; /* Location of object linked to */ - H5O_link_t lnk; /* Link information for object to move */ - hbool_t link_valid = FALSE; /* Flag to indicate that the link information is valid */ - H5G_trav_ud2_t udata; /* User data for traversal */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI_NOINIT(H5G_move) - - /* Sanity check */ - HDassert(src_loc); - HDassert(dst_loc); - HDassert(src_name && *src_name); - HDassert(dst_name && *dst_name); - - /* Get copy of link to move */ - if(H5G_obj_find(src_loc, src_name, (H5G_TARGET_MOUNT|H5G_TARGET_SLINK), &lnk, &src_oloc, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found") - link_valid = TRUE; - - /* Release name for link (it will have a new name in destination) */ - lnk.name = H5MM_xfree(lnk.name); - - /* Create new link to the object */ - if(H5G_link_real(dst_loc, dst_name, src_oloc.file, &lnk, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object") - - /* Set up user data for name replacement */ - /* Get object type */ - switch(lnk.type) { - case H5G_LINK_HARD: - if(H5G_UNKNOWN == (udata.type = H5O_obj_type(&src_oloc, dxpl_id))) - HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object type to move") - break; - - case H5G_LINK_SOFT: - udata.type = H5G_LINK; - break; - - default: - HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type") - } /* end switch */ - udata.dst_name = dst_name; - udata.dst_loc = dst_loc; - - /* Search the open ID list and replace names for the move operation - */ - if(H5G_traverse(src_loc, src_name, H5G_TARGET_MOUNT|H5G_TARGET_SLINK, H5G_move_cb, &udata, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link") - - /* Remove the old name */ - if(H5G_unlink(src_loc, src_name, dxpl_id) < 0) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to unlink old object name") - -done: - /* If there's valid information in the link, reset it */ - if(link_valid) { -#ifdef H5_GROUP_REVISION - H5O_reset(H5O_LINK_ID, &lnk); -#else /* H5_GROUP_REVISION */ - /* Free information for link (but don't free link pointer) */ - if(lnk.type == H5G_LINK_SOFT) - lnk.u.soft.name = H5MM_xfree(lnk.u.soft.name); - lnk.name = H5MM_xfree(lnk.name); -#endif /* H5_GROUP_REVISION */ - } /* end if */ - - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_move() */ - - -/*------------------------------------------------------------------------- * Function: H5G_insertion_file_cb * * Purpose: Callback for finding insertion file. This routine sets the @@ -2997,7 +2157,8 @@ H5G_unmount(H5G_t *grp) *------------------------------------------------------------------------- */ static herr_t -H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, hid_t plist_id) +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 *gcrt_plist=NULL; /* Group create property list created */ H5P_genplist_t *gcpy_plist=NULL; /* Group copy property list created */ @@ -3020,8 +2181,8 @@ H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, hid_t pli HDassert(dst_loc->oloc->file); HDassert(dst_name); - /* Get the property list */ - if(NULL == (gcpy_plist = H5I_object(plist_id))) + /* 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 */ @@ -3038,33 +2199,9 @@ H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc, const char *dst_name, hid_t pli 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") - /* Create group creatiion property to create missing groups */ - if((cpy_option & H5G_COPY_CREATE_INTERMEDIATE_GROUP_FLAG) > 0) { - if(NULL == (gcrt_class = H5I_object_verify(H5P_GROUP_CREATE, H5I_GENPROP_CLS))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") - - /* Create the new property list */ - if((gcplist_id = H5P_create_id(gcrt_class)) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTCREATE, FAIL, "unable to create property list") - gcrt_plist_created = TRUE; - } else - gcplist_id = H5P_GROUP_CREATE_DEFAULT; - - /* Get a pointer to the group creation property list */ - if(NULL == (gcrt_plist = H5I_object(gcplist_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - - /* Set the intermediate group creation property, if requested */ - if(gcrt_plist_created) { - unsigned crt_intmd_group = TRUE; - - if(H5P_set(gcrt_plist, H5G_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set intermediate group creation flag") - } /* end if */ - /* Insert the new object in the destination file's group */ - if(H5G_insert(dst_loc, dst_name, &new_loc, dxpl_id, gcrt_plist) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert the name") + if(H5L_link(dst_loc, dst_name, &new_loc, dxpl_id, lcpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert link") entry_inserted = TRUE; done: @@ -3072,11 +2209,6 @@ done: if(entry_inserted) H5G_loc_free(&new_loc); - if(gcplist_id>0 && gcrt_plist_created) { - if(H5I_dec_ref(gcplist_id)<0) - HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "unable to decrement ref count on property list") - } - FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_copy() */ diff --git a/src/H5Gdeprec.c b/src/H5Gdeprec.c new file mode 100644 index 0000000..c27826e --- /dev/null +++ b/src/H5Gdeprec.c @@ -0,0 +1,193 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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: H5Gdeprec.c + * June 21 2006 + * James Laird <jlaird@ncsa.uiuc.edu> + * + * Purpose: Deprecated functions from the H5G interface. These + * functions are here for compatibility purposes and may be + * removed in the future. Applications should switch to the + * newer APIs. + * + *------------------------------------------------------------------------- + */ + +/* Packages needed by this file... */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Gpublic.h" /* Public Group APIs */ +#include "H5Lpublic.h" /* Public Link APIs */ +#include "H5Ppublic.h" /* Property lists */ + + +/*------------------------------------------------------------------------- + * Function: H5Glink + * + * Purpose: Creates a link between two existing objects. The new + * APIs to do this are H5Lcreate_hard and H5Lcreate_soft. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Glink(hid_t cur_loc_id, H5L_link_t type, const char *cur_name, const char *new_name) +{ + herr_t ret_value; + + FUNC_ENTER_API(H5Glink, FAIL) + H5TRACE4("e","iLlss",cur_loc_id,type,cur_name,new_name); + + if(type == H5L_LINK_HARD) + { + if((ret_value = H5Lcreate_hard(cur_loc_id, cur_name, H5L_SAME_LOC, new_name, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't create link") + } + else if(type == H5L_LINK_SOFT) + { + if((ret_value = H5Lcreate_soft(cur_name, cur_loc_id, new_name, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't create link") + } + else + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Not a valid link type") + +done: + FUNC_LEAVE_API(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5Glink2 + * + * Purpose: Creates a link between two existing objects. The new + * API to do this is H5Llink. + * + *------------------------------------------------------------------------- + */ +H5Glink2(hid_t cur_loc_id, const char *cur_name, + H5L_link_t type, hid_t new_loc_id, const char *new_name) +{ + herr_t ret_value; + + FUNC_ENTER_API(H5Glink2, FAIL) + + if(type == H5L_LINK_HARD) + { + if((ret_value = H5Lcreate_hard(cur_loc_id, cur_name, new_loc_id, new_name, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't create link") + } + else if(type == H5L_LINK_SOFT) + { + /* Soft links only need one location, the new_loc_id, but it's possible that + * new_loc_id is H5L_SAME_LOC */ + if(new_loc_id == H5L_SAME_LOC) + new_loc_id = cur_loc_id; + + if((ret_value = H5Lcreate_soft(cur_name, new_loc_id, new_name, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't create link") + } + else + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Not a valid link type") + +done: + FUNC_LEAVE_API(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5Gmove + * + * Purpose: Moves and renames a link. The new API to do this is H5Lmove. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Gmove(hid_t src_loc_id, const char *src_name, const char *dst_name) +{ + herr_t ret_value; + + FUNC_ENTER_API(H5Gmove, FAIL) + H5TRACE3("e","iss",src_loc_id,src_name,dst_name); + + if((ret_value=H5Lmove(src_loc_id, src_name, H5L_SAME_LOC, dst_name, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't move link") + +done: + FUNC_LEAVE_API(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5Gmove2 + * + * Purpose: Moves and renames a link. The new API to do this is H5Lmove. + * + *------------------------------------------------------------------------- + */ +herr_t H5Gmove2(hid_t src_loc_id, const char *src_name, + hid_t dst_loc_id, const char *dst_name) +{ + herr_t ret_value; + + FUNC_ENTER_API(H5Gmove2, FAIL) + + if((ret_value=H5Lmove(src_loc_id, src_name, dst_loc_id, dst_name, H5P_DEFAULT)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTINIT, FAIL, "Couldn't move link") + +done: + FUNC_LEAVE_API(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5Gunlink + * + * Purpose: Removes a link. The new API is H5Lunlink. + * + *------------------------------------------------------------------------- + */ +herr_t +H5Gunlink(hid_t loc_id, const char *name) +{ + herr_t ret_value; + + FUNC_ENTER_API(H5Gunlink, FAIL) + H5TRACE2("e","is",loc_id,name); + + if((ret_value=H5Lunlink(loc_id, name)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_CANTDELETE, FAIL, "Couldn't delete link") + +done: + FUNC_LEAVE_API(ret_value) +} + +/*------------------------------------------------------------------------- + * Function: H5Gget_linkval + * + * Purpose: Retrieve's a soft link's data. The new API is + * H5Lget_linkval. + * + *------------------------------------------------------------------------- + */ +herr_t H5Gget_linkval(hid_t loc_id, const char *name, + size_t size, char *buf/*out*/) +{ + herr_t ret_value; + + FUNC_ENTER_API(H5Gget_linkval, FAIL) + + if((ret_value=H5Lget_linkval(loc_id, name, size, buf)) < 0) + HGOTO_ERROR(H5E_LINK, H5E_NOTFOUND, FAIL, "Couldn't get link info") + +done: + FUNC_LEAVE_API(ret_value) +} + diff --git a/src/H5Gent.c b/src/H5Gent.c index e2e512b..a8311f0 100644 --- a/src/H5Gent.c +++ b/src/H5Gent.c @@ -28,6 +28,7 @@ #include "H5Gpkg.h" /* Groups */ #include "H5HLprivate.h" /* Local Heaps */ #include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory Management */ /* Private macros */ #define H5G_NO_CHANGE (-1) /*see H5G_ent_modified() */ @@ -436,12 +437,12 @@ H5G_ent_convert(H5F_t *f, haddr_t heap_addr, const char *name, const H5O_link_t /* Build correct information for symbol table entry based on link type */ switch(lnk->type) { - case H5G_LINK_HARD: + case H5L_LINK_HARD: ent->type = H5G_NOTHING_CACHED; ent->header = lnk->u.hard.addr; break; - case H5G_LINK_SOFT: + case H5L_LINK_SOFT: { size_t lnk_offset; /* Offset to sym-link value */ diff --git a/src/H5Glink.c b/src/H5Glink.c index 28ef431..bf23058 100644 --- a/src/H5Glink.c +++ b/src/H5Glink.c @@ -296,7 +296,7 @@ H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap, /* Create link message from object entry */ HDassert(ent->type == H5G_NOTHING_CACHED || ent->type == H5G_CACHED_SLINK); /* XXX: Set character set & creation time for real? */ - lnk->cset = H5T_CSET_ASCII; + lnk->cset = H5F_CRT_DEFAULT_CSET; lnk->ctime = 0; lnk->name = H5MM_xstrdup(name); /* Casting away const OK -QAK */ HDassert(lnk->name); diff --git a/src/H5Gloc.c b/src/H5Gloc.c index 57212b7..4e22357 100644 --- a/src/H5Gloc.c +++ b/src/H5Gloc.c @@ -370,7 +370,7 @@ H5G_loc_insert(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc, HDassert(obj_loc); /* "Translate" object location into link object */ - lnk.type = H5G_LINK_HARD; + lnk.type = H5L_LINK_HARD; #ifdef H5_HAVE_GETTIMEOFDAY { struct timeval now_tv; @@ -381,7 +381,7 @@ H5G_loc_insert(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc, #else /* H5_HAVE_GETTIMEOFDAY */ lnk.ctime = HDtime(NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ - lnk.cset = H5T_CSET_ASCII; /* XXX: Allow user to set this */ + lnk.cset = H5F_CRT_DEFAULT_CSET; /* Casting away const OK -QAK */ lnk.name = (char *)name; lnk.u.hard.addr = obj_loc->oloc->addr; @@ -397,7 +397,6 @@ H5G_loc_insert(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc, done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5G_loc_insert() */ - /*------------------------------------------------------------------------- * Function: H5G_loc_exists diff --git a/src/H5Gname.c b/src/H5Gname.c index fdae809..d3e1d12 100644 --- a/src/H5Gname.c +++ b/src/H5Gname.c @@ -814,6 +814,7 @@ H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key) /* Make certain that the source and destination names are full (not relative) paths */ src_path_r = H5RS_dup(names->loc->path->full_path_r); if(*(H5RS_get_str(names->dst_name)) != '/') { + HDassert(names->dst_loc && names->dst_loc->path); /* Create reference counted string for full dst path */ if((dst_path_r = H5G_build_fullpath_refstr_refstr(names->dst_loc->path->full_path_r, names->dst_name)) == NULL) HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build destination path name") @@ -891,6 +892,9 @@ H5G_name_replace(H5G_obj_t type, H5G_loc_t *loc, FUNC_ENTER_NOAPI(H5G_name_replace, FAIL) + /* Check arguments */ + HDassert(loc && loc->path); + /* Check if the object we are manipulating has a path */ if(loc->path->full_path_r) { unsigned search_group = 0; /* Flag to indicate that groups are to be searched */ diff --git a/src/H5Gnode.c b/src/H5Gnode.c index 90ee688..dabb01c 100644 --- a/src/H5Gnode.c +++ b/src/H5Gnode.c @@ -1987,14 +1987,14 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, H5B_ITER_ERROR, "unable to copy object") /* Construct link information for eventual insertion */ - lnk.type = H5G_LINK_HARD; + lnk.type = H5L_LINK_HARD; lnk.u.hard.addr = new_oloc.addr; } /* ( H5F_addr_defined(src_ent->header)) */ else if(H5G_CACHED_SLINK == src_ent->type) { /* it is a soft link */ /* Construct link information for eventual insertion */ - lnk.type = H5G_LINK_SOFT; + lnk.type = H5L_LINK_SOFT; lnk.u.soft.name = H5HL_offset_into(f, heap, src_ent->cache.slink.lval_offset); } /* else if */ else @@ -2011,7 +2011,7 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr, #else /* H5_HAVE_GETTIMEOFDAY */ lnk.ctime = HDtime(NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ - lnk.cset = H5T_CSET_ASCII; /* XXX: Allow user to set this */ + lnk.cset = H5F_CRT_DEFAULT_CSET; /* XXX: Allow user to set this */ /* lnk.name = name; */ /* This will be set in callback */ /* Determine name of source object */ diff --git a/src/H5Gobj.c b/src/H5Gobj.c index 88b8cdf..7b18469 100644 --- a/src/H5Gobj.c +++ b/src/H5Gobj.c @@ -33,6 +33,7 @@ #include "H5Gpkg.h" /* Groups */ #include "H5HLprivate.h" /* Local Heaps */ #include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ /* Private typedefs */ @@ -113,7 +114,7 @@ H5G_obj_create(H5F_t *f, hid_t dxpl_id, ginfo_size = H5O_mesg_size(H5O_GINFO_ID, f, ginfo); HDassert(ginfo_size); - lnk.type = H5G_LINK_HARD; + lnk.type = H5L_LINK_HARD; lnk.name = &null_char; link_size = H5O_mesg_size(H5O_LINK_ID, f, &lnk); HDassert(link_size); @@ -776,7 +777,7 @@ H5G_obj_remove(H5O_loc_t *oloc, const char *name, H5G_obj_t *obj_type, hid_t dxp /* Release memory for link names (and memory for soft link values) */ for(u = 0; u < linfo.nlinks; u++) { H5MM_xfree(lnk_table[u].name); - if(lnk_table[u].type == H5G_LINK_SOFT) + if(lnk_table[u].type == H5L_LINK_SOFT) H5MM_xfree(lnk_table[u].u.soft.name); } /* end for */ diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h index 98e3516..b0d51d2 100644 --- a/src/H5Gpkg.h +++ b/src/H5Gpkg.h @@ -245,7 +245,7 @@ typedef struct { } H5G_linkvalue_soft_t; typedef struct { - H5G_link_t type; /* Type of link */ + H5L_link_t type; /* Type of link */ union { H5G_linkvalue_hard_t hard; /* Information for hard link */ H5G_linkvalue_soft_t soft; /* Information for soft link */ @@ -273,6 +273,7 @@ H5_DLLVAR const H5AC_class_t H5AC_SNODE[1]; /* * Utility functions */ +H5_DLL char * H5G_normalize(const char *name); H5_DLL H5G_t *H5G_rootof(H5F_t *f); H5_DLL const char * H5G_component(const char *name, size_t *size_p); H5_DLL herr_t H5G_traverse_term_interface(void); @@ -319,6 +320,8 @@ H5_DLL herr_t H5G_ent_convert(H5F_t *f, haddr_t heap_addr, const char *name, H5_DLL herr_t H5G_ent_debug(H5F_t *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * stream, int indent, int fwidth, haddr_t heap); +struct H5HL_t; /* defined in H5HLprivate.h */ + /* Functions that understand symbol table nodes */ H5_DLL herr_t H5G_node_init(H5F_t *f); H5_DLL int H5G_node_iterate (H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr, diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index e498671..c1d3320 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -74,21 +74,15 @@ H5G_CRT_GINFO_EST_NUM_ENTRIES, \ H5G_CRT_GINFO_EST_NAME_LEN} -/* Definitions for creating intermediate groups */ -#define H5G_CRT_INTERMEDIATE_GROUP_NAME "intermediate_group" -#define H5G_CRT_INTERMEDIATE_GROUP_SIZE sizeof(unsigned) -#define H5G_CRT_INTERMEDIATE_GROUP_DEF 0 - /* definitions for copying objects */ #define H5G_CPY_OPTION_NAME "copy object" #define H5G_CPY_OPTION_SIZE sizeof(unsigned) #define H5G_CPY_OPTION_DEF 0 - /* Type of operation being performed for call to H5G_name_replace() */ typedef enum { H5G_NAME_MOVE = 0, /* H5*move call */ - H5G_NAME_UNLINK, /* H5Gunlink call */ + H5G_NAME_UNLINK, /* H5Lunlink call */ H5G_NAME_MOUNT, /* H5Fmount call */ H5G_NAME_UNMOUNT /* H5Funmount call */ } H5G_names_op_t; @@ -128,8 +122,6 @@ H5_DLL H5F_t *H5G_fileof(H5G_t *grp); H5_DLL herr_t H5G_free(H5G_t *grp); H5_DLL H5G_t *H5G_open(H5G_loc_t *loc, hid_t dxpl_id); H5_DLL herr_t H5G_close(H5G_t *grp); -H5_DLL herr_t H5G_insert(H5G_loc_t *loc, const char *name, - H5G_loc_t *obj_loc, hid_t dxpl_id, struct H5P_genplist_t *oc_plist); H5_DLL herr_t H5G_get_objinfo(const H5G_loc_t *loc, const char *name, hbool_t follow_link, H5G_stat_t *statbuf/*out*/, hid_t dxpl_id); H5_DLL H5F_t *H5G_insertion_file(H5G_loc_t *loc, const char *name, hid_t dxpl_id); diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index 9300e8d..a1583c9 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -31,6 +31,7 @@ #include "H5public.h" #include "H5Ipublic.h" +#include "H5Lpublic.h" #include "H5Opublic.h" #include "H5Tpublic.h" @@ -38,13 +39,6 @@ extern "C" { #endif -/* Types of links */ -typedef enum H5G_link_t { - H5G_LINK_ERROR = -1, - H5G_LINK_HARD = 0, - H5G_LINK_SOFT = 1 -} H5G_link_t; - /* * An object has a certain type. The first few numbers are reserved for use * internally by HDF5. Users may add their own types with higher values. The @@ -105,17 +99,10 @@ typedef struct H5G_stat_t { } H5G_stat_t; #endif /* QAK */ -#define H5G_SAME_LOC 0 -#define H5Glink(cur_loc_id, type, cur_name, new_name) \ - H5Glink2(cur_loc_id, cur_name, type, H5G_SAME_LOC, new_name) -#define H5Gmove(src_loc_id, src_name, dst_name) \ - H5Gmove2(src_loc_id, src_name, H5G_SAME_LOC, dst_name) - typedef herr_t (*H5G_iterate_t)(hid_t group, const char *name, void *op_data); /* Flags for object copy (H5Gcopy) */ -#define H5G_COPY_CREATE_INTERMEDIATE_GROUP_FLAG (0x0001u) /* Create missing groups when create a group */ #define H5G_COPY_SHALLOW_HIERARCHY_FLAG (0x0002u) /* Copy only immediate members */ #define H5G_COPY_EXPAND_SOFT_LINK_FLAG (0x0004u) /* Expand soft links into new objects */ #define H5G_COPY_EXPAND_EXT_LINK_FLAG (0x0008u) /* Expand external links into new objects */ @@ -131,26 +118,41 @@ H5_DLL herr_t H5Giterate(hid_t loc_id, const char *name, int *idx, H5_DLL herr_t H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs); H5_DLL ssize_t H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char* name, size_t size); H5_DLL H5G_obj_t H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx); -H5_DLL herr_t H5Gmove2(hid_t src_loc, const char *src, hid_t dst_loc, - const char *dst); -H5_DLL herr_t H5Glink2(hid_t src_loc, const char *cur_name, H5G_link_t type, - hid_t dst_loc, const char *new_name); -H5_DLL herr_t H5Gunlink(hid_t loc_id, const char *name); H5_DLL herr_t H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link, H5G_stat_t *statbuf/*out*/); -H5_DLL herr_t H5Gget_linkval(hid_t loc_id, const char *name, size_t size, - char *buf/*out*/); 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); #ifdef H5_GROUP_REVISION -H5_DLL hid_t H5Gcreate_expand(hid_t loc_id, const char *name, hid_t gcpl_id, +H5_DLL hid_t H5Gcreate_expand(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id); H5_DLL hid_t H5Gget_create_plist(hid_t group_id); #endif /* H5_GROUP_REVISION */ 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 plist_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. + * Use of these functions and variables is depreciated. + */ +H5_DLL herr_t H5Glink(hid_t cur_loc_id, H5L_link_t type, + const char *cur_name, const char *new_name); +H5_DLL herr_t H5Gmove(hid_t src_loc_id, const char *src_name, + const char *dst_name); +H5_DLL herr_t H5Glink2(hid_t cur_loc_id, const char *cur_name, + H5L_link_t type, hid_t new_loc_id, const char *new_name); +H5_DLL herr_t H5Gmove2(hid_t src_loc_id, const char *src_name, + hid_t dst_loc_id, const char *dst_name); +H5_DLL herr_t H5Gunlink(hid_t loc_id, const char *name); +H5_DLL herr_t H5Gget_linkval(hid_t loc_id, const char *name, + size_t size, char *buf/*out*/); + +#define H5G_LINK_ERROR H5L_LINK_ERROR +#define H5G_LINK_HARD H5L_LINK_HARD +#define H5G_LINK_SOFT H5L_LINK_SOFT +#define H5G_link_t H5L_link_t +#define H5G_SAME_LOC H5L_SAME_LOC #ifdef __cplusplus } diff --git a/src/H5Gstab.c b/src/H5Gstab.c index 3491f51..651ddf3 100644 --- a/src/H5Gstab.c +++ b/src/H5Gstab.c @@ -604,7 +604,7 @@ H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata) /* Set link info */ if(udata->lnk) { /* Set (default) common info for link */ - udata->lnk->cset = H5T_CSET_ASCII; + udata->lnk->cset = H5F_CRT_DEFAULT_CSET; udata->lnk->ctime = 0; udata->lnk->name = H5MM_xstrdup(udata->name); @@ -627,14 +627,14 @@ H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata) HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value") /* Set link type */ - udata->lnk->type = H5G_LINK_SOFT; + udata->lnk->type = H5L_LINK_SOFT; } /* end if */ else { /* Set address of object */ udata->lnk->u.hard.addr = ent->header; /* Set link type */ - udata->lnk->type = H5G_LINK_HARD; + udata->lnk->type = H5L_LINK_HARD; } /* end else */ } /* end if */ diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c index 1df90d1..c94cd86 100644 --- a/src/H5Gtraverse.c +++ b/src/H5Gtraverse.c @@ -32,7 +32,9 @@ #include "H5Fpkg.h" /* File access */ #include "H5Gpkg.h" /* Groups */ #include "H5HLprivate.h" /* Local Heaps */ +#include "H5Lprivate.h" /* Links */ #include "H5MMprivate.h" /* Memory management */ +#include "H5Ppublic.h" /* Property Lists */ /* Private typedefs */ @@ -163,7 +165,7 @@ H5G_traverse_slink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk, /* Sanity check */ HDassert(grp_loc); HDassert(lnk); - HDassert(lnk->type == H5G_LINK_SOFT); + HDassert(lnk->type == H5L_LINK_SOFT); HDassert(nlinks); /* Set up temporary location */ @@ -423,7 +425,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Set the object location, if it's a hard link set the address also */ obj_loc.oloc->file = grp_loc.oloc->file; - if(lnk.type == H5G_LINK_HARD) + if(lnk.type == H5L_LINK_HARD) obj_loc.oloc->addr = lnk.u.hard.addr; obj_loc_valid = TRUE; @@ -432,7 +434,7 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, * is the last component of the name and the H5G_TARGET_SLINK bit of * TARGET is set then we don't follow it. */ - if(H5G_LINK_SOFT == lnk.type && + if(H5L_LINK_SOFT == lnk.type && (0 == (target & H5G_TARGET_SLINK) || !last_comp)) { if((*nlinks)-- <= 0) HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "too many links") @@ -506,7 +508,6 @@ H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target, /* Insert new group into current group's symbol table */ if(H5G_loc_insert(&grp_loc, H5G_comp_g, &obj_loc, TRUE, dxpl_id) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert intermediate group") - /* Close new group */ if(H5O_close(obj_loc.oloc) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close") @@ -152,7 +152,7 @@ HDfprintf(stderr, "%s: hdr->id_len = %Zu\n", FUNC, hdr->id_len); hdr = NULL; /* Add heap to list of open objects in file */ - if(H5FO_insert(f, fh->hdr->heap_addr, fh) < 0) + if(H5FO_insert(f, fh->hdr->heap_addr, fh, FALSE) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert heap into list of open objects") /* Set open object count */ @@ -228,7 +228,7 @@ HDfprintf(stderr, "%s: hdr->rc = %u\n", FUNC, hdr->rc); HGOTO_ERROR(H5E_HEAP, H5E_CANTINC, NULL, "can't increment reference count on shared heap header") /* Add heap to list of open objects in file */ - if(H5FO_insert(f, fh->hdr->heap_addr, fh) < 0) + if(H5FO_insert(f, fh->hdr->heap_addr, fh, FALSE) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert heap into list of open objects") /* Set open object count */ diff --git a/src/H5L.c b/src/H5L.c new file mode 100644 index 0000000..fe52dc9 --- /dev/null +++ b/src/H5L.c @@ -0,0 +1,1547 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ +#define H5G_PACKAGE /*suppress error about including H5Gpkg */ +#define H5L_PACKAGE /*suppress error about including H5Gpkg */ + +/* Interface initialization */ +#define H5_INTERFACE_INIT_FUNC H5L_init_interface + +#include "H5private.h" /* Generic Functions */ +#include "H5Lpkg.h" /* Links */ +#include "H5Fpkg.h" /* File access */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Iprivate.h" /* IDs */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Oprivate.h" /* File objects */ +#include "H5Dprivate.h" /* Datasets */ +#include "H5Pprivate.h" /* Property lists */ +#include "H5Gpkg.h" /* Groups */ + +/* Local typedefs */ +#define H5L_MOVE_OP 1 +#define H5L_RENAME_OP 2 + +/* User data for path traversal routine for getting link metadata */ +typedef struct { + H5L_linkinfo_t *linfo; /* Buffer to return to user */ + hid_t dxpl_id; /* dxpl to use in callback */ +} H5L_trav_ud1_t; + +/* User data for path traversal callback to creating a link */ +typedef struct { + H5F_t *file; /* Pointer to the file */ + hid_t dxpl_id; /* Dataset transfer property list */ + H5G_name_t *path; /* Path to object being linked */ + H5O_link_t *lnk; /* Pointer to link information to insert */ +} H5L_trav_ud3_t; + +/* User data for path traversal routine for moving and renaming a link */ +typedef struct { + const char *dst_name; /* Destination name for moving object */ + H5T_cset_t cset; /* Char set for new name */ + H5G_loc_t *dst_loc; /* Destination location for moving object */ + hbool_t copy; /* TRUE if this is a copy operation */ + hid_t dxpl_id; /* dxpl to use in callback */ +} H5L_trav_ud4_t; + +/* User data for path traversal routine for getting soft link value */ +typedef struct { + size_t size; /* Size of user buffer */ + char *buf; /* User buffer */ +} H5L_trav_ud5_t; + +/* User data for path traversal routine for removing link (i.e. unlink) */ +typedef struct { + hid_t dxpl_id; /* Dataset transfer property list */ +} H5L_trav_ud6_t; + +/* User data for path traversal routine for retrieving link creation property list */ +typedef struct { + H5P_genplist_t *lcpl; /* Copy of default property list to be set */ +} H5L_trav_ud8_t; + +/* User data for path traversal routine for moving and renaming an object */ +typedef struct { + H5F_t *file; /* Pointer to the file */ + H5O_link_t *lnk; /* Pointer to link information to insert */ + hid_t dxpl_id; /* Dataset transfer property list */ +} H5L_trav_ud10_t; + +/* Package variables */ + +/* Local variables */ + +/* Private prototypes */ +static herr_t H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5L_create_real(H5G_loc_t *link_loc, const char *link_name, + H5G_name_t *obj_path, H5F_t *obj_file, H5O_link_t *lnk, hid_t dxpl_id, + hid_t lcpl_id); +static herr_t H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name, + H5G_loc_t *link_loc, const char *link_name, hid_t dxpl_id, hid_t lcpl_id); +static herr_t H5L_create_soft(const char *target_path, H5G_loc_t *loc, + const char *name, hid_t dxpl_id, hid_t lcpl_id); +static herr_t H5L_linkval_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5L_linkval(H5G_loc_t *loc, const char *name, size_t size, + char *buf/*out*/, hid_t dxpl_id); +static herr_t H5L_unlink_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5L_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id); +static herr_t H5L_move(H5G_loc_t *src_loc, const char *src_name, + H5G_loc_t *dst_loc, const char *dst_name, hbool_t copy_flag, + hid_t lcpl_id, hid_t dxpl_id); +static herr_t H5L_move_rename_cb(H5G_loc_t *grp_loc/*in*/, const char *name, + const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5L_move_rename_dest_cb(H5G_loc_t *grp_loc/*in*/, + const char *name, const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata/*in,out*/); +static herr_t H5L_get_linkinfo(H5G_loc_t *loc, const char *name, + H5L_linkinfo_t *linkbuf/*out*/, hid_t dxpl_id); +static herr_t H5L_get_linfo_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, + const H5O_link_t *lnk, H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/); + + +/*------------------------------------------------------------------------- + * Function: H5L_init_interface + * + * Purpose: Initialize information specific to H5L interface. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Tuesday, January 24, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_init_interface(void) +{ + H5P_genclass_t *crt_pclass; + size_t nprops; /* Number of properties */ + unsigned intmd_group = H5L_CRT_INTERMEDIATE_GROUP_DEF; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_init_interface) + + /* =========Link Creation Property Class Initialization========= */ + /* Register the default attribute creation properties */ + assert(H5P_CLS_LINK_CREATE_g!=(-1)); + + /* Get the pointer to the link creation class */ + if (NULL == (crt_pclass = H5I_object(H5P_CLS_LINK_CREATE_g))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list class") + + /* Get the number of properties in the class */ + if(H5P_get_nprops_pclass(crt_pclass,&nprops,FALSE)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't query number of properties") + + /* Assume that if there are properties in the class, they are the default ones */ + if(nprops==0) { + /* Register create intermediate groups property */ + if(H5P_register(crt_pclass,H5L_CRT_INTERMEDIATE_GROUP_NAME,H5L_CRT_INTERMEDIATE_GROUP_SIZE, + &intmd_group,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + } + + /* Only register the default property list if it hasn't been created yet */ + if(H5P_LST_LINK_CREATE_g==(-1)) { + /* Register the default link creation property list */ + if ((H5P_LST_LINK_CREATE_g = H5P_create_id (crt_pclass))<0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register default property list") + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5L_term_interface + * + * Purpose: Terminate any resources allocated in H5L_init_interface. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Tuesday, January 24, 2006 + * + *------------------------------------------------------------------------- + */ +int +H5L_term_interface(void) +{ + int n=0; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5L_term_interface) + + /* The H5L interface currently has no resources that need to be freed. */ + + FUNC_LEAVE_NOAPI(n) +} + +/*------------------------------------------------------------------------- + * Function: H5Lmove + * + * Purpose: Renames an object within an HDF5 file and moves it to a new + * group using H5Lrename and H5Lmove. The original name SRC + * is unlinked from the group graph and the inserted with the new + * name DST (which can specify a new path for the object) as an atomic + * operation. The names are interpreted relative to SRC_LOC_ID and + * DST_LOC_ID, which are either file IDs or group ID. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Wednesday, March 29, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lmove(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, + const char *dst_name, hid_t lcpl_id) +{ + H5G_loc_t src_loc, *src_loc_p; + H5G_loc_t dst_loc, *dst_loc_p; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Lmove, FAIL) + H5TRACE5("e","isisi",src_loc_id,src_name,dst_loc_id,dst_name,lcpl_id); + + /* Check arguments */ + if(src_loc_id != H5L_SAME_LOC && H5G_loc(src_loc_id, &src_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(dst_loc_id != H5L_SAME_LOC && H5G_loc(dst_loc_id, &dst_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!src_name || !*src_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified") + if(!dst_name || !*dst_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified") + + /* Set up src & dst location pointers */ + src_loc_p = &src_loc; + dst_loc_p = &dst_loc; + if(src_loc_id == H5L_SAME_LOC && dst_loc_id == H5L_SAME_LOC) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not both be H5L_SAME_LOC") + else if(src_loc_id == H5L_SAME_LOC) + src_loc_p = dst_loc_p; + else if(dst_loc_id == H5L_SAME_LOC) + dst_loc_p = src_loc_p; + + if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") + + if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name, + FALSE, lcpl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to move link") + +done: + FUNC_LEAVE_API(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5Lcopy + * + * Purpose: Creates an identical copy of a link with the same creation + * time and target. The new link can have a different name + * and be in a different location than the original. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Wednesday, March 29, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lcopy(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id, + const char *dst_name, hid_t lcpl_id) +{ + H5G_loc_t src_loc, *src_loc_p; + H5G_loc_t dst_loc, *dst_loc_p; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Lcopy, FAIL) + H5TRACE5("e","isisi",src_loc_id,src_name,dst_loc_id,dst_name,lcpl_id); + + /* Check arguments */ + if(src_loc_id != H5L_SAME_LOC && H5G_loc(src_loc_id, &src_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(dst_loc_id != H5L_SAME_LOC && H5G_loc(dst_loc_id, &dst_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!src_name || !*src_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified") + if(!dst_name || !*dst_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no destination name specified") + + /* Set up src & dst location pointers */ + src_loc_p = &src_loc; + dst_loc_p = &dst_loc; + if(src_loc_id == H5L_SAME_LOC && dst_loc_id == H5L_SAME_LOC) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not both be H5L_SAME_LOC") + else if(src_loc_id == H5L_SAME_LOC) + src_loc_p = dst_loc_p; + else if(dst_loc_id == H5L_SAME_LOC) + dst_loc_p = src_loc_p; + + if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") + + if(H5L_move(src_loc_p, src_name, dst_loc_p, dst_name, TRUE, lcpl_id, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to move link") + +done: + FUNC_LEAVE_API(ret_value) +} + + +/*------------------------------------------------------------------------- + * Function: H5Llink + * + * Purpose: Creates a hard link from NEW_NAME to the object specified + * by OBJ_ID using properties defined in the Link Creation + * Property List LCPL. + * + * This function should be used to link objects that have just + * been created. + * + * CUR_NAME and NEW_NAME are interpreted relative to + * CUR_LOC_ID and NEW_LOC_ID, which is either a file ID or a + * group ID. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Tuesday, December 13, 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Llink(hid_t new_loc_id, const char *new_name, hid_t obj_id, hid_t lcpl_id) +{ + H5G_loc_t new_loc; + H5G_loc_t obj_loc; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Llink, FAIL) + H5TRACE4("e","isii",new_loc_id,new_name,obj_id,lcpl_id); + + /* Check arguments */ + if(new_loc_id == H5L_SAME_LOC) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "cannot use H5L_SAME_LOC when only one location is specified") + if(H5G_loc(new_loc_id, &new_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(H5G_loc(obj_id, &obj_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!new_name || !*new_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + + if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") + + if(H5L_link(&new_loc, new_name, &obj_loc, H5AC_dxpl_id, lcpl_id ) < 0) + HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to create link") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Llink() */ + + +/*------------------------------------------------------------------------- + * Function: H5Lcreate_soft + * + * Purpose: Creates a soft link from NEW_NAME to TARGET_PATH. + * + * TARGET_PATH can be anything and is interpreted at lookup + * time relative to the group which contains the final component + * of NEW_NAME. For instance, if TARGET_PATH is `./foo' and + * NEW_NAME is `./x/y/bar' and a request is made for `./x/y/bar' + * then the actual object looked up is `./x/y/./foo'. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, April 6, 1998 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lcreate_soft(const char *target_path, + hid_t loc_id, const char *name, hid_t lcpl_id) +{ + H5G_loc_t new_loc, *new_loc_p; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Lcreate_soft, FAIL) + H5TRACE4("e","sisi",target_path,loc_id,name,lcpl_id); + + /* Check arguments */ + if(H5G_loc(loc_id, &new_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!target_path || !*target_path) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no target specified") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified") + + if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") + + new_loc_p = &new_loc; + + if(H5L_create_soft(target_path, new_loc_p, name, H5AC_dxpl_id, lcpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to create link") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Lcreate_soft() */ + + +/*------------------------------------------------------------------------- + * Function: H5Lcreate_hard + * + * Purpose: Creates a hard link from NEW_NAME to CUR_NAME. + * + * CUR_NAME must name an existing object. CUR_NAME and + * NEW_NAME are interpreted relative to CUR_LOC_ID and + * NEW_LOC_ID, which are either file IDs or group IDs. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, April 6, 1998 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lcreate_hard(hid_t cur_loc_id, const char *cur_name, + hid_t new_loc_id, const char *new_name, hid_t lcpl_id) +{ + H5G_loc_t cur_loc, *cur_loc_p; + H5G_loc_t new_loc, *new_loc_p; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Lcreate_hard, FAIL) + H5TRACE5("e","isisi",cur_loc_id,cur_name,new_loc_id,new_name,lcpl_id); + + /* Check arguments */ + if(cur_loc_id != H5L_SAME_LOC && H5G_loc(cur_loc_id, &cur_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(new_loc_id != H5L_SAME_LOC && H5G_loc(new_loc_id, &new_loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!cur_name || !*cur_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no current name specified") + if(!new_name || !*new_name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no new name specified") + + if(lcpl_id != H5P_DEFAULT && (TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link creation property list") + + /* Set up current & new location pointers */ + cur_loc_p = &cur_loc; + new_loc_p = &new_loc; + if(cur_loc_id == H5L_SAME_LOC && new_loc_id == H5L_SAME_LOC) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should not be both H5L_SAME_LOC") + else if(cur_loc_id == H5L_SAME_LOC) + cur_loc_p = new_loc_p; + else if(new_loc_id == H5L_SAME_LOC) + new_loc_p = cur_loc_p; + else if(cur_loc_p->oloc->file != new_loc_p->oloc->file) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file.") + + if(H5L_create_hard(cur_loc_p, cur_name, new_loc_p, new_name, H5AC_dxpl_id, lcpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to create link") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Lcreate_hard() */ + + +/*------------------------------------------------------------------------- + * Function: H5Lunlink + * + * Purpose: Removes the specified NAME from the group graph and + * decrements the link count for the object to which NAME + * points. If the link count reaches zero then all file-space + * associated with the object will be reclaimed (but if the + * object is open, then the reclamation of the file space is + * delayed until all handles to the object are closed). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, April 6, 1998 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lunlink(hid_t loc_id, const char *name) +{ + H5G_loc_t loc; + herr_t ret_value=SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Lunlink, FAIL) + H5TRACE2("e","is",loc_id,name); + + /* Check arguments */ + if(H5G_loc(loc_id, &loc) < 0) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name") + + /* Unlink */ + if(H5L_unlink(&loc, name, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to unlink object") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Lunlink() */ + + +/*------------------------------------------------------------------------- + * Function: H5Lget_linkval + * + * Purpose: Returns the link value of a link whose name is NAME. For + * symbolic links, this is the path to which the link points, + * including the null terminator. For user-defined links, it + * is the link buffer. + * + * At most SIZE bytes are copied to the BUF result buffer. + * + * Return: Success: Non-negative with the link value in BUF. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, April 13, 1998 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/) +{ + H5G_loc_t loc; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Lget_linkval, FAIL) + H5TRACE4("e","iszx",loc_id,name,size,buf); + + /* Check arguments */ + if(H5G_loc(loc_id, &loc)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + + /* Get the link value */ + if(H5L_linkval(&loc, name, size, buf, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link value") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Lget_linkval() */ + + +/*------------------------------------------------------------------------- + * Function: H5Lget_linkinfo + * + * Purpose: Gets metadata for a link. + * + * Return: Success: Non-negative with information in LINKBUF + * + * Failure: Negative + * + * Programmer: James Laird + * Wednesday, June 21, 2006 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Lget_linkinfo(hid_t loc_id, const char *name, H5L_linkinfo_t *linkbuf /*out*/) +{ + H5G_loc_t loc; + herr_t ret_value = SUCCEED; + FUNC_ENTER_API(H5Lget_linkinfo, FAIL) + H5TRACE3("e","isx",loc_id,name,linkbuf); + + /* Check arguments */ + if(H5G_loc(loc_id, &loc)) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location") + if(!name || !*name) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified") + + /* Get the creation time */ + if(H5L_get_linkinfo(&loc, name, linkbuf, H5AC_ind_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to get link info") + +done: + FUNC_LEAVE_API(ret_value) +} + + + +/* + *------------------------------------------------------------------------- + *------------------------------------------------------------------------- + * N O A P I F U N C T I O N S B E Y O N D T H I S P O I N T + *------------------------------------------------------------------------- + *------------------------------------------------------------------------- + */ + +/*------------------------------------------------------------------------- + * Function: H5L_link + * + * Purpose: Creates a link from OBJ_ID to CUR_NAME. See H5Llink() for + * full documentation. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Tuesday, December 13, 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5L_link(H5G_loc_t *new_loc, const char *new_name, H5G_loc_t *obj_loc, + hid_t dxpl_id, hid_t lcpl_id) +{ + char *norm_new_name = NULL; /* Pointer to normalized new name */ + H5F_t *file = NULL; /* File link will be in */ + H5O_link_t lnk; /* Link to insert */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_link) + + /* Check args */ + HDassert(new_loc); + HDassert(obj_loc); + HDassert(new_name && *new_name); + + /* Check that the object is not being hard linked into a different file */ + if(NULL == (file = H5G_insertion_file(new_loc, new_name, dxpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to identify insertion file") + if(obj_loc->oloc->file != file) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "cannot link an object from another file") + + /* Construct link information for eventual insertion */ + lnk.type = H5L_LINK_HARD; + lnk.u.hard.addr = obj_loc->oloc->addr; + + /* Create the link */ + if( H5L_create_real(new_loc, new_name, obj_loc->path, obj_loc->oloc->file, &lnk, dxpl_id, lcpl_id) <0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_link() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_link_cb + * + * Purpose: Callback for creating a link to an object. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, September 19, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_link_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/) +{ + H5L_trav_ud3_t *udata = (H5L_trav_ud3_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_link_cb) + + /* Check if the name in this group resolved to a valid location */ + /* (which is not what we want) */ + if(obj_loc != NULL) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name already exists") + + /* Check for crossing file boundaries with a new hard link */ + if(udata->lnk->type == H5L_LINK_HARD) { + /* Check that both objects are in same file */ + if(grp_loc->oloc->file->shared != udata->file->shared) + HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "interfile hard links are not allowed") + } /* end if */ + + /* Set the link's name correctly */ + /* Casting away const OK -QAK */ + udata->lnk->name = name; + + /* Insert link into group */ + if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, (hbool_t)(udata->lnk->type == H5L_LINK_HARD ? TRUE : FALSE), udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object") + + /* Set object's path if it has been passed in and is not set */ + if(udata->path != NULL && udata->path->user_path_r == NULL) + { + if(H5G_name_set(grp_loc->path, udata->path, name) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot set name") + } + +done: + if(ret_value < 0) { + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_link_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_create_real + * + * Purpose: Creates a link at a path location + * + * lnk should have linkclass-specific information already + * set, but this function will take care of setting + * creation time and name. + * + * obj_path can be NULL if the object's path doesn't need to + * be set, and obj_file can be NULL if the object is not a + * hard link. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, December 5, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_create_real(H5G_loc_t *link_loc, const char *link_name, H5G_name_t *obj_path, + H5F_t *obj_file, H5O_link_t *lnk, hid_t dxpl_id, hid_t lcpl_id) +{ + char *norm_link_name = NULL; /* Pointer to normalized link name */ + unsigned target_flags = H5G_TARGET_NORMAL; /* Flags to pass to group traversal function */ + H5T_cset_t char_encoding = H5F_CRT_DEFAULT_CSET; /* Character encoding for link */ + H5P_genplist_t* lc_plist; /* Link creation property list */ + H5L_trav_ud3_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_create_real) + + /* Check args */ + HDassert(link_loc); + HDassert(link_name && *link_name); + HDassert(lnk); + + /* Get normalized link name */ + if((norm_link_name = H5G_normalize(link_name)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") + + /* Check for flags present in creation property list */ + if(lcpl_id != H5P_DEFAULT) + { + unsigned crt_intmd_group; + + if(NULL == (lc_plist = H5I_object(lcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + /* Get intermediate group creation property */ + if(H5P_get(lc_plist, H5L_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for creating missing groups") + + if (crt_intmd_group > 0) + target_flags |= H5G_CRT_INTMD_GROUP; + + /* Get character encoding property */ + if(H5P_get(lc_plist, H5P_CHAR_ENCODING_NAME, &char_encoding) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for character encoding") + } /* end if */ + + /* Fill in common data for the link struct */ + lnk->cset = char_encoding; +#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 */ + + /* Set up user data + * file is used to make sure that hard links don't cross files, and + * should be NULL for other link types. + * lnk is the link struct passed into this function. At this point all + * of its fields should be populated except for name, which is set when + * inserting it in the callback. + * dxpl_id is the dxpl ID that needs to be used during writes and reads. + * path is a pointer to the path of the object being inserted if this is + * a hard link; this is used to set the paths to objects when they are + * created. For other link types, this is NULL. + */ + udata.file = obj_file; + udata.lnk = lnk; + udata.dxpl_id = dxpl_id; + udata.path = obj_path; + + /* Traverse the destination path & create new link */ + if(H5G_traverse(link_loc, link_name, target_flags, H5L_link_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert link") + +done: + /* Free the normalized path name */ + if(norm_link_name) + H5MM_xfree(norm_link_name); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_create_real() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_create_hard + * + * Purpose: Creates a hard link from NEW_NAME to CUR_NAME. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, April 6, 1998 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_create_hard(H5G_loc_t *cur_loc, const char *cur_name, + H5G_loc_t *link_loc, const char *link_name, hid_t dxpl_id, hid_t lcpl_id) +{ + char *norm_cur_name = NULL; /* Pointer to normalized current name */ + H5F_t *link_file = NULL; /* Pointer to file to link to */ + H5O_link_t lnk; /* Link to insert */ + H5O_loc_t obj_oloc; /* Location of object to link to */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_create_hard) + + /* Check args */ + HDassert(cur_loc); + HDassert(link_loc); + HDassert(cur_name && *cur_name); + HDassert(link_name && *link_name); + + /* Get normalized copy of the current name */ + if((norm_cur_name = H5G_normalize(cur_name)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") + + /* Set up link data specific to hard links */ + lnk.type = H5L_LINK_HARD; + + /* Get object location for object pointed to */ + if(H5G_obj_find(cur_loc, norm_cur_name, H5G_TARGET_NORMAL, NULL, &obj_oloc, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found") + + /* Construct link information for eventual insertion */ + lnk.u.hard.addr = obj_oloc.addr; + + /* Set destination's file information */ + link_file = obj_oloc.file; + + /* Create actual link to the object. Pass in NULL for the path, since this + * function shouldn't change an object's user path. */ + if(H5L_create_real(link_loc, link_name, NULL, link_file, &lnk, dxpl_id, lcpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object") + +done: + /* Free the normalized path name */ + if(norm_cur_name) + H5MM_xfree(norm_cur_name); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_create_hard() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_create_soft + * + * Purpose: Creates a soft link from NEW_NAME to CUR_NAME. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Monday, April 6, 1998 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_create_soft( const char *target_path, H5G_loc_t *link_loc, + const char *link_name, hid_t dxpl_id, hid_t lcpl_id) +{ + char *norm_target = NULL; /* Pointer to normalized current name */ + H5O_link_t lnk; /* Link to insert */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_create_soft) + + /* Check args */ + HDassert(link_loc); + HDassert(target_path && *target_path); + HDassert(link_name && *link_name); + + /* Get normalized copy of the link target */ + if((norm_target = H5G_normalize(target_path)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") + + /* Set up link data specific to soft links */ + lnk.type = H5L_LINK_SOFT; + lnk.u.soft.name = norm_target; + + /* Create actual link to the object */ + if(H5L_create_real(link_loc, link_name, NULL, NULL, &lnk, dxpl_id, lcpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object") + +done: + /* Free the normalized target name */ + if(norm_target) + H5MM_xfree(norm_target); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_create_soft() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_linkval_cb + * + * Purpose: Callback for retrieving soft link value for an object. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, September 20, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_linkval_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, + H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/) +{ + H5L_trav_ud5_t *udata = (H5L_trav_ud5_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_linkval_cb) + + /* Check if the name in this group resolved to a valid link */ + if(lnk == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + + if(H5L_LINK_SOFT != lnk->type) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object is not a symbolic link") + + /* Copy to output buffer */ + if(udata->size > 0 && udata->buf) { + HDstrncpy(udata->buf, lnk->u.soft.name, udata->size); + if(HDstrlen(lnk->u.soft.name) >= udata->size) + udata->buf[udata->size - 1] = '\0'; + } /* end if */ + +done: + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_linkval_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_linkval + * + * Purpose: Returns the value of a symbolic link. + * + * Return: Success: Non-negative, with at most SIZE bytes of the + * link value copied into the BUF buffer. If the + * link value is larger than SIZE characters + * counting the null terminator then the BUF + * result will not be null terminated. + * + * Failure: Negative + * + * Programmer: Robb Matzke + * Monday, April 13, 1998 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_linkval(H5G_loc_t *loc, const char *name, size_t size, char *buf/*out*/, hid_t dxpl_id) +{ + H5L_trav_ud5_t udata; /* User data for callback */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_linkval) + + /* Set up user data for retrieving information */ + udata.size = size; + udata.buf = buf; + + /* Traverse the group hierarchy to locate the object to get info about */ + if(H5G_traverse(loc, name, H5G_TARGET_SLINK, H5L_linkval_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5L_linkval() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_unlink_cb + * + * Purpose: Callback for unlinking an object. This routine + * deletes the link + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * Monday, September 19, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_unlink_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t UNUSED *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/) +{ + H5L_trav_ud6_t *udata = (H5L_trav_ud6_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_unlink_cb) + + /* Check if the name in this group resolved to a valid link */ + if(obj_loc == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + + /* Check for removing '.' */ + if(lnk == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't delete self") + + /* Remove the link from the group */ + if(H5G_loc_remove(grp_loc, name, obj_loc, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to unlink name from group") + +done: + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_unlink_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_unlink + * + * Purpose: Unlink a name from a group. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Robb Matzke + * Thursday, September 17, 1998 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id) +{ + H5L_trav_ud6_t udata; /* User data for callback */ + char *norm_name = NULL; /* Pointer to normalized name */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_unlink) + + /* Sanity check */ + HDassert(loc); + HDassert(name && *name); + + /* Get normalized copy of the name */ + if((norm_name = H5G_normalize(name)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") + + /* Set up user data for unlink operation */ + udata.dxpl_id = dxpl_id; + + if(H5G_traverse(loc, norm_name, H5G_TARGET_SLINK|H5G_TARGET_MOUNT, H5L_unlink_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") + +done: + /* Free the normalized path name */ + if(norm_name) + H5MM_xfree(norm_name); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_unlink() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_move_rename_dest_cb + * + * Purpose: Second callback for moving and renaming an object. This routine + * inserts a new link into the group returned by the traversal. + * It is called by H5L_move_rename_cb. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Monday, April 3, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_move_rename_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/) +{ + H5L_trav_ud10_t *udata = (H5L_trav_ud10_t *)_udata; /* User data passed in */ + H5RS_str_t *dst_name_r = NULL; /* Ref-counted version of dest name */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_move_rename_dest_cb) + + /* Make sure an object with this name doesn't already exist */ + if(obj_loc != NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "an object with that name already exists") + + /* Check for crossing file boundaries with a new hard link */ + if(udata->lnk->type == H5L_LINK_HARD) { + /* Check that both objects are in same file */ + if(grp_loc->oloc->file->shared != udata->file->shared) + HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "moving a link across files is not allowed") + } /* end if */ + + /* Give the object its new name */ + /* Casting away const okay -JML */ + udata->lnk->name = H5MM_xfree(udata->lnk->name); + udata->lnk->name=name; + + /* Insert the link into the group */ + if(H5G_obj_insert(grp_loc->oloc, name, udata->lnk, (hbool_t)(udata->lnk->type == H5L_LINK_HARD ? TRUE : FALSE), udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object") + +done: + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); + if(dst_name_r) + H5RS_decr(dst_name_r); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_move_dest_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_move_rename_cb + * + * Purpose: Callback for moving and renaming an object. This routine + * replaces the names of open objects with the moved object + * in the path + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Friday, April 3, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_move_rename_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, + H5G_loc_t *obj_loc, void *_udata/*in,out*/) +{ + H5L_trav_ud4_t *udata = (H5L_trav_ud4_t *)_udata; /* User data passed in */ + H5L_trav_ud10_t udata_out; /* User data for H5L_move_dest_cb traversal */ + H5G_obj_t type; /* Type of object being moved */ + H5RS_str_t *dst_name_r = NULL; /* Ref-counted version of dest name */ + char * orig_name = NULL; /* The name of the link in this group */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_move_rename_cb) + + /* Check if the name in this group resolved to a valid link */ + if(obj_loc == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + + /* Check for operations on '.' */ + if(lnk == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "the name of a link must be supplied to move or rename") + + /* Get object type */ + switch(lnk->type) { + case H5L_LINK_HARD: + if(H5G_UNKNOWN == (type = H5O_obj_type(obj_loc->oloc, udata->dxpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object type to move") + break; + + case H5L_LINK_SOFT: + type = H5G_LINK; + break; + + default: + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type") + } /* end switch */ + + /* Set up user data for move_dest_cb */ + if((udata_out.lnk = H5O_link_copy(lnk, NULL, 0)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "unable to copy link to be moved"); + udata_out.lnk->cset = udata->cset; + udata_out.file = grp_loc->oloc->file; + udata_out.dxpl_id = udata->dxpl_id; + + /* Remember the link's original name (in case it's changed by H5G_name_replace) */ + orig_name = H5MM_xstrdup(name); + + /* Insert the link into its new location */ + if(H5G_traverse(udata->dst_loc, udata->dst_name, H5G_TARGET_NORMAL, H5L_move_rename_dest_cb, &udata_out, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link") + + /* If this is a move and not a copy operation, change the object's name and remove the old link */ + if(!udata->copy) + { + /* Fix names up */ + dst_name_r = H5RS_wrap(udata->dst_name); + HDassert(dst_name_r); + if(H5G_name_replace(type, obj_loc, dst_name_r, udata->dst_loc, H5G_NAME_MOVE) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name ") + + /* Remove the old link */ + if(H5G_obj_remove(grp_loc->oloc, orig_name, &type, udata->dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to remove old name") + } + +done: + /* Cleanup */ + if(orig_name) + H5MM_xfree(orig_name); + + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_move_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_move + * + * Purpose: Atomically move and rename or copy a link. + * + * Creates a copy of a link in a new destination with a new name. + * SRC_LOC and SRC_NAME together define the link's original + * location, while DST_LOC and DST_NAME together define its + * final location. + * + * If copy_flag is FALSE, the original link is removed + * (effectively moving the link). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Monday, May 1, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc, + const char *dst_name, hbool_t copy_flag, hid_t lcpl_id, hid_t dxpl_id) +{ + unsigned target_flags = H5G_TARGET_MOUNT|H5G_TARGET_SLINK; /* Flags to pass to group traversal function */ + H5T_cset_t char_encoding = H5F_CRT_DEFAULT_CSET; /* Character encoding for link */ + H5P_genplist_t* lc_plist; /* Link creation property list */ + H5L_trav_ud4_t udata; /* User data for traversal */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_move) + + /* Sanity check */ + HDassert(src_loc); + HDassert(dst_loc); + HDassert(src_name && *src_name); + HDassert(dst_name && *dst_name); + + /* Check for flags present in creation property list */ + if(lcpl_id != H5P_DEFAULT) + { + unsigned crt_intmd_group; + + if(NULL == (lc_plist = H5I_object(lcpl_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") + + /* Get intermediate group creation property */ + if(H5P_get(lc_plist, H5L_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < +0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for creating missing groups") + + if (crt_intmd_group > 0) + target_flags |= H5G_CRT_INTMD_GROUP; + + /* Get character encoding property */ + if(H5P_get(lc_plist, H5P_CHAR_ENCODING_NAME, &char_encoding) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property value for character encoding") + } /* end if */ + + /* Set up user data */ + udata.dst_loc = dst_loc; + udata.dst_name= dst_name; + udata.cset = char_encoding; + udata.copy = copy_flag; + udata.dxpl_id = dxpl_id; + + /* Do the move */ + if(H5G_traverse(src_loc, src_name, H5G_TARGET_MOUNT|H5G_TARGET_SLINK, H5L_move_rename_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to find link") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_move() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_get_lcpl_cb + * + * Purpose: Callback for getting a link's creation property list. This + * routine gets properties from the link and sets them on the + * copy of the default property list passed in. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Friday, January 27, 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_get_lcpl_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, + H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/) +{ + H5L_trav_ud8_t *udata = (H5L_trav_ud8_t *)_udata; /* User data passed in */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_get_lcpl_cb) + + /* Check if the name in this group resolved to a valid link */ + if(lnk == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + + /* Set appropriate character encoding */ + if(H5P_set(udata->lcpl, H5P_CHAR_ENCODING_NAME, &(lnk->cset)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set property value for character encoding") + +done: + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_get_lcpl_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_get_create_plist + * + * Purpose: Returns a copy of the link's creation property list given + * given a link's location and name. + * + * Return: Success: ID of the property list + * + * Failure: Negative + * + * Programmer: James Laird + * Friday, January 27, 2006 + * + *------------------------------------------------------------------------- + */ +hid_t H5L_get_create_plist(H5G_loc_t *loc, const char* name) +{ + H5P_genplist_t *plist; /* Default property list */ + H5P_genplist_t *plist_copy; /* Copy of list to be modified */ + hid_t lcpl_id=-1; + H5L_trav_ud8_t udata; /* User data for traversal */ + char *norm_name = NULL; /* Pointer to normalized name */ + hid_t ret_value; + + FUNC_ENTER_NOAPI(H5L_get_create_plist, FAIL) + + /* Check arguments */ + HDassert(loc); + HDassert(name && *name); + + /* Get normalized copy of the name */ + if((norm_name = H5G_normalize(name)) == NULL) + HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name") + + /* Get copy of default lcpl */ + if (NULL==(plist=H5I_object(H5P_LST_LINK_CREATE_g))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get default LCPL") + if((lcpl_id=H5P_copy_plist(plist)) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "unable to copy attribute creation properties") + if (NULL==(plist_copy=H5I_object(lcpl_id))) + HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get copy of LCPL") + + /* Set up user data */ + udata.lcpl = plist_copy; + + if(H5G_traverse(loc, norm_name, H5G_TARGET_SLINK|H5G_TARGET_MOUNT, H5L_get_lcpl_cb, &udata, H5AC_dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") + + ret_value = lcpl_id; + +done: + /* Free the normalized path name */ + if(norm_name) + H5MM_xfree(norm_name); + /* If we've created a new lcpl, close it */ + if(ret_value <0 && lcpl_id >= 0) + H5P_close(H5I_object(lcpl_id)); + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_get_create_plist */ + + +/*------------------------------------------------------------------------- + * Function: H5L_get_linfo_cb + * + * Purpose: Callback for retrieving a link's metadata + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Monday, April 17 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_get_linfo_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk, + H5G_loc_t UNUSED *obj_loc, void *_udata/*in,out*/) +{ + H5L_trav_ud1_t *udata = (H5L_trav_ud1_t *)_udata; /* User data passed in */ + H5L_linkinfo_t *linfo = udata->linfo; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_get_linfo_cb) + + /* Check if the name in this group resolved to a valid link */ + if(lnk == NULL) + HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist") + + /* Get information from the link */ + linfo->cset = lnk->cset; + linfo->ctime = lnk->ctime; + linfo->linkclass = lnk->type; + + switch(lnk->type) + { + case H5L_LINK_HARD: + linfo->u.objno = lnk->u.hard.addr; + break; + + case H5L_LINK_SOFT: + linfo->u.link_size = HDstrlen(lnk->u.soft.name) + 1; /*count the null terminator*/ + break; + + default: + HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "unknown link type"); + } + +done: + /* Release the group location for the object */ + /* (Group traversal callbacks are responsible for either taking ownership + * of the group location for the object, or freeing it. - QAK) + */ + if(obj_loc) + H5G_loc_free(obj_loc); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5L_get_linfo_cb() */ + + +/*------------------------------------------------------------------------- + * Function: H5L_get_linkinfo + * + * Purpose: Returns metadata about a link. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Monday, April 17 2006 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5L_get_linkinfo(H5G_loc_t *loc, const char *name, H5L_linkinfo_t *linkbuf/*out*/, hid_t dxpl_id) +{ + H5L_trav_ud1_t udata; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5L_get_linkinfo) + + udata.linfo = linkbuf; + udata.dxpl_id = dxpl_id; + + /* Traverse the group hierarchy to locate the object to get info about */ + if(H5G_traverse(loc, name, H5G_TARGET_SLINK, H5L_get_linfo_cb, &udata, dxpl_id) < 0) + HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5L_get_linkinfo() */ + + +/*------------------------------------------------------------------------- + * Function: H5L get_default_lcpl + * + * Purpose: Accessor for the default Link Creation Property List + * + * Return: Success: ID of the deafult lcpl + * + * Failure: Negative + * + * Programmer: James Laird + * Tuesday, July 4, 2006 + * + *------------------------------------------------------------------------- + */ +hid_t +H5L_get_default_lcpl() +{ + hid_t ret_value = FAIL; /* Return value */ + + FUNC_ENTER_NOAPI(H5L_get_default_lcpl, FAIL) + + ret_value = H5P_LINK_CREATE_DEFAULT; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5L_get_default_lcpl */ + diff --git a/src/H5Lpkg.h b/src/H5Lpkg.h new file mode 100644 index 0000000..04a74f4 --- /dev/null +++ b/src/H5Lpkg.h @@ -0,0 +1,36 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Programmer: James Laird <matzke@llnl.gov> + * Friday, December 1, 2005 + * + * Purpose: This file contains declarations which are visible + * only within the H5L package. Source files outside the + * H5L package should include H5Lprivate.h instead. + */ +#ifndef H5L_PACKAGE +#error "Do not include this file outside the H5L package!" +#endif + +#ifndef _H5Lpkg_H +#define _H5Lpkg_H + +/* Get package's private header */ +#include "H5Lprivate.h" + + + +#endif /* _H5Lpkg_H */ + diff --git a/src/H5Lprivate.h b/src/H5Lprivate.h new file mode 100644 index 0000000..02e6fc6 --- /dev/null +++ b/src/H5Lprivate.h @@ -0,0 +1,43 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * This file contains private information about the H5DL module + * for dealing with links in an HDF5 file. + */ +#ifndef _H5Lprivate_H +#define _H5Lprivate_H + +/* Include package's public header */ +#include "H5Lpublic.h" + +/* Private headers needed by this file */ +#include "H5Gprivate.h" +#include "H5Oprivate.h" + +/* Definitions for creating intermediate groups */ +#define H5L_CRT_INTERMEDIATE_GROUP_NAME "intermediate_group" +#define H5L_CRT_INTERMEDIATE_GROUP_SIZE sizeof(unsigned) +#define H5L_CRT_INTERMEDIATE_GROUP_DEF 0 + + +/* Functions that understand link messages */ +/* forward reference for later use */ +struct H5HL_t; /* defined in H5HLprivate.h */ + +H5_DLL herr_t H5L_link(H5G_loc_t *new_loc, const char *new_name, + H5G_loc_t *obj_loc, hid_t dxpl, hid_t lcpl_id); +H5_DLL hid_t H5L_get_default_lcpl(); + +#endif /* _H5Lprivate_H */ diff --git a/src/H5Lpublic.h b/src/H5Lpublic.h new file mode 100644 index 0000000..a922908 --- /dev/null +++ b/src/H5Lpublic.h @@ -0,0 +1,78 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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: H5Lpublic.h + * Dec 1 2005 + * James Laird + * + * Purpose: Public declarations for the H5L package (links) + * + *------------------------------------------------------------------------- + */ +#ifndef _H5Lpublic_H +#define _H5Lpublic_H + +/* Public headers needed by this file */ +#include "H5public.h" +#include "H5Ipublic.h" +#include "H5Tpublic.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Types of links */ +typedef enum H5L_link_t { + H5L_LINK_ERROR = -1, + H5L_LINK_HARD = 0, + H5L_LINK_SOFT = 1 +} H5L_link_t; + +/* Metadata buffer for user query function */ +typedef struct H5L_linkinfo_t { + H5T_cset_t cset; /* Character set of link name */ + time_t ctime; /* Creation time */ + H5L_link_t linkclass; /* Type of link */ + union { + haddr_t objno; /* Data stored in a hard link */ + size_t link_size; /* Size of a soft link */ + } u; +} H5L_linkinfo_t; + +#define H5L_SAME_LOC 0 + +H5_DLL herr_t H5Llink(hid_t cur_loc_id, const char *cur_name, + hid_t obj_id, hid_t lcpl_id); +H5_DLL herr_t H5Lmove(hid_t src_loc, const char *src_name, hid_t dst_loc, + const char *dst_name, hid_t lcpl_id); +H5_DLL herr_t H5Lcopy(hid_t src_loc, const char *src_name, hid_t dst_loc, + const char *dst_name, hid_t lcpl_id); +H5_DLL herr_t H5Lcreate_hard(hid_t cur_loc, const char *cur_name, + hid_t dst_loc, const char *dst_name, hid_t lcpl_id); +H5_DLL herr_t H5Lcreate_soft(const char *target_path, hid_t loc, + const char *name, hid_t lcpl_id); +H5_DLL herr_t H5Lunlink(hid_t loc_id, const char *name); +H5_DLL herr_t H5Lget_linkval(hid_t loc_id, const char *name, size_t size, + char *buf/*out*/); +H5_DLL herr_t H5Lget_linkinfo(hid_t loc_id, const char *name, + H5L_linkinfo_t *linkbuf /*out*/); + + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/src/H5Olink.c b/src/H5Olink.c index c7c00ca..00a2b92 100644 --- a/src/H5Olink.c +++ b/src/H5Olink.c @@ -38,7 +38,6 @@ /* PRIVATE PROTOTYPES */ static void *H5O_link_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p); static herr_t H5O_link_encode(H5F_t *f, uint8_t *p, const void *_mesg); -static void *H5O_link_copy(const void *_mesg, void *_dest, unsigned update_flags); static size_t H5O_link_size(const H5F_t *f, const void *_mesg); static herr_t H5O_link_reset(void *_mesg); static herr_t H5O_link_free(void *_mesg); @@ -76,9 +75,12 @@ const H5O_msg_class_t H5O_MSG_LINK[1] = {{ /* Current version of link information */ #define H5O_LINK_VERSION 1 +#endif /* H5_GROUP_REVISION */ + /* Declare a free list to manage the H5O_link_t struct */ H5FL_DEFINE_STATIC(H5O_link_t); +#ifdef H5_GROUP_REVISION /*------------------------------------------------------------------------- * Function: H5O_link_decode @@ -122,7 +124,7 @@ H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p) /* Get the type of the link */ lnk->type = *p++; - if(lnk->type < H5G_LINK_HARD || lnk->type > H5G_LINK_SOFT) + if(lnk->type < H5L_LINK_HARD || lnk->type > H5L_LINK_SOFT) HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad link type") /* Get the link creation time from the file */ @@ -146,12 +148,12 @@ H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p) /* Get the appropriate information for each type of link */ switch(lnk->type) { - case H5G_LINK_HARD: + case H5L_LINK_HARD: /* Get the address of the object the link points to */ H5F_addr_decode(f, &p, &(lnk->u.hard.addr)); break; - case H5G_LINK_SOFT: + case H5L_LINK_SOFT: /* Get the link value */ UINT16DECODE(p, len) if(len == 0) @@ -176,7 +178,7 @@ done: if(lnk != NULL) { if(lnk->name != NULL) H5MM_xfree(lnk->name); - if(lnk->type == H5G_LINK_SOFT && lnk->u.soft.name != NULL) + if(lnk->type == H5L_LINK_SOFT && lnk->u.soft.name != NULL) H5MM_xfree(lnk->u.soft.name); H5FL_FREE(H5O_link_t, lnk); } /* end if */ @@ -236,12 +238,12 @@ H5O_link_encode(H5F_t *f, uint8_t *p, const void *_mesg) /* Store the appropriate information for each type of link */ switch(lnk->type) { - case H5G_LINK_HARD: + case H5L_LINK_HARD: /* Store the address of the object the link points to */ H5F_addr_encode(f, &p, lnk->u.hard.addr); break; - case H5G_LINK_SOFT: + case H5L_LINK_SOFT: /* Store the link value */ len = (uint16_t)HDstrlen(lnk->u.soft.name); HDassert(len > 0); @@ -251,12 +253,13 @@ H5O_link_encode(H5F_t *f, uint8_t *p, const void *_mesg) break; default: - HDassert((lnk->type == H5G_LINK_HARD) || (lnk->type == H5G_LINK_SOFT)); + HDassert((lnk->type == H5L_LINK_HARD) || (lnk->type == H5L_LINK_SOFT)); break; } /* end switch */ FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_link_encode() */ +#endif /* H5_GROUP_REVISION */ /*------------------------------------------------------------------------- @@ -277,7 +280,7 @@ H5O_link_encode(H5F_t *f, uint8_t *p, const void *_mesg) * *------------------------------------------------------------------------- */ -static void * +void * H5O_link_copy(const void *_mesg, void *_dest, unsigned UNUSED update_flags) { const H5O_link_t *lnk = (const H5O_link_t *) _mesg; @@ -295,7 +298,7 @@ H5O_link_copy(const void *_mesg, void *_dest, unsigned UNUSED update_flags) *dest = *lnk; HDassert(lnk->name); dest->name = H5MM_xstrdup(lnk->name); - if(lnk->type == H5G_LINK_SOFT) + if(lnk->type == H5L_LINK_SOFT) dest->u.soft.name = H5MM_xstrdup(lnk->u.soft.name); /* Set return value */ @@ -306,6 +309,7 @@ done: } /* end H5O_link_copy() */ +#ifdef H5_GROUP_REVISION /*------------------------------------------------------------------------- * Function: H5O_link_size * @@ -341,17 +345,17 @@ H5O_link_size(const H5F_t *f, const void *_mesg) /* Add the appropriate length for each type of link */ switch(lnk->type) { - case H5G_LINK_HARD: + case H5L_LINK_HARD: ret_value += H5F_SIZEOF_ADDR(f); break; - case H5G_LINK_SOFT: + case H5L_LINK_SOFT: ret_value += 2 + /* Link value length */ HDstrlen(lnk->u.soft.name); /* Link value */ break; default: - HDassert((lnk->type == H5G_LINK_HARD) || (lnk->type == H5G_LINK_SOFT)); + HDassert((lnk->type == H5L_LINK_HARD) || (lnk->type == H5L_LINK_SOFT)); break; } /* end switch */ @@ -381,7 +385,7 @@ H5O_link_reset(void *_mesg) if(lnk) { /* Free information for link (but don't free link pointer) */ - if(lnk->type == H5G_LINK_SOFT) + if(lnk->type == H5L_LINK_SOFT) lnk->u.soft.name = H5MM_xfree(lnk->u.soft.name); lnk->name = H5MM_xfree(lnk->name); } /* end if */ @@ -444,7 +448,7 @@ H5O_link_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link) HDassert(lnk); /* Decrement reference count to the object, for hard links */ - if(lnk->type == H5G_LINK_HARD) { + if(lnk->type == H5L_LINK_HARD) { H5O_loc_t oloc; /* Construct object location for object, in order to decrement it's ref count */ @@ -545,12 +549,12 @@ H5O_link_copy_file(H5F_t UNUSED *file_src, void *native_src, H5F_t UNUSED *file_ /* "Deep copy" other information for each kind of link */ switch(link_src->type) { - case H5G_LINK_HARD: + case H5L_LINK_HARD: /* Set link's address undefined here, will be fixed up in "post copy" callback */ link_dst->u.hard.addr = HADDR_UNDEF; break; - case H5G_LINK_SOFT: + case H5L_LINK_SOFT: /* Copy the soft link's value */ if(NULL == (link_dst->u.soft.name = H5MM_xstrdup(link_src->u.soft.name))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") @@ -641,7 +645,7 @@ H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, /* Additional "deep copy" for each kind of link */ switch(link_src->type) { - case H5G_LINK_HARD: + case H5L_LINK_HARD: /* Copy the object pointed to */ { H5O_loc_t src_oloc; /* Temporary object location for source object */ @@ -669,7 +673,7 @@ H5O_link_post_copy_file(const H5O_loc_t *parent_src_oloc, const void *mesg_src, } /* end case */ break; - case H5G_LINK_SOFT: + case H5L_LINK_SOFT: HGOTO_DONE(SUCCEED) break; @@ -715,8 +719,8 @@ H5O_link_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * HDassert(fwidth >= 0); HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, - "Link Type:", (lnk->type == H5G_LINK_HARD ? "Hard" : - (lnk->type == H5G_LINK_SOFT ? "Soft" : "Unknown"))); + "Link Type:", (lnk->type == H5L_LINK_HARD ? "Hard" : + (lnk->type == H5L_LINK_SOFT ? "Soft" : "Unknown"))); tm = HDlocaltime(&(lnk->ctime)); HDstrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm); @@ -730,12 +734,12 @@ H5O_link_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * "Link Name:", lnk->name); switch(lnk->type) { - case H5G_LINK_HARD: + case H5L_LINK_HARD: HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth, "Object address:", lnk->u.hard.addr); break; - case H5G_LINK_SOFT: + case H5L_LINK_SOFT: HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth, "Link Value:", lnk->u.soft.name); break; diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index 1c4108a..59c2081 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -39,6 +39,7 @@ #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; @@ -153,7 +154,7 @@ typedef struct H5O_link_soft_t { } H5O_link_soft_t; typedef struct H5O_link_t { - H5G_link_t type; /* Type of link */ + H5L_link_t type; /* Type of link */ time_t ctime; /* Time link was createed */ H5T_cset_t cset; /* Character set of link name */ char *name; /* Link name */ @@ -366,6 +367,12 @@ H5_DLL herr_t H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, in int fwidth); /* + * These functions operate on links + */ +H5_DLL void *H5O_link_copy(const void *_mesg, void *_dest, unsigned update_flags); + + +/* * These functions operate on object locations */ H5_DLL herr_t H5O_loc_reset(H5O_loc_t *loc); @@ -56,6 +56,8 @@ hid_t H5P_CLS_DATATYPE_CREATE_g = FAIL; hid_t H5P_CLS_DATATYPE_ACCESS_g = FAIL; hid_t H5P_CLS_ATTRIBUTE_CREATE_g = FAIL; hid_t H5P_CLS_OBJECT_COPY_g = FAIL; +hid_t H5P_CLS_LINK_CREATE_g = FAIL; +hid_t H5P_CLS_STRING_CREATE_g = FAIL; /* * Predefined property lists for each predefined class. These are initialized @@ -74,6 +76,7 @@ hid_t H5P_LST_DATATYPE_CREATE_g = FAIL; hid_t H5P_LST_DATATYPE_ACCESS_g = FAIL; hid_t H5P_LST_ATTRIBUTE_CREATE_g = FAIL; hid_t H5P_LST_OBJECT_COPY_g = FAIL; +hid_t H5P_LST_LINK_CREATE_g = FAIL; /* Track the revision count of a class, to make comparisons faster */ static unsigned H5P_next_rev=0; @@ -238,10 +241,14 @@ H5P_init_interface(void) H5O_ginfo_t ginfo = H5G_CRT_GROUP_INFO_DEF; /* Object creation property class variables. In sequence, they are, * - Creation property list class to modify - * - Default value for "intermediate group creation" */ H5P_genclass_t *ocrt_class; /* Pointer to object (dataset, group, or datatype) creation property list class created */ - unsigned intmd_group = H5G_CRT_INTERMEDIATE_GROUP_DEF; + /* String creation property class variables. In sequence, they are, + * - Creation property list class to modify + * - Default value for "character encoding" + */ + H5P_genclass_t *strcrt_class; /* Pointer to string creation class */ + H5T_cset_t char_encoding = H5P_CHAR_ENCODING_DEF; /* Object copy property class variables. In sequence, they are, * - Copy property list class to modify * - Default value for "object copy parameters" @@ -284,18 +291,6 @@ H5P_init_interface(void) if ((H5P_CLS_OBJECT_CREATE_g = H5I_register (H5I_GENPROP_CLS, ocrt_class))<0) HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class") - /* Get the number of properties in the object class */ - if(H5P_get_nprops_pclass(ocrt_class,&nprops,FALSE)<0) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't query number of properties") - - /* Assume that if there are properties in the class, they are the default ones */ - if(nprops==0) { - /* Register create intermediate groups */ - if(H5P_register(ocrt_class,H5G_CRT_INTERMEDIATE_GROUP_NAME,H5G_CRT_INTERMEDIATE_GROUP_SIZE, - &intmd_group,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") - } /* end if */ - /* Create object copy property class */ /* Allocate the object copy class */ @@ -436,15 +431,49 @@ H5P_init_interface(void) if ((H5P_CLS_DATATYPE_ACCESS_g = H5I_register (H5I_GENPROP_CLS, pclass))<0) HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class"); + /* Create string creation property class + * Objects that contain strings should inherit from this class + * For example, links and attributes have names associated with them. */ + + /* Allocate the string creation class */ + assert(H5P_CLS_STRING_CREATE_g==(-1)); + if (NULL==(strcrt_class = H5P_create_class (root_class,"string create",1,NULL,NULL,NULL,NULL,NULL,NULL))) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed"); + + /* Register the string class */ + if ((H5P_CLS_STRING_CREATE_g = H5I_register (H5I_GENPROP_CLS, strcrt_class))<0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class"); + + /* Get the number of properties in the string class */ + if(H5P_get_nprops_pclass(strcrt_class,&nprops,FALSE)<0) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "can't query number of properties") + + /* Assume that if there are properties in the class, they are the default ones */ + if(nprops==0) { + /* Register character encoding */ + if(H5P_register(strcrt_class,H5P_CHAR_ENCODING_NAME,H5P_CHAR_ENCODING_SIZE, + &char_encoding,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + } /* end if */ + /* Allocate the attribute creation class */ assert(H5P_CLS_ATTRIBUTE_CREATE_g==(-1)); - if (NULL==(pclass = H5P_create_class (ocrt_class,"attribute create",1,NULL,NULL,NULL,NULL,NULL,NULL))) + if (NULL==(pclass = H5P_create_class (strcrt_class,"attribute create",1,NULL,NULL,NULL,NULL,NULL,NULL))) HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed"); /* Register the attribute creation class */ if ((H5P_CLS_ATTRIBUTE_CREATE_g = H5I_register (H5I_GENPROP_CLS, pclass))<0) HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class"); + /* Allocate the link creation class */ + assert(H5P_CLS_LINK_CREATE_g==(-1)); + if (NULL==(pclass = H5P_create_class (strcrt_class,"link create",1,NULL,NULL,NULL,NULL,NULL,NULL))) + HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed"); + + /* Register the link creation class */ + if ((H5P_CLS_LINK_CREATE_g = H5I_register (H5I_GENPROP_CLS, pclass))<0) + HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class"); + done: FUNC_LEAVE_NOAPI(ret_value); } @@ -503,8 +532,10 @@ H5P_term_interface(void) H5P_LST_GROUP_ACCESS_g = H5P_LST_DATATYPE_CREATE_g = H5P_LST_DATATYPE_ACCESS_g = + H5P_CLS_STRING_CREATE_g = H5P_LST_ATTRIBUTE_CREATE_g = H5P_LST_OBJECT_COPY_g = + H5P_LST_LINK_CREATE_g = H5P_LST_MOUNT_g = (-1); } /* end if */ } /* end if */ @@ -526,8 +557,10 @@ H5P_term_interface(void) H5P_CLS_GROUP_ACCESS_g = H5P_CLS_DATATYPE_CREATE_g = H5P_CLS_DATATYPE_ACCESS_g = + H5P_CLS_STRING_CREATE_g = H5P_CLS_ATTRIBUTE_CREATE_g = H5P_CLS_OBJECT_COPY_g = + H5P_CLS_LINK_CREATE_g = H5P_CLS_MOUNT_g = (-1); } /* end if */ } /* end if */ diff --git a/src/H5Pacpl.c b/src/H5Pacpl.c index 7f86def..6374dc0 100644 --- a/src/H5Pacpl.c +++ b/src/H5Pacpl.c @@ -16,88 +16,10 @@ /* Private header files */ #include "H5private.h" /* Generic Functions */ -#include "H5Aprivate.h" /* Datasets */ #include "H5Eprivate.h" /* Error handling */ #include "H5Ppkg.h" /* Property lists */ -#include "H5Tprivate.h" /* Datatypes */ /* Local datatypes */ /* Static function prototypes */ -#ifdef H5_GROUP_REVISION - -/*------------------------------------------------------------------------- - * Function: H5Pset_char_encoding - * - * Purpose: Sets the character encoding of the attribute's name. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: James Laird - * Wednesday, October 26, 2005 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_char_encoding(hid_t plist_id, H5T_cset_t encoding) -{ - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value=SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pset_char_encoding, FAIL); - H5TRACE2("e","iTc",plist_id,encoding); - - /* Check arguments */ - if (encoding <= H5T_CSET_ERROR || encoding >= H5T_NCSET) - HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "character encoding is not valid") - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id,H5P_ATTRIBUTE_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Set the character encoding */ - if(H5P_set(plist, H5A_CHAR_ENCODING_NAME, &encoding) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding") - -done: - FUNC_LEAVE_API(ret_value); -} /* end H5P_set_char_encoding() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pget_char_encoding - * - * Purpose: Gets the character encoding of the attribute's name. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: James Laird - * November 1, 2005 - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_char_encoding(hid_t plist_id, H5T_cset_t *encoding /*out*/) -{ - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value = SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pget_char_encoding, FAIL); - H5TRACE2("e","ix",plist_id,encoding); - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get value */ - if(encoding) - if(H5P_get(plist, H5A_CHAR_ENCODING_NAME, encoding) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get character encoding flag") - -done: - FUNC_LEAVE_API(ret_value); -} /* end H5Pget_create_intermediate_group() */ -#endif /* H5_GROUP_REVISION */ - diff --git a/src/H5Plcpl.c b/src/H5Plcpl.c new file mode 100644 index 0000000..927bfc9 --- /dev/null +++ b/src/H5Plcpl.c @@ -0,0 +1,101 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define H5P_PACKAGE /*suppress error about including H5Ppkg */ + +/* Private header files */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Lprivate.h" /* Links */ +#include "H5Ppkg.h" /* Property lists */ + +/* Local datatypes */ + +/* Static function prototypes */ + +#ifdef H5_GROUP_REVISION + +/*------------------------------------------------------------------------- + * Function: H5Pset_create_intermediate_group + * + * Purpose: set crt_intmd_group so that H5Lcreate(), H5Llink, etc. + * will create missing groups along the given path "name" + * + * Note: XXX: This property should really be an access property. -QAK + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * May 08, 2005 + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_create_intermediate_group(hid_t plist_id, unsigned crt_intmd_group) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Pset_create_intermediate_group, FAIL); + H5TRACE2("e","iIu",plist_id,crt_intmd_group); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set value */ + crt_intmd_group = crt_intmd_group > 0 ? 1 : 0; + if(H5P_set(plist, H5L_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set intermediate group creation flag") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_create_intermediate_group() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_create_intermediate_group + * + * Purpose: Returns the crt_intmd_group, which is set to create missing + * groups during H5Lcreate, etc. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Peter Cao + * May 08, 2005 + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_create_intermediate_group(hid_t plist_id, unsigned *crt_intmd_group /*out*/) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pget_create_intermediate_group, FAIL); + H5TRACE2("e","ix",plist_id,crt_intmd_group); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get values */ + if(crt_intmd_group) + if(H5P_get(plist, H5L_CRT_INTERMEDIATE_GROUP_NAME, crt_intmd_group) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get intermediate group creation flag") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_create_intermediate_group() */ + +#endif /* H5_GROUP_REVISION */ + diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c index 7002b9d..23000f1 100755 --- a/src/H5Pocpl.c +++ b/src/H5Pocpl.c @@ -24,93 +24,6 @@ /* Static function prototypes */ -#ifdef H5_GROUP_REVISION - -/*------------------------------------------------------------------------- - * Function: H5Pset_create_intermediate_group - * - * Purpose: set crt_intmd_group so that H5Gcreate(), H5Dcreate, etc. - * will create missing groups along the given path "name" - * - * Usage: H5Pset_create_intermediate_group(plist_id, crt_intmd_group) - * hid_t plist_id; IN: Property list to create a new group - * unsigned crt_intmd_group; IN: Flag to create intermediate group - * positive value -- to create intermediate group - * otherwise -- do not create intermediate group - * For example, H5Pset_create_intermediate_group(plist_id, 1) to create intermediate group; - * - * Note: XXX: This property should really be an access property. -QAK - * XXX: The property is used only at creation time. It should - * be a creation property. However, the property is not - * saved with the group. In that sense, it should be access - * property. We do not have a good solution for this kind - * of property. For now, it is used as a creation property. - * -PXC - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Peter Cao - * May 08, 2005 - *------------------------------------------------------------------------- - */ -herr_t -H5Pset_create_intermediate_group(hid_t plist_id, unsigned crt_intmd_group) -{ - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_API(H5Pset_create_intermediate_group, FAIL); - H5TRACE2("e","iIu",plist_id,crt_intmd_group); - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Set value */ - crt_intmd_group = crt_intmd_group > 0 ? 1 : 0; - if(H5P_set(plist, H5G_CRT_INTERMEDIATE_GROUP_NAME, &crt_intmd_group) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set intermediate group creation flag") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pset_create_intermediate_group() */ - - -/*------------------------------------------------------------------------- - * Function: H5Pget_create_intermediate_group - * - * Purpose: Returns the crt_intmd_group, which is set at H5Gcreate(hid_t loc_id, - * const char* name, ... ) for create missing groups - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Peter Cao - * May 08, 2005 - *------------------------------------------------------------------------- - */ -herr_t -H5Pget_create_intermediate_group(hid_t plist_id, unsigned *crt_intmd_group /*out*/) -{ - H5P_genplist_t *plist; /* Property list pointer */ - herr_t ret_value = SUCCEED; /* return value */ - - FUNC_ENTER_API(H5Pget_create_intermediate_group, FAIL); - H5TRACE2("e","ix",plist_id,crt_intmd_group); - - /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(plist_id, H5P_OBJECT_CREATE))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") - - /* Get values */ - if(crt_intmd_group) - if(H5P_get(plist, H5G_CRT_INTERMEDIATE_GROUP_NAME, crt_intmd_group) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get intermediate group creation flag") - -done: - FUNC_LEAVE_API(ret_value) -} /* end H5Pget_create_intermediate_group() */ -#endif /* H5_GROUP_REVISION */ - /*------------------------------------------------------------------------- * Function: H5Pset_copy_object diff --git a/src/H5Pprivate.h b/src/H5Pprivate.h index 12b3e93..f81c233 100644 --- a/src/H5Pprivate.h +++ b/src/H5Pprivate.h @@ -25,6 +25,11 @@ #include "H5private.h" /* Generic Functions */ #include "H5Oprivate.h" /* Object headers */ +/* String creation properties */ +#define H5P_CHAR_ENCODING_NAME "character_encoding" +#define H5P_CHAR_ENCODING_SIZE sizeof(H5T_cset_t) +#define H5P_CHAR_ENCODING_DEF H5F_CRT_DEFAULT_CSET + /* Forward declarations for anonymous H5P objects */ typedef struct H5P_genplist_t H5P_genplist_t; typedef struct H5P_genclass_t H5P_genclass_t; diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index d87cc48..b8f5edb 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -92,8 +92,10 @@ typedef herr_t (*H5P_iterate_t)(hid_t id, const char *name, void *iter_data); #define H5P_GROUP_ACCESS (H5OPEN H5P_CLS_GROUP_ACCESS_g) #define H5P_DATATYPE_CREATE (H5OPEN H5P_CLS_DATATYPE_CREATE_g) #define H5P_DATATYPE_ACCESS (H5OPEN H5P_CLS_DATATYPE_ACCESS_g) +#define H5P_STRING_CREATE (H5OPEN H5P_CLS_STRING_CREATE_g) #define H5P_ATTRIBUTE_CREATE (H5OPEN H5P_CLS_ATTRIBUTE_CREATE_g) #define H5P_OBJECT_COPY (H5OPEN H5P_CLS_OBJECT_COPY_g) +#define H5P_LINK_CREATE (H5OPEN H5P_CLS_LINK_CREATE_g) H5_DLLVAR hid_t H5P_CLS_NO_CLASS_g; H5_DLLVAR hid_t H5P_CLS_OBJECT_CREATE_g; H5_DLLVAR hid_t H5P_CLS_FILE_CREATE_g; @@ -106,8 +108,10 @@ H5_DLLVAR hid_t H5P_CLS_GROUP_CREATE_g; H5_DLLVAR hid_t H5P_CLS_GROUP_ACCESS_g; H5_DLLVAR hid_t H5P_CLS_DATATYPE_CREATE_g; H5_DLLVAR hid_t H5P_CLS_DATATYPE_ACCESS_g; +H5_DLLVAR hid_t H5P_CLS_STRING_CREATE_g; H5_DLLVAR hid_t H5P_CLS_ATTRIBUTE_CREATE_g; H5_DLLVAR hid_t H5P_CLS_OBJECT_COPY_g; +H5_DLLVAR hid_t H5P_CLS_LINK_CREATE_g; /* * The library created default property lists @@ -127,8 +131,10 @@ H5_DLLVAR hid_t H5P_CLS_OBJECT_COPY_g; #define H5P_GROUP_ACCESS_DEFAULT (H5OPEN H5P_LST_GROUP_ACCESS_g) #define H5P_DATATYPE_CREATE_DEFAULT (H5OPEN H5P_LST_DATATYPE_CREATE_g) #define H5P_DATATYPE_ACCESS_DEFAULT (H5OPEN H5P_LST_DATATYPE_ACCESS_g) +#define H5P_STRING_CLASS_DEFAULT (H5OPEN H5P_LST_STRING_CLASS_g) #define H5P_ATTRIBUTE_CREATE_DEFAULT (H5OPEN H5P_LST_ATTRIBUTE_CREATE_g) #define H5P_OBJECT_COPY_DEFAULT (H5OPEN H5P_LST_OBJECT_COPY_g) +#define H5P_LINK_CREATE_DEFAULT (H5OPEN H5P_LST_LINK_CREATE_g) H5_DLLVAR hid_t H5P_LST_NO_CLASS_g; H5_DLLVAR hid_t H5P_LST_FILE_CREATE_g; H5_DLLVAR hid_t H5P_LST_FILE_ACCESS_g; @@ -142,6 +148,7 @@ H5_DLLVAR hid_t H5P_LST_DATATYPE_CREATE_g; H5_DLLVAR hid_t H5P_LST_DATATYPE_ACCESS_g; H5_DLLVAR hid_t H5P_LST_ATTRIBUTE_CREATE_g; H5_DLLVAR hid_t H5P_LST_OBJECT_COPY_g; +H5_DLLVAR hid_t H5P_LST_LINK_CREATE_g; /* Public functions */ H5_DLL hid_t H5Pcreate_class(hid_t parent, const char *name, diff --git a/src/H5Pstrcpl.c b/src/H5Pstrcpl.c new file mode 100644 index 0000000..ac13539 --- /dev/null +++ b/src/H5Pstrcpl.c @@ -0,0 +1,101 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +#define H5P_PACKAGE /*suppress error about including H5Ppkg */ + +/* Private header files */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Ppkg.h" /* Property lists */ + +/* Local datatypes */ + +/* Static function prototypes */ + +#ifdef H5_GROUP_REVISION +/*------------------------------------------------------------------------- + * Function: H5Pset_char_encoding + * + * Purpose: Sets the character encoding of the string. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * Wednesday, October 26, 2005 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_char_encoding(hid_t plist_id, H5T_cset_t encoding) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value=SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pset_char_encoding, FAIL); + H5TRACE2("e","iTc",plist_id,encoding); + + /* Check arguments */ + if (encoding <= H5T_CSET_ERROR || encoding >= H5T_NCSET) + HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "character encoding is not valid") + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id,H5P_STRING_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set the character encoding */ + if(H5P_set(plist, H5P_CHAR_ENCODING_NAME, &encoding) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set character encoding") + +done: + FUNC_LEAVE_API(ret_value); +} /* end H5P_set_char_encoding() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_char_encoding + * + * Purpose: Gets the character encoding of the string. + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: James Laird + * November 1, 2005 + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_char_encoding(hid_t plist_id, H5T_cset_t *encoding /*out*/) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pget_char_encoding, FAIL); + H5TRACE2("e","ix",plist_id,encoding); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_STRING_CREATE))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get value */ + if(encoding) + if(H5P_get(plist, H5P_CHAR_ENCODING_NAME, encoding) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get character encoding flag") + +done: + FUNC_LEAVE_API(ret_value); +} /* end H5Pget_char_encoding() */ + +#endif /* H5_GROUP_REVISION */ + @@ -420,7 +420,7 @@ static H5T_t *H5T_decode(const unsigned char *buf); #define H5T_INIT_TYPE_STRING_COMMON { \ H5T_INIT_TYPE_ALLOC_COMMON(H5T_STRING) \ H5T_INIT_TYPE_NUM_COMMON(H5T_ORDER_NONE) \ - dt->shared->u.atomic.u.s.cset = H5T_CSET_ASCII; \ + dt->shared->u.atomic.u.s.cset = H5F_CRT_DEFAULT_CSET; \ } #define H5T_INIT_TYPE_CSTRING_CORE { \ @@ -3104,7 +3104,7 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method) HGOTO_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to reopen named data type"); /* Insert opened named datatype into opened object list for the file */ - if(H5FO_insert(old_dt->oloc.file, old_dt->oloc.addr, new_dt->shared)<0) + if(H5FO_insert(old_dt->oloc.file, old_dt->oloc.addr, new_dt->shared, FALSE)<0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, NULL, "can't insert datatype into list of open objects") /* Increment object count for the object in the top file */ diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c index 5b19201..4c6eb87 100644 --- a/src/H5Tcommit.c +++ b/src/H5Tcommit.c @@ -28,12 +28,13 @@ #include "H5FLprivate.h" /* Free Lists */ #include "H5FOprivate.h" /* File objects */ #include "H5Iprivate.h" /* IDs */ +#include "H5Lprivate.h" /* Links */ #include "H5Oprivate.h" /* Object headers */ #include "H5Pprivate.h" /* Property lists */ #include "H5Tpkg.h" /* Datatypes */ /* Static local functions */ -static herr_t H5T_commit(H5G_loc_t *loc, const char *name, H5T_t *type, +static herr_t H5T_commit(H5F_t *file, H5T_t *type, hid_t dxpl_id, hid_t tcpl_id, hid_t tapl_id); static H5T_t *H5T_open_oid(H5G_loc_t *loc, hid_t dxpl_id); @@ -77,7 +78,11 @@ herr_t H5Tcommit(hid_t loc_id, const char *name, hid_t type_id) { H5G_loc_t loc; + H5G_loc_t type_loc; + H5F_t *file; H5T_t *type = NULL; + hbool_t uncommit = FALSE; /* TRUE if H5T_commit needs to be undone */ + H5T_state_t old_state; /* The state of the datatype before H5T_commit. */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_API(H5Tcommit, FAIL) @@ -91,11 +96,48 @@ H5Tcommit(hid_t loc_id, const char *name, hid_t type_id) if(NULL == (type = H5I_object_verify(type_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") - /* Commit the type */ - if(H5T_commit(&loc, name, type, H5AC_dxpl_id, H5P_DATATYPE_CREATE_DEFAULT, H5P_DEFAULT) < 0) + /* Find the insertion file */ + if(NULL == (file = H5G_insertion_file(&loc, name, H5AC_dxpl_id))) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to find insertion point") + + /* Record the type's state so that we can revert to it if linking fails */ + old_state = type->shared->state; + + /* Write the type to disk */ + if(H5T_commit(file, type, H5AC_dxpl_id, H5P_DATATYPE_CREATE_DEFAULT, H5P_DEFAULT) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype") + if(H5G_loc(type_id, &type_loc) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to get committed datatype's location") + + /* Link the type into the group hierarchy */ + if( H5L_link(&loc, name, &type_loc, H5AC_dxpl_id, H5P_DEFAULT) < 0) + { + uncommit = TRUE; /* Linking failed, and we need to undo H5T_commit. */ + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to create link to type") + } + done: + /* If the datatype was committed but couldn't be linked, we need to return it to the state it was in + * before it was committed. */ + if(TRUE == uncommit) + { + if(type->shared->state == H5T_STATE_OPEN && H5F_addr_defined(type->oloc.addr)) { + /* Remove the datatype from the list of opened objects in the file */ + if(H5FO_top_decr(type->oloc.file, type->oloc.addr) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't decrement count for object") + if(H5FO_delete(type->oloc.file, H5AC_dxpl_id, type->oloc.addr) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't remove dataset from list of open objects") + if(H5O_close(&(type->oloc)) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to release object header") + if(H5O_delete(file, H5AC_dxpl_id, type->oloc.addr) < 0) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDELETE, FAIL, "unable to delete object header") + /* Mark datatype as being back in memory */ + if(H5T_set_loc(type, file, H5T_LOC_MEMORY)) + HDONE_ERROR(H5E_DATATYPE, H5E_CANTDELETE, FAIL, "unable to return datatype to memory") + type->oloc.addr = HADDR_UNDEF; + type->shared->state = old_state; + } /* end if */ } FUNC_LEAVE_API(ret_value) } /* end H5Tcommit() */ @@ -105,8 +147,10 @@ done: * Function: H5Tcommit_expand * * Purpose: Save a transient datatype to a file and turn the type handle - * into a named, immutable type. - * Add property to create missing groups along the path. + * into a "named", immutable type. + * + * The resulting ID should be linked into the file with + * H5Lcreate or it will be deleted when closed. * * Return: Non-negative on success/Negative on failure * @@ -116,20 +160,18 @@ done: *------------------------------------------------------------------------- */ herr_t -H5Tcommit_expand(hid_t loc_id, const char *name, hid_t type_id, hid_t tcpl_id, hid_t tapl_id) +H5Tcommit_expand(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id) { H5G_loc_t loc; H5T_t *type = NULL; herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_API(H5Tcommit_expand, FAIL) - H5TRACE5("e","isiii",loc_id,name,type_id,tcpl_id,tapl_id); + H5TRACE4("e","iiii",loc_id,type_id,tcpl_id,tapl_id); /* Check arguments */ 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") if(NULL == (type = H5I_object_verify(type_id, H5I_DATATYPE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") @@ -150,7 +192,7 @@ H5Tcommit_expand(hid_t loc_id, const char *name, hid_t type_id, hid_t tcpl_id, h #endif /* LATER */ /* Commit the type */ - if(H5T_commit(&loc, name, type, H5AC_dxpl_id, tcpl_id, tapl_id) < 0) + if(H5T_commit(loc.oloc->file, type, H5AC_dxpl_id, tcpl_id, tapl_id) < 0) HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype") done: @@ -173,18 +215,17 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5T_commit(H5G_loc_t *loc, const char *name, H5T_t *type, hid_t dxpl_id, +H5T_commit(H5F_t *file, H5T_t *type, hid_t dxpl_id, hid_t tcpl_id, hid_t UNUSED tapl_id) { - H5F_t *file = NULL; +/* H5F_t *file = NULL; */ H5P_genplist_t *tc_plist; /* Property list created */ H5G_loc_t type_loc; /* Dataset location */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5T_commit) - HDassert(loc); - HDassert(name && *name); + HDassert(file); HDassert(type); HDassert(tcpl_id != H5P_DEFAULT); #ifdef LATER @@ -201,10 +242,6 @@ H5T_commit(H5G_loc_t *loc, const char *name, H5T_t *type, hid_t dxpl_id, if(H5T_STATE_IMMUTABLE == type->shared->state) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is immutable") - /* Find the insertion file */ - if(NULL == (file = H5G_insertion_file(loc, name, dxpl_id))) - HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to find insertion point") - /* Check for a "sensible" datatype to store on disk */ if(H5T_is_sensible(type) <= 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "datatype is not sensible") @@ -232,20 +269,13 @@ H5T_commit(H5G_loc_t *loc, const char *name, H5T_t *type, hid_t dxpl_id, if(NULL == (tc_plist = H5I_object(tcpl_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list") - /* - * Give the datatype a name. That is, create and add a new object to the - * group this datatype is being initially created in. - */ - if(H5G_insert(loc, name, &type_loc, dxpl_id, tc_plist) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to name datatype") - type->shared->state = H5T_STATE_OPEN; type->shared->fo_count=1; /* Add datatype to the list of open objects in the file */ if(H5FO_top_incr(type->oloc.file, type->oloc.addr) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, FAIL, "can't incr object ref. count") - if(H5FO_insert(type->oloc.file, type->oloc.addr, type->shared) < 0) + if(H5FO_insert(type->oloc.file, type->oloc.addr, type->shared, TRUE) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, FAIL, "can't insert datatype into list of open objects") /* Mark datatype as being on memory now. Since this datatype may still be used in memory @@ -470,7 +500,7 @@ H5T_open(H5G_loc_t *loc, hid_t dxpl_id) HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL, "not found") /* Add the datatype to the list of opened objects in the file */ - if(H5FO_insert(dt->oloc.file, dt->oloc.addr, dt->shared) < 0) + if(H5FO_insert(dt->oloc.file, dt->oloc.addr, dt->shared, FALSE) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINSERT, NULL, "can't insert datatype into list of open objects") /* Increment object count for the object in the top file */ diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index a4846dd..51da42a 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -503,9 +503,7 @@ H5_DLL herr_t H5Tclose(hid_t type_id); H5_DLL htri_t H5Tequal(hid_t type1_id, hid_t type2_id); H5_DLL herr_t H5Tlock(hid_t type_id); H5_DLL herr_t H5Tcommit(hid_t loc_id, const char *name, hid_t type_id); -#ifdef H5_GROUP_REVISION -H5_DLL herr_t H5Tcommit_expand(hid_t loc_id, const char *name, hid_t type_id, hid_t tcpl_id, hid_t tapl_id); -#endif /* H5_GROUP_REVISION */ +H5_DLL herr_t H5Tcommit_expand(hid_t loc_id, hid_t type_id, hid_t tcpl_id, hid_t tapl_id); H5_DLL htri_t H5Tcommitted(hid_t type_id); H5_DLL herr_t H5Tencode(hid_t obj_id, void *buf, size_t *nalloc); H5_DLL hid_t H5Tdecode(const void *buf); diff --git a/src/H5err.txt b/src/H5err.txt index 51807f8..7cc1c15 100644 --- a/src/H5err.txt +++ b/src/H5err.txt @@ -188,7 +188,7 @@ MINOR, OHDR, H5E_CANTPACK, Can't pack messages MINOR, GROUP, H5E_CANTOPENOBJ, Can't open object MINOR, GROUP, H5E_CANTCLOSEOBJ, Can't close object MINOR, GROUP, H5E_COMPLEN, Name component is too long -MINOR, GROUP, H5E_LINK, Link count failure +MINOR, GROUP, H5E_LINK, Link failure MINOR, GROUP, H5E_SLINK, Symbolic link error MINOR, GROUP, H5E_PATH, Problem with path to object diff --git a/src/Makefile.am b/src/Makefile.am index 24dd7d9..561d63d 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,37 +42,25 @@ DISTCLEANFILES=H5pubconf.h # library sources libhdf5_la_SOURCES= H5.c H5dbg.c H5A.c H5AC.c H5B.c H5Bcache.c \ H5B2.c H5B2cache.c H5B2dbg.c H5B2int.c H5B2stat.c H5B2test.c \ - H5C.c \ - H5CS.c \ - H5D.c \ - H5Dcompact.c \ - H5Dcontig.c \ + H5C.c H5CS.c H5D.c H5Dcompact.c H5Dcontig.c \ H5Defl.c H5Dio.c H5Distore.c H5Dmpio.c H5Doh.c H5Dselect.c H5Dtest.c \ H5E.c H5F.c \ H5Fdbg.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5FD.c H5FDcore.c \ H5FDfamily.c H5FDlog.c H5FDmpi.c H5FDmpio.c \ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDstdio.c \ - H5FDstream.c H5FL.c H5FO.c \ - H5FS.c H5FScache.c H5FSdbg.c \ - H5G.c H5Gent.c H5Glink.c H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c \ - H5Goh.c \ - H5Gstab.c \ - H5Gtest.c \ - H5Gtraverse.c \ + H5FDstream.c H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c \ + H5G.c H5Gdeprec.c H5Gent.c H5Glink.c H5Gloc.c H5Gname.c H5Gnode.c \ + H5Gobj.c H5Goh.c H5Gstab.c H5Gtest.c H5Gtraverse.c \ H5HF.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \ H5HFhdr.c H5HFiblock.c H5HFint.c H5HFiter.c H5HFsection.c \ H5HFspace.c H5HFstat.c H5HFtest.c \ H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \ - H5MP.c H5MPtest.c \ - H5O.c \ - H5Oattr.c H5Obogus.c H5Ocache.c \ + H5MP.c H5MPtest.c H5L.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \ H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Oginfo.c H5Olayout.c \ - H5Olinfo.c \ - H5Olink.c \ - H5Omtime.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 H5Pgcpl.c \ - H5Pocpl.c H5Ptest.c H5R.c H5RC.c \ + H5Plcpl.c H5Pocpl.c H5Pstrcpl.c H5Ptest.c H5R.c H5RC.c \ H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \ H5Sselect.c H5Stest.c \ H5SL.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \ @@ -90,7 +78,7 @@ include_HEADERS =H5public.h H5Apublic.h H5ACpublic.h \ H5Epubgen.h H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDcore.h H5FDfamily.h \ H5FDlog.h H5FDmpi.h H5FDmpio.h H5FDmpiposix.h \ H5FDmulti.h H5FDsec2.h H5FDstdio.h H5FDstream.h \ - H5Gpublic.h H5Ipublic.h \ + H5Gpublic.h H5Ipublic.h H5Lpublic.h \ H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h H5Spublic.h \ H5Tpublic.h H5Zpublic.h H5pubconf.h hdf5.h H5api_adpt.h diff --git a/src/Makefile.in b/src/Makefile.in index d86dc93..b041080 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -91,26 +91,27 @@ am_libhdf5_la_OBJECTS = H5.lo H5dbg.lo H5A.lo H5AC.lo H5B.lo \ H5FDfamily.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo \ H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDstdio.lo \ H5FDstream.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo H5FSdbg.lo \ - H5G.lo H5Gent.lo H5Glink.lo H5Gloc.lo H5Gname.lo H5Gnode.lo \ - H5Gobj.lo H5Goh.lo H5Gstab.lo H5Gtest.lo H5Gtraverse.lo \ - H5HF.lo H5HFcache.lo H5HFdbg.lo H5HFdblock.lo H5HFdtable.lo \ - H5HFhdr.lo H5HFiblock.lo H5HFint.lo H5HFiter.lo H5HFsection.lo \ - H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HG.lo H5HGdbg.lo \ - H5HL.lo H5HLdbg.lo H5HP.lo H5I.lo H5MF.lo H5MM.lo H5MP.lo \ - H5MPtest.lo H5O.lo H5Oattr.lo H5Obogus.lo H5Ocache.lo \ - H5Ocont.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 \ - H5Pgcpl.lo H5Pocpl.lo H5Ptest.lo H5R.lo H5RC.lo H5RS.lo H5S.lo \ - H5Sall.lo H5Shyper.lo H5Smpio.lo H5Snone.lo H5Spoint.lo \ - H5Sselect.lo H5Stest.lo H5SL.lo H5ST.lo H5T.lo H5Tarray.lo \ - H5Tbit.lo H5Tcommit.lo H5Tcompound.lo H5Tconv.lo H5Tcset.lo \ - H5Tenum.lo H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo \ - H5Tnative.lo H5Toffset.lo H5Toh.lo H5Topaque.lo H5Torder.lo \ - H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo H5Tvlen.lo H5TS.lo H5V.lo \ - H5Z.lo H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \ - H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo + H5G.lo H5Gdeprec.lo H5Gent.lo H5Glink.lo H5Gloc.lo H5Gname.lo \ + H5Gnode.lo H5Gobj.lo H5Goh.lo H5Gstab.lo H5Gtest.lo \ + H5Gtraverse.lo H5HF.lo H5HFcache.lo H5HFdbg.lo H5HFdblock.lo \ + H5HFdtable.lo H5HFhdr.lo H5HFiblock.lo H5HFint.lo H5HFiter.lo \ + H5HFsection.lo H5HFspace.lo H5HFstat.lo H5HFtest.lo H5HG.lo \ + H5HGdbg.lo H5HL.lo H5HLdbg.lo H5HP.lo H5I.lo H5MF.lo H5MM.lo \ + H5MP.lo H5MPtest.lo H5L.lo H5O.lo H5Oattr.lo H5Obogus.lo \ + H5Ocache.lo H5Ocont.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 H5Pgcpl.lo H5Plcpl.lo H5Pocpl.lo H5Pstrcpl.lo \ + H5Ptest.lo H5R.lo H5RC.lo H5RS.lo H5S.lo H5Sall.lo H5Shyper.lo \ + H5Smpio.lo H5Snone.lo H5Spoint.lo H5Sselect.lo H5Stest.lo \ + H5SL.lo H5ST.lo H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo \ + H5Tcompound.lo H5Tconv.lo H5Tcset.lo H5Tenum.lo H5Tfields.lo \ + H5Tfixed.lo H5Tfloat.lo H5Tinit.lo H5Tnative.lo H5Toffset.lo \ + H5Toh.lo H5Topaque.lo H5Torder.lo H5Tpad.lo H5Tprecis.lo \ + H5Tstrpad.lo H5Tvlen.lo H5TS.lo H5V.lo H5Z.lo H5Zdeflate.lo \ + H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo H5Zszip.lo \ + H5Zscaleoffset.lo H5Ztrans.lo libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS) PROGRAMS = $(noinst_PROGRAMS) H5detect_SOURCES = H5detect.c @@ -388,37 +389,25 @@ DISTCLEANFILES = H5pubconf.h # library sources libhdf5_la_SOURCES = H5.c H5dbg.c H5A.c H5AC.c H5B.c H5Bcache.c \ H5B2.c H5B2cache.c H5B2dbg.c H5B2int.c H5B2stat.c H5B2test.c \ - H5C.c \ - H5CS.c \ - H5D.c \ - H5Dcompact.c \ - H5Dcontig.c \ + H5C.c H5CS.c H5D.c H5Dcompact.c H5Dcontig.c \ H5Defl.c H5Dio.c H5Distore.c H5Dmpio.c H5Doh.c H5Dselect.c H5Dtest.c \ H5E.c H5F.c \ H5Fdbg.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5FD.c H5FDcore.c \ H5FDfamily.c H5FDlog.c H5FDmpi.c H5FDmpio.c \ H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDstdio.c \ - H5FDstream.c H5FL.c H5FO.c \ - H5FS.c H5FScache.c H5FSdbg.c \ - H5G.c H5Gent.c H5Glink.c H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c \ - H5Goh.c \ - H5Gstab.c \ - H5Gtest.c \ - H5Gtraverse.c \ + H5FDstream.c H5FL.c H5FO.c H5FS.c H5FScache.c H5FSdbg.c \ + H5G.c H5Gdeprec.c H5Gent.c H5Glink.c H5Gloc.c H5Gname.c H5Gnode.c \ + H5Gobj.c H5Goh.c H5Gstab.c H5Gtest.c H5Gtraverse.c \ H5HF.c H5HFcache.c H5HFdbg.c H5HFdblock.c H5HFdtable.c \ H5HFhdr.c H5HFiblock.c H5HFint.c H5HFiter.c H5HFsection.c \ H5HFspace.c H5HFstat.c H5HFtest.c \ H5HG.c H5HGdbg.c H5HL.c H5HLdbg.c H5HP.c H5I.c H5MF.c H5MM.c \ - H5MP.c H5MPtest.c \ - H5O.c \ - H5Oattr.c H5Obogus.c H5Ocache.c \ + H5MP.c H5MPtest.c H5L.c H5O.c H5Oattr.c H5Obogus.c H5Ocache.c \ H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Oginfo.c H5Olayout.c \ - H5Olinfo.c \ - H5Olink.c \ - H5Omtime.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 H5Pgcpl.c \ - H5Pocpl.c H5Ptest.c H5R.c H5RC.c \ + H5Plcpl.c H5Pocpl.c H5Pstrcpl.c H5Ptest.c H5R.c H5RC.c \ H5RS.c H5S.c H5Sall.c H5Shyper.c H5Smpio.c H5Snone.c H5Spoint.c \ H5Sselect.c H5Stest.c \ H5SL.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \ @@ -436,7 +425,7 @@ include_HEADERS = H5public.h H5Apublic.h H5ACpublic.h \ H5Epubgen.h H5Epublic.h H5Fpublic.h H5FDpublic.h H5FDcore.h H5FDfamily.h \ H5FDlog.h H5FDmpi.h H5FDmpio.h H5FDmpiposix.h \ H5FDmulti.h H5FDsec2.h H5FDstdio.h H5FDstream.h \ - H5Gpublic.h H5Ipublic.h \ + H5Gpublic.h H5Ipublic.h H5Lpublic.h \ H5MMpublic.h H5Opublic.h H5Ppublic.h H5Rpublic.h H5Spublic.h \ H5Tpublic.h H5Zpublic.h H5pubconf.h hdf5.h H5api_adpt.h @@ -606,6 +595,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsfile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fsuper.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5G.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gdeprec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gent.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Glink.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gloc.Plo@am__quote@ @@ -635,6 +625,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HLdbg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HP.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5I.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5L.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MF.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MM.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5MP.Plo@am__quote@ @@ -665,7 +656,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pfapl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pfcpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pgcpl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Plcpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pocpl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Pstrcpl.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ptest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5R.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5RC.Plo@am__quote@ @@ -29,6 +29,7 @@ #include "H5FDpublic.h" /* File drivers */ #include "H5Gpublic.h" /* Groups */ #include "H5Ipublic.h" /* ID management */ +#include "H5Lpublic.h" /* Links */ #include "H5MMpublic.h" /* Memory management */ #include "H5Opublic.h" /* Object headers */ #include "H5Ppublic.h" /* Property lists */ |