summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/H5.c3
-rw-r--r--src/H5A.c627
-rw-r--r--src/H5Apkg.h8
-rw-r--r--src/H5Aprivate.h3
-rw-r--r--src/H5B2.c12
-rw-r--r--src/H5D.c554
-rw-r--r--src/H5Dcontig.c14
-rw-r--r--src/H5Dio.c91
-rw-r--r--src/H5Distore.c50
-rw-r--r--src/H5Dmpio.c10
-rw-r--r--src/H5Dpkg.h3
-rw-r--r--src/H5Dprivate.h7
-rw-r--r--src/H5Edefin.h1
-rw-r--r--src/H5Einit.h5
-rw-r--r--src/H5Epubgen.h2
-rw-r--r--src/H5Eterm.h3
-rw-r--r--src/H5F.c136
-rw-r--r--src/H5FDcore.c3
-rw-r--r--src/H5FDmulti.c2
-rw-r--r--src/H5Fdbg.c17
-rw-r--r--src/H5Fmount.c345
-rw-r--r--src/H5Fpkg.h5
-rw-r--r--src/H5Fprivate.h7
-rw-r--r--src/H5Fsuper.c15
-rw-r--r--src/H5G.c3721
-rw-r--r--src/H5Gent.c319
-rw-r--r--src/H5Glink.c725
-rw-r--r--src/H5Gloc.c469
-rw-r--r--src/H5Gname.c880
-rw-r--r--src/H5Gnode.c561
-rw-r--r--src/H5Gobj.c884
-rw-r--r--src/H5Gpkg.h227
-rw-r--r--src/H5Gprivate.h176
-rw-r--r--src/H5Gpublic.h7
-rw-r--r--src/H5Gstab.c623
-rw-r--r--src/H5Gtest.c185
-rw-r--r--src/H5Gtraverse.c589
-rw-r--r--src/H5HL.c429
-rw-r--r--src/H5HLdbg.c21
-rw-r--r--src/H5HLpkg.h3
-rw-r--r--src/H5HLprivate.h1
-rw-r--r--src/H5I.c211
-rw-r--r--src/H5O.c3172
-rw-r--r--src/H5Oattr.c47
-rw-r--r--src/H5Obogus.c6
-rw-r--r--src/H5Ocache.c554
-rw-r--r--src/H5Ocont.c53
-rw-r--r--src/H5Odtype.c60
-rw-r--r--src/H5Oefl.c5
-rw-r--r--src/H5Ofill.c12
-rw-r--r--src/H5Oginfo.c334
-rw-r--r--src/H5Olayout.c6
-rw-r--r--src/H5Olinfo.c301
-rw-r--r--src/H5Olink.c672
-rw-r--r--src/H5Omtime.c12
-rw-r--r--src/H5Oname.c6
-rw-r--r--src/H5Opkg.h51
-rw-r--r--src/H5Opline.c5
-rw-r--r--src/H5Oprivate.h115
-rw-r--r--src/H5Osdspace.c15
-rw-r--r--src/H5Oshared.c225
-rw-r--r--src/H5Ostab.c91
-rw-r--r--src/H5P.c72
-rw-r--r--src/H5Pgcpl.c194
-rwxr-xr-xsrc/H5Pocpl.c2
-rw-r--r--src/H5Ppublic.h4
-rw-r--r--src/H5R.c452
-rw-r--r--src/H5RS.c64
-rw-r--r--src/H5RSprivate.h1
-rw-r--r--src/H5Rprivate.h7
-rw-r--r--src/H5S.c71
-rw-r--r--src/H5SL.c1
-rw-r--r--src/H5Spkg.h3
-rw-r--r--src/H5Sprivate.h6
-rw-r--r--src/H5Stest.c9
-rw-r--r--src/H5T.c422
-rw-r--r--src/H5Tarray.c5
-rw-r--r--src/H5Tbit.c8
-rw-r--r--src/H5Tcommit.c369
-rw-r--r--src/H5Tconv.c6
-rw-r--r--src/H5Tenum.c5
-rw-r--r--src/H5Tpkg.h17
-rw-r--r--src/H5Tprivate.h15
-rw-r--r--src/H5Tvlen.c5
-rw-r--r--src/H5err.txt1
-rw-r--r--src/H5private.h1
-rwxr-xr-xsrc/Makefile.am12
-rw-r--r--src/Makefile.in32
88 files changed, 12277 insertions, 7203 deletions
diff --git a/src/H5.c b/src/H5.c
index cd4d2a2..3fda450 100644
--- a/src/H5.c
+++ b/src/H5.c
@@ -221,6 +221,9 @@ H5_term_library(void)
pending += DOWN(A);
pending += DOWN(S);
pending += DOWN(T);
+ /* Don't shut down the object header code until objects are shut down */
+ if(pending==0)
+ pending += DOWN(O);
/* Don't shut down the file code until objects in files are shut down */
if(pending==0)
pending += DOWN(F);
diff --git a/src/H5A.c b/src/H5A.c
index 42dcfa2..25d5368 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -28,14 +28,14 @@
#include "H5Sprivate.h" /* Dataspace functions */
/* PRIVATE PROTOTYPES */
-static hid_t H5A_create(const H5G_entry_t *ent, const char *name,
+static hid_t H5A_create(const H5G_loc_t *loc, const char *name,
const H5T_t *type, const H5S_t *space, hid_t dxpl_id);
-static hid_t H5A_open(H5G_entry_t *ent, unsigned idx, hid_t dxpl_id);
+static hid_t H5A_open(H5G_loc_t *loc, unsigned idx, hid_t dxpl_id);
static herr_t H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id);
static herr_t H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id);
-static int H5A_get_index(H5G_entry_t *ent, const char *name, hid_t dxpl_id);
+static int H5A_get_index(H5O_loc_t *loc, const char *name, hid_t dxpl_id);
static hsize_t H5A_get_storage_size(const H5A_t *attr);
-static herr_t H5A_rename(H5G_entry_t *ent, const char *old_name, const char *new_name, hid_t dxpl_id);
+static herr_t H5A_rename(H5O_loc_t *loc, const char *old_name, const char *new_name, hid_t dxpl_id);
/* Object header iterator callbacks */
/* Data structure for callback for locating the index by name */
@@ -70,14 +70,14 @@ DESCRIPTION
static herr_t
H5A_init_interface(void)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5A_init_interface)
/*
* Create attribute group.
*/
- if (H5I_register_type(H5I_ATTR, (size_t)H5I_ATTRID_HASHSIZE, H5A_RESERVED_ATOMS, (H5I_free_t)H5A_close)<H5I_FILE)
+ if(H5I_register_type(H5I_ATTR, (size_t)H5I_ATTRID_HASHSIZE, H5A_RESERVED_ATOMS, (H5I_free_t)H5A_close) < H5I_FILE)
HGOTO_ERROR(H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to initialize interface")
done:
@@ -108,8 +108,8 @@ H5A_term_interface(void)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5A_term_interface)
- if (H5_interface_initialize_g) {
- if ((n=H5I_nmembers(H5I_ATTR))>0) {
+ if(H5_interface_initialize_g) {
+ if((n = H5I_nmembers(H5I_ATTR))>0) {
(void)H5I_clear_type(H5I_ATTR, FALSE);
} else {
(void)H5I_dec_type_ref(H5I_ATTR);
@@ -136,8 +136,6 @@ H5A_term_interface(void)
RETURNS
Non-negative on success/Negative on failure
- ERRORS
-
DESCRIPTION
This function creates an attribute which is attached to the object
specified with 'location_id'. The name specified with 'name' for each
@@ -154,18 +152,14 @@ H5A_term_interface(void)
attribute is reduced to zero.
The location object may be either a group or a dataset, both of
which may have any sort of attribute.
- *
- * Modifications:
- * Robb Matzke, 5 Jun 1998
- * The LOC_ID can also be a committed datatype.
- *
+
--------------------------------------------------------------------------*/
/* ARGSUSED */
hid_t
H5Acreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
hid_t UNUSED plist_id)
{
- H5G_entry_t *ent = NULL;
+ H5G_loc_t loc; /* Object location */
H5T_t *type = NULL;
H5S_t *space = NULL;
hid_t ret_value = FAIL;
@@ -174,20 +168,20 @@ H5Acreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
H5TRACE5("i","isiii",loc_id,name,type_id,space_id,plist_id);
/* check arguments */
- if (H5I_FILE==H5I_get_type(loc_id) || H5I_ATTR==H5I_get_type(loc_id))
+ if(H5I_FILE == H5I_get_type(loc_id) || H5I_ATTR == H5I_get_type(loc_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
- if (NULL==(ent=H5G_loc(loc_id)))
+ if(H5G_loc(loc_id, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
- if (!name || !*name)
+ if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
- if (NULL == (type = H5I_object_verify(type_id, H5I_DATATYPE)))
+ if(NULL == (type = H5I_object_verify(type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a type")
- if (NULL == (space = H5I_object_verify(space_id, H5I_DATASPACE)))
+ if(NULL == (space = H5I_object_verify(space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
/* Go do the real work for attaching the attribute to the dataset */
- if ((ret_value=H5A_create(ent,name,type,space, H5AC_dxpl_id))<0)
- HGOTO_ERROR (H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create attribute")
+ if((ret_value = H5A_create(&loc, name, type, space, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to create attribute")
done:
FUNC_LEAVE_API(ret_value)
@@ -211,16 +205,11 @@ done:
* Programmer: Quincey Koziol
* April 2, 1998
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added a deep copy of the symbol table entry
- *
*-------------------------------------------------------------------------
*/
static hid_t
-H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type,
- const H5S_t *space, hid_t dxpl_id)
+H5A_create(const H5G_loc_t *loc, const char *name, const H5T_t *type,
+ const H5S_t *space, hid_t dxpl_id)
{
H5A_t *attr = NULL;
H5A_iter_cb1 cb; /* Iterator callback */
@@ -229,47 +218,51 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type,
FUNC_ENTER_NOAPI_NOINIT(H5A_create)
/* check args */
- assert(ent);
- assert(name);
- assert(type);
- assert(space);
+ HDassert(loc);
+ HDassert(name);
+ HDassert(type);
+ HDassert(space);
/* Iterate over the existing attributes to check for duplicates */
- cb.name=name;
- cb.idx=(-1);
- if((ret_value=H5O_iterate(ent,H5O_ATTR_ID,H5A_find_idx_by_name,&cb,dxpl_id))<0)
+ cb.name = name;
+ cb.idx = (-1);
+ if((ret_value = H5O_iterate(loc->oloc, H5O_ATTR_ID, H5A_find_idx_by_name, &cb, dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "error iterating over attributes")
- if(ret_value>0)
+ if(ret_value > 0)
HGOTO_ERROR(H5E_ATTR, H5E_ALREADYEXISTS, FAIL, "attribute already exists")
/* Check if the dataspace has an extent set (or is NULL) */
- if( !(H5S_has_extent(space)) )
+ if(!(H5S_has_extent(space)))
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace extent has not been set")
/* Build the attribute information */
- if((attr = H5FL_CALLOC(H5A_t))==NULL)
+ if((attr = H5FL_CALLOC(H5A_t)) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for attribute info")
/* Copy the attribute name */
- attr->name=HDstrdup(name);
+ attr->name = HDstrdup(name);
/* Copy the attribute's datatype */
- attr->dt=H5T_copy(type, H5T_COPY_ALL);
+ attr->dt = H5T_copy(type, H5T_COPY_ALL);
/* Mark any datatypes as being on disk now */
- if (H5T_set_loc(attr->dt, ent->file, H5T_LOC_DISK)<0)
+ if(H5T_set_loc(attr->dt, loc->oloc->file, H5T_LOC_DISK) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
/* Copy the dataspace for the attribute */
- attr->ds=H5S_copy(space, FALSE);
+ attr->ds = H5S_copy(space, FALSE);
/* Mark it initially set to initialized */
attr->initialized = TRUE; /*for now, set to false later*/
- /* Deep copy of the symbol table entry */
- if (H5G_ent_copy(&(attr->ent),ent,H5G_COPY_DEEP)<0)
+ /* Copy the object header information */
+ if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5O_COPY_DEEP) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
+ /* Deep copy of the group hierarchy path */
+ if(H5G_name_copy(&(attr->path), loc->path, H5G_COPY_DEEP) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy path")
+
/* Compute the size of pieces on disk */
if(H5T_committed(attr->dt)) {
H5O_shared_t sh_mesg;
@@ -278,37 +271,37 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type,
HDmemset(&sh_mesg,0,sizeof(H5O_shared_t));
/* Get shared message information for datatype */
- if (H5O_get_share(H5O_DTYPE_ID,attr->ent.file, type, &sh_mesg/*out*/)<0)
+ if(H5O_get_share(H5O_DTYPE_ID, attr->oloc.file, type, &sh_mesg/*out*/) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
/* Compute shared message size for datatype */
- attr->dt_size=H5O_raw_size(H5O_SHARED_ID,attr->ent.file,&sh_mesg);
+ attr->dt_size = H5O_raw_size(H5O_SHARED_ID, attr->oloc.file, &sh_mesg);
} /* end if */
else
- attr->dt_size=H5O_raw_size(H5O_DTYPE_ID,attr->ent.file,type);
- assert(attr->dt_size>0);
- attr->ds_size=H5S_raw_size(attr->ent.file,space);
- assert(attr->ds_size>0);
- H5_ASSIGN_OVERFLOW(attr->data_size,H5S_GET_EXTENT_NPOINTS(attr->ds)*H5T_get_size(attr->dt),hssize_t,size_t);
+ attr->dt_size = H5O_raw_size(H5O_DTYPE_ID, attr->oloc.file, type);
+ HDassert(attr->dt_size > 0);
+ attr->ds_size = H5S_raw_size(attr->oloc.file, space);
+ HDassert(attr->ds_size > 0);
+ H5_ASSIGN_OVERFLOW(attr->data_size, H5S_GET_EXTENT_NPOINTS(attr->ds) * H5T_get_size(attr->dt), hssize_t, size_t);
/* Hold the symbol table entry (and file) open */
- if (H5O_open(&(attr->ent)) < 0)
+ if(H5O_open(&(attr->oloc)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open")
- attr->ent_opened=1;
+ attr->obj_opened = TRUE;
/* Create the attribute message and save the attribute index */
- if (H5O_modify(&(attr->ent), H5O_ATTR_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, attr, dxpl_id) < 0)
+ if(H5O_modify(&(attr->oloc), H5O_ATTR_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, attr, dxpl_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to update attribute header messages")
/* Register the new attribute and get an ID for it */
- if ((ret_value = H5I_register(H5I_ATTR, attr)) < 0)
+ if((ret_value = H5I_register(H5I_ATTR, attr)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
/* Now it's safe to say it's uninitialized */
attr->initialized = FALSE;
done:
- if (ret_value < 0) {
+ if(ret_value < 0) {
if(attr)
(void)H5A_close(attr);
} /* end if */
@@ -330,8 +323,6 @@ done:
RETURNS
Non-negative on success, negative on failure
- ERRORS
-
DESCRIPTION
This function determines if an attribute matches the name to search
for (from the 'op_data') and sets the index value in the 'op_data'.
@@ -353,7 +344,7 @@ H5A_find_idx_by_name(const void *_mesg, unsigned idx, void *_op_data)
* callback info if names are the same.
*/
if(HDstrcmp(mesg->name,op_data->name)==0) {
- op_data->idx=idx;
+ op_data->idx = idx;
ret_value=1;
} /* end if */
else
@@ -370,13 +361,11 @@ H5A_find_idx_by_name(const void *_mesg, unsigned idx, void *_op_data)
Determine the index of an attribute in an object header
USAGE
int H5A_get_index (ent, name)
- H5G_entry_t *ent; IN: Symbol table entry of object
- const char *name; IN: Name of dataset to find
+ H5O_loc_t *loc; IN: Object location
+ const char *name; IN: Name of dataset to find
RETURNS
non-negative on success, negative on failure
- ERRORS
-
DESCRIPTION
This function determines the index of the attribute within an object
header. This is not stored in the attribute structure because it is only
@@ -384,22 +373,22 @@ H5A_find_idx_by_name(const void *_mesg, unsigned idx, void *_op_data)
object header.
--------------------------------------------------------------------------*/
static int
-H5A_get_index(H5G_entry_t *ent, const char *name, hid_t dxpl_id)
+H5A_get_index(H5O_loc_t *loc, const char *name, hid_t dxpl_id)
{
- H5A_iter_cb1 cb; /* Iterator callback */
- int ret_value=FAIL; /* Return value */
+ H5A_iter_cb1 udata; /* Iterator callback info */
+ int ret_value = FAIL; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5A_get_index)
- assert(ent);
- assert(name);
+ HDassert(loc);
+ HDassert(name);
- cb.name=name;
- cb.idx=(-1);
- if((ret_value=H5O_iterate(ent,H5O_ATTR_ID,H5A_find_idx_by_name,&cb,dxpl_id))<0)
+ udata.name = name;
+ udata.idx = (-1);
+ if((ret_value = H5O_iterate(loc, H5O_ATTR_ID, H5A_find_idx_by_name, &udata, dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "error iterating over attributes")
- if(ret_value>0)
- ret_value=cb.idx;
+ if(ret_value > 0)
+ ret_value = udata.idx;
else
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "attribute not found")
@@ -420,8 +409,6 @@ done:
RETURNS
ID of attribute on success, negative on failure
- ERRORS
-
DESCRIPTION
This function opens an existing attribute for access. The attribute
name specified is used to look up the corresponding attribute for the
@@ -429,36 +416,32 @@ done:
H5Aclose or resource leaks will develop.
The location object may be either a group or a dataset, both of
which may have any sort of attribute.
- *
- * Modifications:
- * Robb Matzke, 5 Jun 1998
- * The LOC_ID can also be a named (committed) datatype.
--------------------------------------------------------------------------*/
hid_t
H5Aopen_name(hid_t loc_id, const char *name)
{
- H5G_entry_t *ent = NULL; /*Symtab entry of object to attribute*/
- int idx=0;
+ H5G_loc_t loc; /* Object location */
+ int idx;
hid_t ret_value;
FUNC_ENTER_API(H5Aopen_name, FAIL)
H5TRACE2("i","is",loc_id,name);
/* check arguments */
- if (H5I_FILE==H5I_get_type(loc_id) || H5I_ATTR==H5I_get_type(loc_id))
+ if(H5I_FILE == H5I_get_type(loc_id) || H5I_ATTR == H5I_get_type(loc_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
- if (NULL==(ent=H5G_loc(loc_id)))
+ if(H5G_loc(loc_id, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
- if (!name || !*name)
+ if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
/* Look up the attribute for the object */
- if((idx=H5A_get_index(ent,name, H5AC_dxpl_id))<0)
+ if((idx = H5A_get_index(loc.oloc, name, H5AC_dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "attribute not found")
/* Go do the real work for opening the attribute */
- if ((ret_value=H5A_open(ent, (unsigned)idx, H5AC_dxpl_id))<0)
- HGOTO_ERROR (H5E_ATTR, H5E_CANTINIT, FAIL, "unable to open attribute")
+ if((ret_value = H5A_open(&loc, (unsigned)idx, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to open attribute")
done:
FUNC_LEAVE_API(ret_value)
@@ -477,8 +460,6 @@ done:
RETURNS
ID of attribute on success, negative on failure
- ERRORS
-
DESCRIPTION
This function opens an existing attribute for access. The attribute
index specified is used to look up the corresponding attribute for the
@@ -486,30 +467,25 @@ done:
H5Aclose or resource leaks will develop.
The location object may be either a group or a dataset, both of
which may have any sort of attribute.
- *
- * Modifications:
- * Robb Matzke, 5 Jun 1998
- * The LOC_ID can also be a named (committed) datatype.
- *
--------------------------------------------------------------------------*/
hid_t
H5Aopen_idx(hid_t loc_id, unsigned idx)
{
- H5G_entry_t *ent = NULL; /*Symtab entry of object to attribute */
+ H5G_loc_t loc; /* Object location */
hid_t ret_value;
FUNC_ENTER_API(H5Aopen_idx, FAIL)
H5TRACE2("i","iIu",loc_id,idx);
/* check arguments */
- if (H5I_FILE==H5I_get_type(loc_id) || H5I_ATTR==H5I_get_type(loc_id))
+ if(H5I_FILE == H5I_get_type(loc_id) || H5I_ATTR == H5I_get_type(loc_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
- if (NULL==(ent=H5G_loc(loc_id)))
+ if(H5G_loc(loc_id, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
/* Go do the real work for opening the attribute */
- if ((ret_value=H5A_open(ent, idx, H5AC_dxpl_id))<0)
- HGOTO_ERROR (H5E_ATTR, H5E_CANTINIT, FAIL, "unable to open attribute")
+ if((ret_value = H5A_open(&loc, idx, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to open attribute")
done:
FUNC_LEAVE_API(ret_value)
@@ -531,15 +507,10 @@ done:
* Programmer: Quincey Koziol
* April 2, 1998
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added a deep copy of the symbol table entry
- *
*-------------------------------------------------------------------------
*/
static hid_t
-H5A_open(H5G_entry_t *ent, unsigned idx, hid_t dxpl_id)
+H5A_open(H5G_loc_t *loc, unsigned idx, hid_t dxpl_id)
{
H5A_t *attr = NULL;
hid_t ret_value;
@@ -547,32 +518,36 @@ H5A_open(H5G_entry_t *ent, unsigned idx, hid_t dxpl_id)
FUNC_ENTER_NOAPI_NOINIT(H5A_open)
/* check args */
- assert(ent);
+ HDassert(loc);
/* Read in attribute with H5O_read() */
H5_CHECK_OVERFLOW(idx,unsigned,int);
- if (NULL==(attr=H5O_read(ent, H5O_ATTR_ID, (int)idx, NULL, dxpl_id)))
+ if(NULL == (attr = H5O_read(loc->oloc, H5O_ATTR_ID, (int)idx, NULL, dxpl_id)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to load attribute info from dataset header")
- attr->initialized=1;
+ attr->initialized = TRUE;
/* Deep copy of the symbol table entry */
- if (H5G_ent_copy(&(attr->ent),ent,H5G_COPY_DEEP)<0)
+ if(H5O_loc_copy(&(attr->oloc), loc->oloc, H5O_COPY_DEEP) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
+
+ /* Deep copy of the group hier. path */
+ if(H5G_name_copy(&(attr->path), loc->path, H5G_COPY_DEEP) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
/* Hold the symbol table entry (and file) open */
- if (H5O_open(&(attr->ent)) < 0)
+ if(H5O_open(&(attr->oloc)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, FAIL, "unable to open")
- attr->ent_opened=1;
+ attr->obj_opened = TRUE;
/* Register the new attribute and get an ID for it */
- if ((ret_value = H5I_register(H5I_ATTR, attr)) < 0)
+ if((ret_value = H5I_register(H5I_ATTR, attr)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register attribute for ID")
done:
- if (ret_value < 0) {
+ if(ret_value < 0) {
if(attr)
(void)H5A_close(attr);
- }
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* H5A_open() */
@@ -591,8 +566,6 @@ done:
RETURNS
Non-negative on success/Negative on failure
- ERRORS
-
DESCRIPTION
This function writes a complete attribute to disk.
--------------------------------------------------------------------------*/
@@ -607,15 +580,15 @@ H5Awrite(hid_t attr_id, hid_t type_id, const void *buf)
H5TRACE3("e","iix",attr_id,type_id,buf);
/* check arguments */
- if (NULL == (attr = H5I_object_verify(attr_id, H5I_ATTR)))
+ if(NULL == (attr = H5I_object_verify(attr_id, H5I_ATTR)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
- if (NULL == (mem_type = H5I_object_verify(type_id, H5I_DATATYPE)))
+ if(NULL == (mem_type = H5I_object_verify(type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
- if (NULL == buf)
+ if(NULL == buf)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null attribute buffer")
/* Go write the actual data to the attribute */
- if ((ret_value=H5A_write(attr,mem_type,buf, H5AC_dxpl_id))<0)
+ if((ret_value = H5A_write(attr,mem_type,buf, H5AC_dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute")
done:
@@ -636,8 +609,6 @@ done:
RETURNS
Non-negative on success/Negative on failure
- ERRORS
-
DESCRIPTION
This function writes a complete attribute to disk.
--------------------------------------------------------------------------*/
@@ -658,41 +629,41 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
FUNC_ENTER_NOAPI_NOINIT(H5A_write)
- assert(attr);
- assert(mem_type);
- assert(buf);
+ HDassert(attr);
+ HDassert(mem_type);
+ HDassert(buf);
/* Create buffer for data to store on disk */
- if((snelmts=H5S_GET_EXTENT_NPOINTS(attr->ds))<0)
- HGOTO_ERROR (H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
- H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,size_t);
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->ds)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
+ H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, size_t);
- if(nelmts>0) {
+ if(nelmts > 0) {
/* Get the memory and file datatype sizes */
src_type_size = H5T_get_size(mem_type);
dst_type_size = H5T_get_size(attr->dt);
/* Convert memory buffer into disk buffer */
/* Set up type conversion function */
- if (NULL == (tpath = H5T_path_find(mem_type, attr->dt, NULL, NULL, dxpl_id, FALSE)))
+ if(NULL == (tpath = H5T_path_find(mem_type, attr->dt, NULL, NULL, dxpl_id, FALSE)))
HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes")
/* Check for type conversion required */
- if (!H5T_path_noop(tpath)) {
- if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL)))<0 ||
- (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->dt, H5T_COPY_ALL)))<0)
+ if(!H5T_path_noop(tpath)) {
+ if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL))) < 0 ||
+ (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->dt, H5T_COPY_ALL))) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
/* Get the maximum buffer size needed and allocate it */
- buf_size=nelmts*MAX(src_type_size,dst_type_size);
- if (NULL==(tconv_buf = H5FL_BLK_MALLOC (attr_buf, buf_size)) || NULL==(bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ buf_size = nelmts * MAX(src_type_size, dst_type_size);
+ if(NULL == (tconv_buf = H5FL_BLK_MALLOC (attr_buf, buf_size)) || NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Copy the user's data into the buffer for conversion */
- HDmemcpy(tconv_buf,buf,(src_type_size*nelmts));
+ HDmemcpy(tconv_buf, buf, (src_type_size * nelmts));
/* Perform datatype conversion */
- if (H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id)<0)
+ if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed")
/* Free the previous attribute data buffer, if there is one */
@@ -700,40 +671,40 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, const void *buf, hid_t dxpl_id)
H5FL_BLK_FREE(attr_buf, attr->data);
/* Set the pointer to the attribute data to the converted information */
- attr->data=tconv_buf;
+ attr->data = tconv_buf;
} /* end if */
/* No type conversion necessary */
else {
- HDassert(dst_type_size==src_type_size);
+ HDassert(dst_type_size == src_type_size);
/* Allocate the attribute buffer, if there isn't one */
- if(attr->data==NULL)
- if (NULL==(attr->data = H5FL_BLK_MALLOC(attr_buf, dst_type_size*nelmts)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(attr->data == NULL)
+ if(NULL == (attr->data = H5FL_BLK_MALLOC(attr_buf, dst_type_size * nelmts)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Copy the attribute data into the user's buffer */
- HDmemcpy(attr->data,buf,(dst_type_size*nelmts));
+ HDmemcpy(attr->data, buf, (dst_type_size * nelmts));
} /* end else */
/* Look up the attribute for the object */
- if((idx=H5A_get_index(&(attr->ent),attr->name,dxpl_id))<0)
+ if((idx = H5A_get_index(&(attr->oloc), attr->name, dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_BADVALUE, FAIL, "attribute not found")
/* Modify the attribute data */
- if (H5O_modify(&(attr->ent), H5O_ATTR_ID, idx, 0, H5O_UPDATE_DATA_ONLY|H5O_UPDATE_TIME, attr, dxpl_id) < 0)
+ if(H5O_modify(&(attr->oloc), H5O_ATTR_ID, idx, 0, H5O_UPDATE_DATA_ONLY|H5O_UPDATE_TIME, attr, dxpl_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to update attribute header messages")
} /* end if */
/* Indicate the the attribute doesn't need fill-values */
- attr->initialized=TRUE;
+ attr->initialized = TRUE;
done:
/* Release resources */
- if (src_id >= 0)
+ if(src_id >= 0)
(void)H5I_dec_ref(src_id);
- if (dst_id >= 0)
+ if(dst_id >= 0)
(void)H5I_dec_ref(dst_id);
- if (bkg_buf)
+ if(bkg_buf)
H5FL_BLK_FREE(attr_buf, bkg_buf);
FUNC_LEAVE_NOAPI(ret_value)
@@ -753,8 +724,6 @@ done:
RETURNS
Non-negative on success/Negative on failure
- ERRORS
-
DESCRIPTION
This function reads a complete attribute from disk.
--------------------------------------------------------------------------*/
@@ -769,15 +738,15 @@ H5Aread(hid_t attr_id, hid_t type_id, void *buf)
H5TRACE3("e","iix",attr_id,type_id,buf);
/* check arguments */
- if (NULL == (attr = H5I_object_verify(attr_id, H5I_ATTR)))
+ if(NULL == (attr = H5I_object_verify(attr_id, H5I_ATTR)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
- if (NULL == (mem_type = H5I_object_verify(type_id, H5I_DATATYPE)))
+ if(NULL == (mem_type = H5I_object_verify(type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
- if (NULL == buf)
+ if(NULL == buf)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "null attribute buffer")
/* Go write the actual data to the attribute */
- if ((ret_value=H5A_read(attr,mem_type,buf,H5AC_dxpl_id))<0)
+ if((ret_value = H5A_read(attr,mem_type,buf,H5AC_dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_READERROR, FAIL, "unable to read attribute")
done:
@@ -798,8 +767,6 @@ done:
RETURNS
Non-negative on success/Negative on failure
- ERRORS
-
DESCRIPTION
This function reads a complete attribute from disk.
--------------------------------------------------------------------------*/
@@ -824,8 +791,8 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
assert(buf);
/* Create buffer for data to store on disk */
- if((snelmts=H5S_GET_EXTENT_NPOINTS(attr->ds))<0)
- HGOTO_ERROR (H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
+ if((snelmts = H5S_GET_EXTENT_NPOINTS(attr->ds)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTCOUNT, FAIL, "dataspace is invalid")
H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,size_t);
if(nelmts>0) {
@@ -834,31 +801,31 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
dst_type_size = H5T_get_size(mem_type);
/* Check if the attribute has any data yet, if not, fill with zeroes */
- if(attr->ent_opened && !attr->initialized) {
+ if(attr->obj_opened && !attr->initialized) {
HDmemset(buf,0,(dst_type_size*nelmts));
} /* end if */
else { /* Attribute exists and has a value */
/* Convert memory buffer into disk buffer */
/* Set up type conversion function */
- if (NULL == (tpath = H5T_path_find(attr->dt, mem_type, NULL, NULL, dxpl_id, FALSE)))
+ if(NULL == (tpath = H5T_path_find(attr->dt, mem_type, NULL, NULL, dxpl_id, FALSE)))
HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dst datatypes")
/* Check for type conversion required */
- if (!H5T_path_noop(tpath)) {
- if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->dt, H5T_COPY_ALL)))<0 ||
- (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL)))<0)
+ if(!H5T_path_noop(tpath)) {
+ if((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->dt, H5T_COPY_ALL))) < 0 ||
+ (dst_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL))) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL, "unable to register types for conversion")
/* Get the maximum buffer size needed and allocate it */
- buf_size=nelmts*MAX(src_type_size,dst_type_size);
- if (NULL==(tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)) || NULL==(bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ buf_size = nelmts*MAX(src_type_size,dst_type_size);
+ if(NULL == (tconv_buf = H5FL_BLK_MALLOC(attr_buf, buf_size)) || NULL == (bkg_buf = H5FL_BLK_CALLOC(attr_buf, buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Copy the attribute data into the buffer for conversion */
HDmemcpy(tconv_buf,attr->data,(src_type_size*nelmts));
/* Perform datatype conversion. */
- if (H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id)<0)
+ if(H5T_convert(tpath, src_id, dst_id, nelmts, (size_t)0, (size_t)0, tconv_buf, bkg_buf, dxpl_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "datatype conversion failed")
/* Copy the converted data into the user's buffer */
@@ -866,7 +833,7 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
} /* end if */
/* No type conversion necessary */
else {
- HDassert(dst_type_size==src_type_size);
+ HDassert(dst_type_size == src_type_size);
/* Copy the attribute data into the user's buffer */
HDmemcpy(buf,attr->data,(dst_type_size*nelmts));
@@ -876,13 +843,13 @@ H5A_read(const H5A_t *attr, const H5T_t *mem_type, void *buf, hid_t dxpl_id)
done:
/* Release resources */
- if (src_id >= 0)
+ if(src_id >= 0)
(void)H5I_dec_ref(src_id);
- if (dst_id >= 0)
+ if(dst_id >= 0)
(void)H5I_dec_ref(dst_id);
- if (tconv_buf)
+ if(tconv_buf)
H5FL_BLK_FREE(attr_buf, tconv_buf);
- if (bkg_buf)
+ if(bkg_buf)
H5FL_BLK_FREE(attr_buf, bkg_buf);
FUNC_LEAVE_NOAPI(ret_value)
@@ -900,8 +867,6 @@ done:
RETURNS
A dataspace ID on success, negative on failure
- ERRORS
-
DESCRIPTION
This function retrieves a copy of the dataspace for an attribute.
The dataspace ID returned from this function must be released with H5Sclose
@@ -918,16 +883,16 @@ H5Aget_space(hid_t attr_id)
H5TRACE1("i","i",attr_id);
/* check arguments */
- if (NULL == (attr = H5I_object_verify(attr_id, H5I_ATTR)))
+ if(NULL == (attr = H5I_object_verify(attr_id, H5I_ATTR)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
/* Copy the attribute's dataspace */
- if (NULL==(dst=H5S_copy (attr->ds, FALSE)))
- HGOTO_ERROR (H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy dataspace")
+ if(NULL == (dst = H5S_copy (attr->ds, FALSE)))
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy dataspace")
/* Atomize */
- if ((ret_value=H5I_register (H5I_DATASPACE, dst))<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
+ if((ret_value = H5I_register (H5I_DATASPACE, dst)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
done:
FUNC_LEAVE_API(ret_value)
@@ -945,19 +910,10 @@ done:
RETURNS
A datatype ID on success, negative on failure
- ERRORS
-
DESCRIPTION
This function retrieves a copy of the datatype for an attribute.
The datatype ID returned from this function must be released with H5Tclose
or resource leaks will develop.
- *
- * Modifications:
- * Robb Matzke, 4 Jun 1998
- * The datatype is reopened if it's a named type before returning it to
- * the application. The datatypes returned by this function are always
- * read-only. If an error occurs when atomizing the return datatype
- * then the datatype is closed.
--------------------------------------------------------------------------*/
hid_t
H5Aget_type(hid_t attr_id)
@@ -970,7 +926,7 @@ H5Aget_type(hid_t attr_id)
H5TRACE1("i","i",attr_id);
/* check arguments */
- if (NULL == (attr = H5I_object_verify(attr_id, H5I_ATTR)))
+ if(NULL == (attr = H5I_object_verify(attr_id, H5I_ATTR)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
/*
@@ -978,21 +934,21 @@ H5Aget_type(hid_t attr_id)
* reopen the type before returning it to the user. Make the type
* read-only.
*/
- if (NULL==(dst=H5T_copy(attr->dt, H5T_COPY_REOPEN)))
+ if(NULL == (dst = H5T_copy(attr->dt, H5T_COPY_REOPEN)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy datatype")
/* Mark any datatypes as being in memory now */
- if (H5T_set_loc(dst, NULL, H5T_LOC_MEMORY)<0)
+ if(H5T_set_loc(dst, NULL, H5T_LOC_MEMORY) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
- if (H5T_lock(dst, FALSE)<0)
+ if(H5T_lock(dst, FALSE) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype")
/* Atomize */
- if ((ret_value=H5I_register(H5I_DATATYPE, dst))<0)
+ if((ret_value = H5I_register(H5I_DATATYPE, dst)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype atom")
done:
- if(ret_value<0) {
+ if(ret_value < 0) {
if(dst!=NULL)
(void)H5T_close(dst);
} /* end if */
@@ -1015,8 +971,6 @@ done:
This function returns the length of the attribute's name (which may be
longer than 'buf_size') on success or negative for failure.
- ERRORS
-
DESCRIPTION
This function retrieves the name of an attribute for an attribute ID.
Up to 'buf_size' characters are stored in 'buf' followed by a '\0' string
@@ -1035,9 +989,9 @@ H5Aget_name(hid_t attr_id, size_t buf_size, char *buf)
H5TRACE3("Zs","izs",attr_id,buf_size,buf);
/* check arguments */
- if (NULL == (attr = H5I_object_verify(attr_id, H5I_ATTR)))
+ if(NULL == (attr = H5I_object_verify(attr_id, H5I_ATTR)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
- if (!buf && buf_size)
+ if(!buf && buf_size)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer")
/* get the real attribute length */
@@ -1085,14 +1039,14 @@ done:
hsize_t
H5Aget_storage_size(hid_t attr_id)
{
- H5A_t *attr=NULL;
+ H5A_t *attr = NULL;
hsize_t ret_value; /* Return value */
FUNC_ENTER_API(H5Aget_storage_size, 0)
H5TRACE1("h","i",attr_id);
/* Check args */
- if (NULL==(attr=H5I_object_verify(attr_id, H5I_ATTR)))
+ if(NULL == (attr = H5I_object_verify(attr_id, H5I_ATTR)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, 0, "not an attribute")
/* Set return value */
@@ -1148,20 +1102,14 @@ H5A_get_storage_size(const H5A_t *attr)
RETURNS
Number of attributes on success, negative on failure
- ERRORS
-
DESCRIPTION
This function returns the number of attributes attached to a dataset or
group, 'location_id'.
- *
- * Modifications:
- * Robb Matzke, 5 Jun 1998
- * The LOC_ID can also be a named (committed) datatype.
--------------------------------------------------------------------------*/
int
H5Aget_num_attrs(hid_t loc_id)
{
- H5G_entry_t *ent = NULL; /*symtab ent of object to attribute */
+ H5O_loc_t *loc = NULL; /* Object location for attribute */
void *obj = NULL;
int ret_value;
@@ -1169,27 +1117,30 @@ H5Aget_num_attrs(hid_t loc_id)
H5TRACE1("Is","i",loc_id);
/* check arguments */
- if (H5I_FILE==H5I_get_type(loc_id) || H5I_ATTR==H5I_get_type(loc_id))
+ if(H5I_FILE == H5I_get_type(loc_id) || H5I_ATTR == H5I_get_type(loc_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
if(NULL == (obj = H5I_object(loc_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADATOM, FAIL, "illegal object atom")
switch (H5I_get_type (loc_id)) {
case H5I_DATASET:
- ent = H5D_entof ((H5D_t*)obj);
+ loc = H5D_oloc((H5D_t*)obj);
break;
+
case H5I_DATATYPE:
- if (NULL==(ent=H5T_entof ((H5T_t*)obj)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "target datatype is not committed")
+ if(NULL == (loc = H5T_oloc((H5T_t*)obj)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "target datatype is not committed")
break;
+
case H5I_GROUP:
- ent = H5G_entof ((H5G_t*)obj);
+ loc = H5G_oloc((H5G_t*)obj);
break;
+
default:
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "inappropriate attribute target")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "inappropriate attribute target")
} /*lint !e788 All appropriate cases are covered */
/* Look up the attribute for the object */
- ret_value=H5O_count(ent, H5O_ATTR_ID, H5AC_ind_dxpl_id);
+ ret_value = H5O_count(loc, H5O_ATTR_ID, H5AC_ind_dxpl_id);
done:
FUNC_LEAVE_API(ret_value)
@@ -1202,35 +1153,33 @@ done:
* Purpose: Rename an attribute
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
* Programmer: Raymond Lu
* October 23, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Arename(hid_t loc_id, const char *old_name, const char *new_name)
{
- H5G_entry_t *ent = NULL; /*symtab ent of object to attribute */
- herr_t ret_value; /* Return value */
+ H5G_loc_t loc; /* Object location */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Arename, FAIL)
H5TRACE3("e","iss",loc_id,old_name,new_name);
/* check arguments */
- if (!old_name || !new_name)
+ if(!old_name || !new_name)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "name is nil")
- if (H5I_FILE==H5I_get_type(loc_id) || H5I_ATTR==H5I_get_type(loc_id))
+ if(H5I_FILE == H5I_get_type(loc_id) || H5I_ATTR == H5I_get_type(loc_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
- if (NULL==(ent=H5G_loc(loc_id)))
+ if(H5G_loc(loc_id, & loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
/* Call private function */
- ret_value = H5A_rename(ent, old_name, new_name, H5AC_dxpl_id);
+ if(H5A_rename(loc.oloc, old_name, new_name, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRENAME, FAIL, "can't rename attribute")
done:
FUNC_LEAVE_API(ret_value)
@@ -1243,46 +1192,43 @@ done:
* Purpose: Private function for H5Arename. Rename an attribute
*
* Return: Success: Non-negative
- *
* Failure: Negative
*
* Programmer: Raymond Lu
* October 23, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5A_rename(H5G_entry_t *ent, const char *old_name, const char *new_name, hid_t dxpl_id)
+H5A_rename(H5O_loc_t *loc, const char *old_name, const char *new_name, hid_t dxpl_id)
{
- int seq, idx=FAIL; /* Index of attribute being querried */
- H5A_t found_attr; /* Attribute with OLD_NAME */
- herr_t ret_value=SUCCEED; /* Return value */
+ int seq, idx = FAIL; /* Index of attribute being querried */
+ H5A_t found_attr; /* Attribute with OLD_NAME */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5A_rename)
/* Check arguments */
- assert(ent);
- assert(old_name);
- assert(new_name);
+ HDassert(loc);
+ HDassert(old_name);
+ HDassert(new_name);
/* Read in the existing attributes to check for duplicates */
- seq=0;
- while(H5O_read(ent, H5O_ATTR_ID, seq, &found_attr, dxpl_id)!=NULL) {
+ seq = 0;
+ while(H5O_read(loc, H5O_ATTR_ID, seq, &found_attr, dxpl_id) != NULL) {
/*
* Compare found attribute name.
*/
- if(HDstrcmp(found_attr.name,old_name)==0) {
+ if(HDstrcmp(found_attr.name, old_name) == 0) {
idx = seq;
break;
}
- if(H5O_reset (H5O_ATTR_ID, &found_attr)<0)
+ if(H5O_reset(H5O_ATTR_ID, &found_attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't release attribute info")
seq++;
- }
+ } /* end while */
H5E_clear_stack(NULL);
- if(idx<0)
+ if(idx < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "attribute cannot be found")
/* Copy the attribute name. */
@@ -1293,20 +1239,20 @@ H5A_rename(H5G_entry_t *ent, const char *old_name, const char *new_name, hid_t d
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "String copy failed")
/* Indicate entry is not opened and the attribute doesn't need fill-values. */
- found_attr.ent_opened=FALSE;
- found_attr.initialized=TRUE;
+ found_attr.obj_opened = FALSE;
+ found_attr.initialized = TRUE;
/* Modify the attribute message */
- if (H5O_modify(ent, H5O_ATTR_ID, idx, 0, H5O_UPDATE_TIME, &found_attr, dxpl_id) < 0)
+ if(H5O_modify(loc, H5O_ATTR_ID, idx, 0, H5O_UPDATE_TIME, &found_attr, dxpl_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to update attribute header messages")
/* Close the attribute */
- if(H5A_free(&found_attr)<0)
+ if(H5A_free(&found_attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "unable to close renamed attribute")
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5A_rename() */
/*--------------------------------------------------------------------------
@@ -1324,8 +1270,6 @@ done:
Returns a negative value if something is wrong, the return value of the
last operator if it was non-zero, or zero if all attributes were processed.
- ERRORS
-
DESCRIPTION
This function interates over the attributes of dataset or group
specified with 'loc_id'. For each attribute of the object, the
@@ -1345,31 +1289,22 @@ done:
C. Negative causes the iterator to immediately return that value,
indicating failure. The iterator can be restarted at the next
attribute.
- *
- * Modifications:
- * Robb Matzke, 5 Jun 1998
- * The LOC_ID can also be a named (committed) datatype.
- *
- * Robb Matzke, 5 Jun 1998
- * Like the group iterator, if ATTR_NUM is the null pointer then all
- * attributes are processed.
- *
--------------------------------------------------------------------------*/
herr_t
H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op, void *op_data)
{
- H5G_entry_t *ent = NULL; /*symtab ent of object to attribute */
+ H5G_loc_t loc; /* Object location */
H5A_t found_attr;
+ int idx, start_idx;
herr_t ret_value = 0;
- int idx, start_idx;
FUNC_ENTER_API(H5Aiterate, FAIL)
H5TRACE4("e","i*Iuxx",loc_id,attr_num,op,op_data);
/* check arguments */
- if (H5I_FILE==H5I_get_type(loc_id) || H5I_ATTR==H5I_get_type(loc_id))
+ if(H5I_FILE == H5I_get_type(loc_id) || H5I_ATTR == H5I_get_type(loc_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
- if (NULL==(ent=H5G_loc(loc_id)))
+ if(H5G_loc(loc_id, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
/*
@@ -1377,29 +1312,29 @@ H5Aiterate(hid_t loc_id, unsigned *attr_num, H5A_operator_t op, void *op_data)
* reasonable.
*/
start_idx = idx = (attr_num ? (int)*attr_num : 0);
- if (idx<0)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
- if(idx<H5O_count(ent, H5O_ATTR_ID, H5AC_dxpl_id)) {
- while(H5O_read(ent, H5O_ATTR_ID, idx++, &found_attr, H5AC_dxpl_id)!=NULL) {
+ if(idx < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
+ if(idx < H5O_count(loc.oloc, H5O_ATTR_ID, H5AC_dxpl_id)) {
+ while(H5O_read(loc.oloc, H5O_ATTR_ID, idx++, &found_attr, H5AC_dxpl_id) != NULL) {
/*
* Compare found attribute name to new attribute name reject
* creation if names are the same.
*/
- if((ret_value=(op)(loc_id,found_attr.name,op_data))!=0) {
- if(H5O_reset (H5O_ATTR_ID, &found_attr)<0)
+ if((ret_value = (op)(loc_id,found_attr.name,op_data)) != 0) {
+ if(H5O_reset(H5O_ATTR_ID, &found_attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't release attribute info")
break;
- }
- if(H5O_reset (H5O_ATTR_ID, &found_attr)<0)
+ } /* end if */
+ if(H5O_reset(H5O_ATTR_ID, &found_attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTFREE, FAIL, "can't release attribute info")
- }
+ } /* end while */
H5E_clear_stack(NULL);
- }
+ } /* end if */
else
if(start_idx>0)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
- if (attr_num)
+ if(attr_num)
*attr_num = (unsigned)idx;
done:
@@ -1419,23 +1354,16 @@ done:
RETURNS
Non-negative on success/Negative on failure
- ERRORS
-
DESCRIPTION
This function removes the named attribute from a dataset or group.
This function should not be used when attribute IDs are open on 'loc_id'
as it may cause the internal indexes of the attributes to change and future
writes to the open attributes to produce incorrect results.
- *
- * Modifications:
- * Robb Matzke, 5 Jun 1998
- * The LOC_ID can also be a named (committed) datatype.
- *
--------------------------------------------------------------------------*/
herr_t
H5Adelete(hid_t loc_id, const char *name)
{
- H5G_entry_t *ent = NULL; /*symtab ent of object to attribute */
+ H5G_loc_t loc; /* Object location */
int found;
herr_t ret_value;
@@ -1443,19 +1371,19 @@ H5Adelete(hid_t loc_id, const char *name)
H5TRACE2("e","is",loc_id,name);
/* check arguments */
- if (H5I_FILE==H5I_get_type(loc_id) || H5I_ATTR==H5I_get_type(loc_id))
+ if(H5I_FILE == H5I_get_type(loc_id) || H5I_ATTR == H5I_get_type(loc_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "location is not valid for an attribute")
- if (NULL==(ent=H5G_loc(loc_id)))
+ if(H5G_loc(loc_id, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
- if (!name || !*name)
+ if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
/* Look up the attribute index for the object */
- if((found=H5A_get_index(ent,name,H5AC_dxpl_id))<0)
+ if((found = H5A_get_index(loc.oloc, name, H5AC_dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_NOTFOUND, FAIL, "attribute not found")
/* Delete the attribute from the location */
- if ((ret_value=H5O_remove(ent, H5O_ATTR_ID, found, TRUE, H5AC_dxpl_id)) < 0)
+ if((ret_value = H5O_remove(loc.oloc, H5O_ATTR_ID, found, TRUE, H5AC_dxpl_id)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDELETE, FAIL, "unable to delete attribute header message")
done:
@@ -1474,8 +1402,6 @@ done:
RETURNS
Non-negative on success/Negative on failure
- ERRORS
-
DESCRIPTION
This function releases an attribute from use. Further use of the
attribute ID will result in undefined behavior.
@@ -1483,17 +1409,17 @@ done:
herr_t
H5Aclose(hid_t attr_id)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Aclose, FAIL)
H5TRACE1("e","i",attr_id);
/* check arguments */
- if (NULL == H5I_object_verify(attr_id, H5I_ATTR))
+ if(NULL == H5I_object_verify(attr_id, H5I_ATTR))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute")
/* Decrement references to that atom (and close it) */
- if(H5I_dec_ref (attr_id)<0)
+ if(H5I_dec_ref (attr_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDEC, FAIL, "can't close attribute")
done:
@@ -1520,9 +1446,9 @@ done:
H5A_t *
H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr, unsigned update_flags)
{
- H5A_t *new_attr=NULL;
- hbool_t allocated_attr=FALSE; /* Whether the attribute was allocated */
- H5A_t *ret_value=NULL; /* Return value */
+ H5A_t *new_attr = NULL;
+ hbool_t allocated_attr = FALSE; /* Whether the attribute was allocated */
+ H5A_t *ret_value = NULL; /* Return value */
FUNC_ENTER_NOAPI(H5A_copy, NULL)
@@ -1530,13 +1456,13 @@ H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr, unsigned update_flags)
assert(old_attr);
/* get space */
- if(_new_attr==NULL) {
+ if(_new_attr == NULL) {
/* Sanity check - We should not be only updating data if we don'y have anything */
HDassert(!(update_flags&H5O_UPDATE_DATA_ONLY));
- if (NULL==(new_attr = H5FL_MALLOC(H5A_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- allocated_attr=TRUE;
+ if(NULL == (new_attr = H5FL_MALLOC(H5A_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ allocated_attr = TRUE;
} /* end if */
else
new_attr=_new_attr;
@@ -1546,26 +1472,26 @@ H5A_copy(H5A_t *_new_attr, const H5A_t *old_attr, unsigned update_flags)
*new_attr = *old_attr;
/* Don't open the object header for a copy */
- new_attr->ent_opened=0;
+ new_attr->obj_opened = FALSE;
/* Copy the guts of the attribute */
- new_attr->name=HDstrdup(old_attr->name);
- new_attr->dt=H5T_copy(old_attr->dt, H5T_COPY_ALL);
- new_attr->ds=H5S_copy(old_attr->ds, FALSE);
+ new_attr->name = HDstrdup(old_attr->name);
+ new_attr->dt = H5T_copy(old_attr->dt, H5T_COPY_ALL);
+ new_attr->ds = H5S_copy(old_attr->ds, FALSE);
} /* end if */
if(old_attr->data) {
- if(!(update_flags&H5O_UPDATE_DATA_ONLY) || new_attr->data==NULL) {
- if (NULL==(new_attr->data=H5FL_BLK_MALLOC(attr_buf,old_attr->data_size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ if(!(update_flags&H5O_UPDATE_DATA_ONLY) || new_attr->data == NULL) {
+ if(NULL == (new_attr->data = H5FL_BLK_MALLOC(attr_buf,old_attr->data_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
} /* end if */
HDmemcpy(new_attr->data,old_attr->data,old_attr->data_size);
} /* end if */
/* Set the return value */
- ret_value=new_attr;
+ ret_value = new_attr;
done:
- if(ret_value==NULL) {
+ if(ret_value == NULL) {
if(new_attr!=NULL && allocated_attr)
(void)H5A_close(new_attr);
} /* end if */
@@ -1592,7 +1518,7 @@ done:
herr_t
H5A_free(H5A_t *attr)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5A_free, FAIL)
@@ -1602,10 +1528,10 @@ H5A_free(H5A_t *attr)
if(attr->name)
H5MM_xfree(attr->name);
if(attr->dt)
- if(H5T_close(attr->dt)<0)
+ if(H5T_close(attr->dt) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release datatype info")
if(attr->ds)
- if(H5S_close(attr->ds)<0)
+ if(H5S_close(attr->ds) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release dataspace info")
if(attr->data)
H5FL_BLK_FREE(attr_buf, attr->data);
@@ -1632,20 +1558,20 @@ done:
herr_t
H5A_close(H5A_t *attr)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5A_close, FAIL)
- assert(attr);
+ HDassert(attr);
/* Check if the attribute has any data yet, if not, fill with zeroes */
- if(attr->ent_opened && !attr->initialized) {
- uint8_t *tmp_buf=H5FL_BLK_CALLOC(attr_buf, attr->data_size);
- if (NULL == tmp_buf)
+ if(attr->obj_opened && !attr->initialized) {
+ uint8_t *tmp_buf = H5FL_BLK_CALLOC(attr_buf, attr->data_size);
+ if(NULL == tmp_buf)
HGOTO_ERROR(H5E_ATTR, H5E_NOSPACE, FAIL, "memory allocation failed for attribute fill-value")
/* Go write the fill data to the attribute */
- if (H5A_write(attr,attr->dt,tmp_buf,H5AC_dxpl_id)<0)
+ if(H5A_write(attr, attr->dt, tmp_buf, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_WRITEERROR, FAIL, "unable to write attribute")
/* Free temporary buffer */
@@ -1653,14 +1579,18 @@ H5A_close(H5A_t *attr)
} /* end if */
/* Free dynamicly allocated items */
- if(H5A_free(attr)<0)
+ if(H5A_free(attr) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release attribute info")
/* Close the object's symbol-table entry */
- if(attr->ent_opened)
- if(H5O_close(&(attr->ent))<0)
+ if(attr->obj_opened)
+ if(H5O_close(&(attr->oloc)) < 0)
HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release object header info")
+ /* Release the group hier. path for the object the attribute is on */
+ if(H5G_name_free(&(attr->path)) < 0)
+ HGOTO_ERROR(H5E_ATTR, H5E_CANTRELEASE, FAIL, "can't release group hier. path")
+
H5FL_FREE(H5A_t, attr);
done:
@@ -1669,34 +1599,65 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5A_entof
+ * Function: H5A_oloc
*
- * Purpose: Return the symbol table entry for an attribute. It's the
- * symbol table entry for the object to which the attribute
+ * Purpose: Return the object location for an attribute. It's the
+ * object location for the object to which the attribute
* belongs, not the attribute itself.
*
* Return: Success: Ptr to entry
- *
* Failure: NULL
*
* Programmer: Robb Matzke
* Thursday, August 6, 1998
*
- * Modifications:
+ *-------------------------------------------------------------------------
+ */
+H5O_loc_t *
+H5A_oloc(H5A_t *attr)
+{
+ H5O_loc_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5A_oloc, NULL)
+
+ HDassert(attr);
+
+ /* Set return value */
+ ret_value = &(attr->oloc);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5A_oloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5A_nameof
+ *
+ * Purpose: Return the group hier. path for an attribute. It's the
+ * group hier. path for the object to which the attribute
+ * belongs, not the attribute itself.
+ *
+ * Return: Success: Ptr to entry
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 12, 2005
*
*-------------------------------------------------------------------------
*/
-H5G_entry_t *
-H5A_entof(H5A_t *attr)
+H5G_name_t *
+H5A_nameof(H5A_t *attr)
{
- H5G_entry_t *ret_value; /* Return value */
+ H5G_name_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5A_entof, NULL)
- assert(attr);
+ FUNC_ENTER_NOAPI(H5A_nameof, NULL)
+
+ HDassert(attr);
/* Set return value */
- ret_value=&(attr->ent);
+ ret_value=&(attr->path);
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5A_nameof() */
+
diff --git a/src/H5Apkg.h b/src/H5Apkg.h
index 753ad64..cfe22ea 100644
--- a/src/H5Apkg.h
+++ b/src/H5Apkg.h
@@ -39,13 +39,15 @@
/* Other private headers needed by this file */
#include "H5FLprivate.h" /* Free Lists */
+#include "H5Oprivate.h" /* Object headers */
#include "H5Sprivate.h" /* Dataspace */
#include "H5Tprivate.h" /* Datatype functions */
struct H5A_t {
- unsigned initialized;/* Indicate whether the attribute has been modified */
- unsigned ent_opened; /* Object header entry opened? */
- H5G_entry_t ent; /* Object Header entry (for both datasets & groups) */
+ hbool_t initialized;/* Indicate whether the attribute has been modified */
+ hbool_t obj_opened; /* Object header entry opened? */
+ H5O_loc_t oloc; /* Object location for object attribute is on */
+ H5G_name_t path; /* Group hierarchy path */
char *name; /* Attribute's name */
H5T_t *dt; /* Attribute's datatype */
size_t dt_size; /* Size of datatype on disk */
diff --git a/src/H5Aprivate.h b/src/H5Aprivate.h
index 8d694bc..9b24490 100644
--- a/src/H5Aprivate.h
+++ b/src/H5Aprivate.h
@@ -28,6 +28,7 @@
typedef struct H5A_t H5A_t;
/* Library private functions in package */
-H5_DLL H5G_entry_t *H5A_entof(H5A_t *attr);
+H5_DLL struct H5O_loc_t *H5A_oloc(H5A_t *attr);
+H5_DLL H5G_name_t *H5A_nameof(H5A_t *attr);
#endif
diff --git a/src/H5B2.c b/src/H5B2.c
index 194cdb6..7b81dbf 100644
--- a/src/H5B2.c
+++ b/src/H5B2.c
@@ -96,8 +96,7 @@ static herr_t H5B2_swap_leaf(H5F_t *f, hid_t dxpl_id, unsigned depth,
H5B2_internal_t *internal, unsigned *internal_flags_ptr,
unsigned idx, void *swap_loc);
static herr_t H5B2_insert_internal(H5F_t *f, hid_t dxpl_id,
- H5RC_t *bt2_shared, unsigned depth, H5AC_info_t *parent_cache_info,
- unsigned *parent_cache_info_flags_ptr,
+ H5RC_t *bt2_shared, unsigned depth, unsigned *parent_cache_info_flags_ptr,
H5B2_node_ptr_t *curr_node_ptr, void *udata);
static herr_t H5B2_insert_leaf(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
H5B2_node_ptr_t *curr_node_ptr, void *udata);
@@ -2476,8 +2475,7 @@ done:
*/
static herr_t
H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
- unsigned depth, H5AC_info_t *parent_cache_info,
- unsigned *parent_cache_info_flags_ptr,
+ unsigned depth, unsigned *parent_cache_info_flags_ptr,
H5B2_node_ptr_t *curr_node_ptr, void *udata)
{
H5B2_internal_t *internal; /* Pointer to internal node */
@@ -2492,7 +2490,6 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
HDassert(f);
HDassert(bt2_shared);
HDassert(depth>0);
- HDassert(parent_cache_info);
HDassert(parent_cache_info_flags_ptr);
HDassert(curr_node_ptr);
HDassert(H5F_addr_defined(curr_node_ptr->addr));
@@ -2583,8 +2580,7 @@ H5B2_insert_internal(H5F_t *f, hid_t dxpl_id, H5RC_t *bt2_shared,
/* Attempt to insert node */
if(depth>1) {
- if(H5B2_insert_internal(f,dxpl_id,bt2_shared,depth-1,&internal->cache_info,&internal_flags,
- &internal->node_ptrs[idx],udata)<0)
+ if(H5B2_insert_internal(f, dxpl_id, bt2_shared, depth-1, &internal_flags, &internal->node_ptrs[idx], udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree internal node")
} /* end if */
else {
@@ -2670,7 +2666,7 @@ H5B2_insert(H5F_t *f, hid_t dxpl_id, const H5B2_class_t *type, haddr_t addr,
/* Attempt to insert record into B-tree */
if(bt2->depth>0) {
- if(H5B2_insert_internal(f,dxpl_id,bt2->shared,bt2->depth,&(bt2->cache_info),&bt2_flags,&bt2->root,udata)<0)
+ if(H5B2_insert_internal(f, dxpl_id, bt2->shared, bt2->depth, &bt2_flags, &bt2->root, udata) < 0)
HGOTO_ERROR(H5E_BTREE, H5E_CANTINSERT, FAIL, "unable to insert record into B-tree internal node")
} /* end if */
else {
diff --git a/src/H5D.c b/src/H5D.c
index 156b70d..df24bab 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -62,9 +62,9 @@ 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_entry_t *loc, const char *name, hid_t type_id,
+static H5D_t * H5D_create(H5G_loc_t *loc, const char *name, hid_t type_id,
const H5S_t *space, hid_t dcpl_id, hid_t dxpl_id);
-static H5D_t * H5D_open_oid(const H5G_entry_t *ent, 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);
static hsize_t H5D_get_storage_size(H5D_t *dset, hid_t dxpl_id);
static haddr_t H5D_get_offset(const H5D_t *dset);
@@ -1162,7 +1162,7 @@ hid_t
H5Dcreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
hid_t dcpl_id)
{
- H5G_entry_t *loc; /* Entry for group to insert dataset into */
+ 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 */
@@ -1171,7 +1171,7 @@ H5Dcreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
H5TRACE5("i","isiii",loc_id,name,type_id,space_id,dcpl_id);
/* Check arguments */
- if(NULL == (loc = H5G_loc(loc_id)))
+ if(H5G_loc(loc_id, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID")
if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
@@ -1186,11 +1186,11 @@ H5Dcreate(hid_t loc_id, const char *name, hid_t type_id, hid_t space_id,
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, name, type_id, space, dcpl_id, H5AC_dxpl_id)))
+ if(NULL == (new_dset = H5D_create(&loc, name, 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 ((ret_value = H5I_register(H5I_DATASET, new_dset)) < 0)
+ if((ret_value = H5I_register(H5I_DATASET, new_dset)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register dataset")
done:
@@ -1225,8 +1225,10 @@ hid_t
H5Dopen(hid_t loc_id, const char *name)
{
H5D_t *dset = NULL;
- H5G_entry_t *loc = NULL; /*location holding the dataset */
- H5G_entry_t ent; /*dataset symbol table entry */
+ H5G_loc_t loc; /* Object location of group */
+ H5G_loc_t dset_loc; /* Object location of dataset */
+ H5G_name_t path; /* Dataset group hier. path */
+ H5O_loc_t oloc; /* Dataset object location */
hbool_t ent_found = FALSE; /* Entry at 'name' found */
hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datset */
hid_t ret_value;
@@ -1235,26 +1237,33 @@ H5Dopen(hid_t loc_id, const char *name)
H5TRACE2("i","is",loc_id,name);
/* Check args */
- if (NULL == (loc = H5G_loc(loc_id)))
+ if(H5G_loc(loc_id, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
- if (!name || !*name)
+ if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+ /* Set up dataset location to fill in */
+ dset_loc.oloc = &oloc;
+ dset_loc.path = &path;
+ H5G_loc_reset(&dset_loc);
+
/* Find the dataset object */
- if (H5G_find(loc, name, &ent, dxpl_id) < 0)
+ if(H5G_loc_find(&loc, name, &dset_loc, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found")
ent_found = TRUE;
/* Check that the object found is the correct type */
- if (H5G_get_type(&ent, dxpl_id) != H5G_DATASET)
+ if(H5O_obj_type(&oloc, dxpl_id) != H5G_DATASET)
HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset")
/* Open the dataset */
- if ((dset = H5D_open(&ent, dxpl_id))==NULL)
+ if((dset = H5D_open(&dset_loc, dxpl_id)) == NULL) {
+ ent_found = FALSE; /* Reset this, since H5D_open 'owns' it and then free's it on failure */
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't open dataset")
+ } /* end if */
/* Register an atom for the dataset */
- if((ret_value=H5I_register(H5I_DATASET, dset)) <0)
+ if((ret_value = H5I_register(H5I_DATASET, dset)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "can't register dataset atom")
done:
@@ -1264,12 +1273,13 @@ done:
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataset")
} /* end if */
else {
- if(ent_found && ent.header)
- H5G_free_ent_name(&ent);
+ if(ent_found)
+ H5G_name_free(&path);
} /* end else */
} /* end if */
+
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Dopen() */
/*-------------------------------------------------------------------------
@@ -1289,28 +1299,26 @@ done:
herr_t
H5Dclose(hid_t dset_id)
{
- H5D_t *dset = NULL; /* Dataset object to release */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5D_t *dset; /* Dataset object to release */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Dclose, FAIL)
H5TRACE1("e","i",dset_id);
/* Check args */
- if (NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
+ if(NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
- if (NULL == dset->ent.file)
- HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a dataset")
/*
* Decrement the counter on the dataset. It will be freed if the count
* reaches zero.
*/
- if (H5I_dec_ref(dset_id) < 0)
+ if(H5I_dec_ref(dset_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't free")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Dclose() */
/*-------------------------------------------------------------------------
@@ -1466,9 +1474,9 @@ done:
/*-------------------------------------------------------------------------
* Function: H5Dget_type
*
- * Purpose: Returns a copy of the file data type for a dataset.
+ * Purpose: Returns a copy of the file datatype for a dataset.
*
- * Return: Success: ID for a copy of the data type. The data
+ * Return: Success: ID for a copy of the datatype. The data
* type should be released by calling
* H5Tclose().
*
@@ -1494,9 +1502,9 @@ H5Dget_type(hid_t dset_id)
if (NULL==(dset=H5I_object_verify(dset_id, H5I_DATASET)))
HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
- /* Copy the data type and mark it read-only */
+ /* Copy the datatype and mark it read-only */
if (NULL==(copied_type=H5T_copy (dset->shared->type, H5T_COPY_REOPEN)))
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy the data type")
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy the datatype")
/* Mark any datatypes as being in memory now */
if (H5T_set_loc(copied_type, NULL, H5T_LOC_MEMORY)<0)
@@ -1504,11 +1512,11 @@ H5Dget_type(hid_t dset_id)
/* Unlock copied type */
if (H5T_lock (copied_type, FALSE)<0)
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient data type")
+ HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient datatype")
/* Create an atom */
if ((ret_value=H5I_register (H5I_DATATYPE, copied_type))<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register data type")
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register datatype")
done:
if(ret_value<0) {
@@ -1570,7 +1578,7 @@ H5Dget_create_plist(hid_t dset_id)
/* Copy the dataset type into the fill value message */
if(copied_fill.type==NULL)
if(NULL==(copied_fill.type=H5T_copy(dset->shared->type, H5T_COPY_TRANSIENT)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy dataset data type for fill value")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy dataset datatype for fill value")
/* Set back the fill value property to property list */
if(H5P_set(new_plist, H5D_CRT_FILL_VALUE_NAME, &copied_fill) < 0)
@@ -1777,7 +1785,7 @@ static herr_t
H5D_update_entry_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, H5P_genplist_t *plist)
{
size_t ohdr_size = H5D_MINHDR_SIZE; /* Size of dataset's object header */
- H5G_entry_t *ent=NULL; /* Dataset's group entry */
+ H5O_loc_t *oloc = NULL; /* Dataset's object location */
H5O_layout_t *layout; /* Dataset's layout information */
H5T_t *type; /* Dataset's datatype */
H5S_t *space; /* Dataset's dataspace */
@@ -1799,45 +1807,45 @@ H5D_update_entry_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, H5P_genplist_t *p
FUNC_ENTER_NOAPI(H5D_update_entry_info, FAIL)
/* Sanity checking */
- assert(file);
- assert(dset);
+ HDassert(file);
+ HDassert(dset);
/* Pick up former parameters */
- ent=&dset->ent;
- layout=&dset->shared->layout;
- type=dset->shared->type;
- space=dset->shared->space;
- alloc_time=dset->shared->alloc_time;
- efl=&dset->shared->efl;
+ oloc = &dset->oloc;
+ layout = &dset->shared->layout;
+ type = dset->shared->type;
+ space = dset->shared->space;
+ alloc_time = dset->shared->alloc_time;
+ efl = &dset->shared->efl;
/* Add the dataset's raw data size to the size of the header, if the raw data will be stored as compact */
- if (layout->type == H5D_COMPACT)
+ if(layout->type == H5D_COMPACT)
ohdr_size += layout->u.compact.size;
/* Create (open for write access) an object header */
- if (H5O_create(file, dxpl_id, ohdr_size, ent) < 0)
+ if(H5O_create(file, dxpl_id, ohdr_size, oloc) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to create dataset object header")
/* Get a pointer to the object header itself */
- if((oh=H5O_protect(ent, dxpl_id))==NULL)
+ if((oh = H5O_protect(oloc, dxpl_id)) == NULL)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to protect dataset object header")
/* Point at dataset's copy, to cache it for later */
- fill_prop=&dset->shared->fill;
- fill_time=dset->shared->fill_time;
+ fill_prop = &dset->shared->fill;
+ fill_time = dset->shared->fill_time;
/* Check if dataset has non-default creation property list */
- if(dset->shared->dcpl_id!=H5P_DATASET_CREATE_DEFAULT) {
+ if(dset->shared->dcpl_id != H5P_DATASET_CREATE_DEFAULT) {
/*
* Retrieve properties of fill value and others. Copy them into new fill
* value struct.
*/
- if (H5P_get(plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
+ if(H5P_get(plist, H5D_CRT_FILL_TIME_NAME, &fill_time) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill time")
dset->shared->fill_time=fill_time; /* Cache this for later */
/* Get the fill value information from the property list */
- if (H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, fill_prop) < 0)
+ if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, fill_prop) < 0)
HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't retrieve fill value")
} /* end if */
@@ -1966,9 +1974,9 @@ H5D_update_entry_info(H5F_t *file, hid_t dxpl_id, H5D_t *dset, H5P_genplist_t *p
#ifdef H5O_ENABLE_BOGUS
/*
- * Add a "bogus" message.
+ * Add a "bogus" message (for error testing).
*/
- if (H5O_bogus_oh(file, dxpl_id, oh))<0)
+ if(H5O_bogus_oh(file, dxpl_id, oh)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to update 'bogus' message")
#endif /* H5O_ENABLE_BOGUS */
@@ -1982,8 +1990,8 @@ done:
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to release fill-value info")
/* Release pointer to object header itself */
- if(ent!=NULL && oh!=NULL)
- if(H5O_unprotect(ent,oh, dxpl_id, oh_flags)<0)
+ if(oloc != NULL && oh != NULL)
+ if(H5O_unprotect(oloc, oh, dxpl_id, oh_flags) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to unprotect dataset object header")
FUNC_LEAVE_NOAPI(ret_value)
@@ -2011,7 +2019,7 @@ done:
*-------------------------------------------------------------------------
*/
static H5D_t *
-H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space,
+H5D_create(H5G_loc_t *loc, const char *name, hid_t type_id, const H5S_t *space,
hid_t dcpl_id, hid_t dxpl_id)
{
const H5T_t *type; /* Datatype for dataset */
@@ -2023,17 +2031,18 @@ H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space
H5P_genplist_t *dc_plist=NULL; /* New Property list */
hbool_t has_vl_type=FALSE; /* Flag to indicate a VL-type for dataset */
hbool_t chunk_init=FALSE; /* Flag to indicate that chunk information was initialized */
+ H5G_loc_t dset_loc; /* Dataset location */
H5D_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5D_create, NULL)
/* check args */
- assert (loc);
- assert (name && *name);
- assert (H5I_DATATYPE==H5I_get_type(type_id));
- assert (space);
- assert (H5I_GENPROP_LST==H5I_get_type(dcpl_id));
- assert (H5I_GENPROP_LST==H5I_get_type(dxpl_id));
+ HDassert(loc);
+ HDassert(name && *name);
+ HDassert(H5I_DATATYPE==H5I_get_type(type_id));
+ HDassert(space);
+ HDassert(H5I_GENPROP_LST==H5I_get_type(dcpl_id));
+ HDassert(H5I_GENPROP_LST==H5I_get_type(dxpl_id));
/* Get the dataset's datatype */
if (NULL == (type = H5I_object(type_id)))
@@ -2055,14 +2064,17 @@ H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space
if (NULL==(new_dset = H5FL_CALLOC(H5D_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- H5G_ent_reset(&(new_dset->ent));
+ /* Set up & reset dataset location */
+ dset_loc.oloc = &(new_dset->oloc);
+ dset_loc.path = &(new_dset->path);
+ H5G_loc_reset(&dset_loc);
/* Initialize the shared dataset 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)))
+ 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 */
@@ -2189,7 +2201,7 @@ H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space
H5_ASSIGN_OVERFLOW(new_dset->shared->layout.u.contig.size,tmp_size,hssize_t,hsize_t);
/* Get the sieve buffer size for this dataset */
- new_dset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(loc->file);
+ new_dset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(file);
} /* end case */
break;
@@ -2287,50 +2299,50 @@ H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space
* 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, &new_dset->ent, dxpl_id, dc_plist) < 0)
+ 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->ent.file, new_dset->ent.header)<0)
+ 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->ent.file,new_dset->ent.header,new_dset->shared)<0)
+ 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")
- new_dset->shared->fo_count=1;
+ new_dset->shared->fo_count = 1;
/* Success */
ret_value = new_dset;
done:
- if (!ret_value && new_dset && new_dset->shared) {
- if( new_dset->shared) {
- if(new_dset->shared->layout.type==H5D_CHUNKED && chunk_init) {
- if(H5D_istore_dest(new_dset,H5AC_dxpl_id)<0)
+ if(!ret_value && new_dset && new_dset->shared) {
+ if(new_dset->shared) {
+ if(new_dset->shared->layout.type == H5D_CHUNKED && chunk_init) {
+ if(H5D_istore_dest(new_dset,H5AC_dxpl_id) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, NULL, "unable to destroy chunk cache")
} /* end if */
- if (new_dset->shared->space) {
- if(H5S_close(new_dset->shared->space)<0)
+ if(new_dset->shared->space) {
+ if(H5S_close(new_dset->shared->space) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release dataspace")
} /* end if */
- if (new_dset->shared->type) {
- if(H5I_dec_ref(new_dset->shared->type_id)<0)
+ if(new_dset->shared->type) {
+ if(H5I_dec_ref(new_dset->shared->type_id) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release datatype")
} /* end if */
- if (H5F_addr_defined(new_dset->ent.header)) {
- if(H5O_close(&(new_dset->ent))<0)
+ if(H5F_addr_defined(new_dset->oloc.addr)) {
+ if(H5O_close(&(new_dset->oloc)) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release object header")
if(file) {
- if(H5O_delete(file, dxpl_id,new_dset->ent.header)<0)
+ if(H5O_delete(file, dxpl_id, new_dset->oloc.addr) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTDELETE, NULL, "unable to delete object header")
} /* end if */
} /* end if */
- if(new_dset->shared->dcpl_id!=0) {
- if(H5I_dec_ref(new_dset->shared->dcpl_id)<0)
+ if(new_dset->shared->dcpl_id != 0) {
+ if(H5I_dec_ref(new_dset->shared->dcpl_id) < 0)
HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, NULL, "unable to decrement ref count on property list")
} /* end if */
- H5FL_FREE(H5D_shared_t,new_dset->shared);
+ H5FL_FREE(H5D_shared_t, new_dset->shared);
} /* end if */
- new_dset->ent.file = NULL;
+ new_dset->oloc.file = NULL;
H5FL_FREE(H5D_t, new_dset);
} /* end if */
@@ -2356,33 +2368,30 @@ done:
*-------------------------------------------------------------------------
*/
htri_t
-H5D_isa(H5G_entry_t *ent, hid_t dxpl_id)
+H5D_isa(H5O_loc_t *loc, hid_t dxpl_id)
{
htri_t exists;
- htri_t ret_value=TRUE; /* Return value */
+ htri_t ret_value = TRUE; /* Return value */
FUNC_ENTER_NOAPI(H5D_isa, FAIL)
- assert(ent);
+ HDassert(loc);
- /* Data type */
- if ((exists=H5O_exists(ent, H5O_DTYPE_ID, 0, dxpl_id))<0) {
+ /* Datatype */
+ if((exists = H5O_exists(loc, H5O_DTYPE_ID, 0, dxpl_id)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read object header")
- } else if (!exists) {
+ else if(!exists)
HGOTO_DONE(FALSE)
- }
/* Layout */
- if ((exists=H5O_exists(ent, H5O_LAYOUT_ID, 0, dxpl_id))<0) {
+ if((exists = H5O_exists(loc, H5O_SDSPACE_ID, 0, dxpl_id)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read object header")
- } else if (!exists) {
+ else if(!exists)
HGOTO_DONE(FALSE)
- }
-
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5D_isa() */
/*
@@ -2400,67 +2409,78 @@ done:
*
*-------------------------------------------------------------------------
*/
-H5D_t*
-H5D_open(const H5G_entry_t *ent, hid_t dxpl_id)
+H5D_t *
+H5D_open(const H5G_loc_t *loc, hid_t dxpl_id)
{
- H5D_shared_t *shared_fo=NULL;
- H5D_t *dataset=NULL;
+ H5D_shared_t *shared_fo = NULL;
+ H5D_t *dataset = NULL;
H5D_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5D_open, NULL)
/* check args */
- assert (ent);
+ HDassert(loc);
+
+ /* Allocate the dataset structure */
+ if(NULL == (dataset = H5FL_CALLOC(H5D_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Shallow copy (take ownership) of the object location object */
+ if(H5O_loc_copy(&(dataset->oloc), loc->oloc, H5O_COPY_SHALLOW) < 0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTCOPY, NULL, "can't copy object location")
+
+ /* Shallow copy (take ownership) of the group hier. path */
+ if(H5G_name_copy(&(dataset->path), loc->path, H5G_COPY_SHALLOW) < 0)
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTCOPY, NULL, "can't copy path")
/* Check if dataset was already open */
- if((shared_fo=H5FO_opened(ent->file,ent->header))==NULL) {
+ if((shared_fo = H5FO_opened(dataset->oloc.file, dataset->oloc.addr)) == NULL) {
/* Clear any errors from H5FO_opened() */
H5E_clear_stack(NULL);
/* Open the dataset object */
- if ((dataset=H5D_open_oid(ent, dxpl_id)) ==NULL)
+ if(H5D_open_oid(dataset, dxpl_id) < 0)
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->ent.file,dataset->ent.header,dataset->shared)<0)
+ if(H5FO_insert(dataset->oloc.file, dataset->oloc.addr, dataset->shared) < 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 */
- if(H5FO_top_incr(dataset->ent.file, dataset->ent.header) < 0)
+ if(H5FO_top_incr(dataset->oloc.file, dataset->oloc.addr) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, NULL, "can't increment object count")
+ /* We're the first dataset to use the the shared info */
dataset->shared->fo_count = 1;
} /* end if */
else {
- if(NULL == (dataset = H5FL_CALLOC(H5D_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for dataset")
-
- /* Shallow copy (take ownership) of the group entry object */
- if(H5G_ent_copy(&(dataset->ent),ent,H5G_COPY_SHALLOW)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTCOPY, NULL, "can't copy group entry")
-
- dataset->shared=shared_fo;
+ /* Point to shared info */
+ dataset->shared = shared_fo;
+ /* Increment # of datasets using shared information */
shared_fo->fo_count++;
/* Check if the object has been opened through the top file yet */
- if(H5FO_top_count(dataset->ent.file, dataset->ent.header) == 0) {
+ if(H5FO_top_count(dataset->oloc.file, dataset->oloc.addr) == 0) {
/* Open the object through this top file */
- if(H5O_open(&(dataset->ent)) < 0)
+ if(H5O_open(&(dataset->oloc)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, NULL, "unable to open object header")
} /* end if */
/* Increment object count for the object in the top file */
- if(H5FO_top_incr(dataset->ent.file, dataset->ent.header) < 0)
+ if(H5FO_top_incr(dataset->oloc.file, dataset->oloc.addr) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINC, NULL, "can't increment object count")
} /* end else */
ret_value = dataset;
done:
- if(ret_value==NULL) {
+ if(ret_value == NULL) {
if(dataset) {
- if(shared_fo==NULL) /* Need to free shared fo */
+ /* Free the dataset's group hier. path */
+ H5G_name_free(&dataset->path);
+
+ if(shared_fo == NULL) /* Need to free shared fo */
H5FL_FREE(H5D_shared_t, dataset->shared);
H5FL_FREE(H5D_t, dataset);
}
@@ -2469,7 +2489,7 @@ done:
} /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5D_open() */
/*-------------------------------------------------------------------------
@@ -2484,59 +2504,50 @@ done:
*
*-------------------------------------------------------------------------
*/
-static H5D_t *
-H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id)
+static herr_t
+H5D_open_oid(H5D_t *dataset, hid_t dxpl_id)
{
- H5D_t *dataset = NULL; /*new dataset struct */
H5O_fill_new_t fill = {NULL, 0, NULL, H5D_ALLOC_TIME_LATE, H5D_CRT_FILL_TIME_DEF, TRUE};
unsigned alloc_time_state; /* Allocation time state */
H5O_fill_t *fill_prop; /* Pointer to dataset's fill value area */
H5O_pline_t pline; /* I/O pipeline information */
H5P_genplist_t *plist; /* Property list */
- H5D_t *ret_value = NULL; /*return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5D_open_oid, NULL)
+ FUNC_ENTER_NOAPI(H5D_open_oid, FAIL)
/* check args */
- assert (ent);
-
- /* Allocate the dataset structure */
- if(NULL==(dataset=H5FL_CALLOC(H5D_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDassert(dataset);
/* (Set the 'vl_type' parameter to FALSE since it doesn't matter from here) */
if(NULL==(dataset->shared = H5D_new(H5P_DATASET_CREATE_DEFAULT,FALSE,FALSE)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- /* Shallow copy (take ownership) of the group entry object */
- if(H5G_ent_copy(&(dataset->ent),ent,H5G_COPY_SHALLOW)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTCOPY, NULL, "can't copy group entry")
-
- /* Find the dataset object */
- if (H5O_open(&(dataset->ent)) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, NULL, "unable to open")
+ /* Open the dataset object */
+ if(H5O_open(&(dataset->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTOPENOBJ, FAIL, "unable to open")
/* Get the type and space */
- if (NULL==(dataset->shared->type=H5O_read(&(dataset->ent), H5O_DTYPE_ID, 0, NULL, dxpl_id)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to load type info from dataset header")
+ if(NULL == (dataset->shared->type = H5O_read(&(dataset->oloc), H5O_DTYPE_ID, 0, NULL, dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to load type info from dataset header")
/* Get a datatype ID for the dataset's datatype */
if((dataset->shared->type_id = H5I_register(H5I_DATATYPE, dataset->shared->type))<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, NULL, "unable to register type")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "unable to register type")
- if (NULL==(dataset->shared->space=H5S_read(&(dataset->ent),dxpl_id)))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to load space info from dataset header")
+ if(NULL == (dataset->shared->space = H5S_read(&(dataset->oloc), dxpl_id)))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to load space info from dataset header")
/* Get dataset creation property list object */
- if (NULL == (plist = H5I_object(dataset->shared->dcpl_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "can't get dataset creation property list")
+ if(NULL == (plist = H5I_object(dataset->shared->dcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get dataset creation property list")
/* Get the optional filters message */
- if(NULL == H5O_read(&(dataset->ent), H5O_PLINE_ID, 0, &pline, dxpl_id)) {
+ if(NULL == H5O_read(&(dataset->oloc), H5O_PLINE_ID, 0, &pline, dxpl_id)) {
H5E_clear_stack(NULL);
HDmemset(&pline, 0, sizeof(pline));
- }
+ } /* end if */
if(H5P_set(plist, H5D_CRT_DATA_PIPELINE_NAME, &pline) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set pipeline")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set pipeline")
/*
* Get the raw data layout info. It's actually stored in two locations:
@@ -2544,10 +2555,10 @@ H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id)
* values are copied to the dataset create plist so the user can query
* them.
*/
- if (NULL==H5O_read(&(dataset->ent), H5O_LAYOUT_ID, 0, &(dataset->shared->layout), dxpl_id))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to read data layout message")
+ if(NULL == H5O_read(&(dataset->oloc), H5O_LAYOUT_ID, 0, &(dataset->shared->layout), dxpl_id))
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read data layout message")
if(H5P_set(plist, H5D_CRT_LAYOUT_NAME, &dataset->shared->layout.type) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set layout")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set layout")
switch (dataset->shared->layout.type) {
case H5D_CONTIGUOUS:
/* Compute the size of the contiguous storage for versions of the
@@ -2567,14 +2578,14 @@ H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id)
dataset->shared->io_ops.writevv=H5D_contig_writevv;
/* Get the sieve buffer size for this dataset */
- dataset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(dataset->ent.file);
+ dataset->shared->cache.contig.sieve_buf_size = H5F_SIEVE_BUF_SIZE(dataset->oloc.file);
break;
case H5D_CHUNKED:
/*
* Chunked storage. The creation plist's dimension is one less than
* the chunk dimension because the chunk includes a dimension for the
- * individual bytes of the data type.
+ * individual bytes of the datatype.
*/
{
unsigned chunk_ndims; /* Dimensionality of chunk */
@@ -2582,13 +2593,13 @@ H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id)
chunk_ndims = dataset->shared->layout.u.chunk.ndims - 1;
if(H5P_set(plist, H5D_CRT_CHUNK_DIM_NAME, &chunk_ndims) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set chunk dimensions")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set chunk dimensions")
if(H5P_set(plist, H5D_CRT_CHUNK_SIZE_NAME, dataset->shared->layout.u.chunk.dim) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set chunk size")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set chunk size")
/* Initialize the chunk cache for the dataset */
- if(H5D_istore_init(dataset->ent.file,dataset)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL, "can't initialize chunk cache")
+ if(H5D_istore_init(dataset->oloc.file, dataset)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't initialize chunk cache")
}
/* Set the I/O functions for this layout type */
@@ -2603,7 +2614,7 @@ H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id)
break;
default:
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet")
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "not implemented yet")
} /* end switch */ /*lint !e788 All appropriate cases are covered */
/* Point at dataset's copy, to cache it for later */
@@ -2611,12 +2622,12 @@ H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id)
/* Retrieve & release the previous fill-value settings */
if(H5P_get(plist, H5D_CRT_FILL_VALUE_NAME, fill_prop) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't get fill value")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't get fill value")
if(H5O_reset(H5O_FILL_ID, fill_prop)<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, NULL, "can't release fill info")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "can't release fill info")
/* Get the new fill value message */
- if(NULL == H5O_read(&(dataset->ent), H5O_FILL_NEW_ID, 0, &fill, dxpl_id)) {
+ if(NULL == H5O_read(&(dataset->oloc), H5O_FILL_NEW_ID, 0, &fill, dxpl_id)) {
H5E_clear_stack(NULL);
HDmemset(&fill, 0, sizeof(fill));
@@ -2635,7 +2646,7 @@ H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id)
break;
default:
- HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, NULL, "not implemented yet")
+ HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "not implemented yet")
} /* end switch */ /*lint !e788 All appropriate cases are covered */
/* Set the default fill time */
@@ -2643,18 +2654,18 @@ H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id)
} /* end if */
if(fill.fill_defined) {
if(NULL==H5O_copy(H5O_FILL_ID, &fill, fill_prop))
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "can't copy fill value")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "can't copy fill value")
} else {
/* For compatibility with v1.4. Retrieve the old fill value message.
* If size is 0, make it -1 for undefined. */
- if(NULL == H5O_read(&(dataset->ent), H5O_FILL_ID, 0, fill_prop, dxpl_id)) {
+ if(NULL == H5O_read(&(dataset->oloc), H5O_FILL_ID, 0, fill_prop, dxpl_id)) {
H5E_clear_stack(NULL);
HDmemset(fill_prop, 0, sizeof(H5O_fill_t));
- }
+ } /* end if */
if(fill_prop->size == 0) {
fill_prop->type = fill_prop->buf = NULL;
fill_prop->size = (size_t)-1;
- }
+ } /* end if */
} /* end else */
alloc_time_state=0;
if( (dataset->shared->layout.type==H5D_COMPACT && fill.alloc_time==H5D_ALLOC_TIME_EARLY)
@@ -2664,24 +2675,24 @@ H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id)
/* Set revised fill value properties */
if(H5P_set(plist, H5D_CRT_FILL_VALUE_NAME, fill_prop) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set fill value")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set fill value")
dataset->shared->alloc_time=fill.alloc_time; /* Cache this for later */
if(H5P_set(plist, H5D_CRT_ALLOC_TIME_NAME, &fill.alloc_time) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set allocation time")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set allocation time")
if(H5P_set(plist, H5D_CRT_ALLOC_TIME_STATE_NAME, &alloc_time_state) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set allocation time state")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set allocation time state")
dataset->shared->fill_time=fill.fill_time; /* Cache this for later */
if(H5P_set(plist, H5D_CRT_FILL_TIME_NAME, &fill.fill_time) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set fill time")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set fill time")
/* Get the external file list message, which might not exist. Space is
* also undefined when space allocate time is H5D_ALLOC_TIME_LATE. */
if((dataset->shared->layout.type==H5D_CONTIGUOUS && !H5F_addr_defined(dataset->shared->layout.u.contig.addr))
|| (dataset->shared->layout.type==H5D_CHUNKED && !H5F_addr_defined(dataset->shared->layout.u.chunk.addr))) {
HDmemset(&dataset->shared->efl,0,sizeof(H5O_efl_t));
- if(NULL != H5O_read(&(dataset->ent), H5O_EFL_ID, 0, &dataset->shared->efl, dxpl_id)) {
+ if(NULL != H5O_read(&(dataset->oloc), H5O_EFL_ID, 0, &dataset->shared->efl, dxpl_id)) {
if(H5P_set(plist, H5D_CRT_EXT_FILE_LIST_NAME, &dataset->shared->efl) < 0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, NULL, "can't set external file list")
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set external file list")
/* Override the I/O functions for this layout type */
dataset->shared->io_ops.readvv=H5D_efl_readvv;
@@ -2694,42 +2705,38 @@ H5D_open_oid(const H5G_entry_t *ent, hid_t dxpl_id)
* This is important only for parallel I/O where the space must
* be fully allocated before I/O can happen.
*/
- if ((H5F_get_intent(dataset->ent.file) & H5F_ACC_RDWR)
+ if((H5F_get_intent(dataset->oloc.file) & H5F_ACC_RDWR)
&& ((dataset->shared->layout.type==H5D_CONTIGUOUS && !H5F_addr_defined(dataset->shared->layout.u.contig.addr))
|| (dataset->shared->layout.type==H5D_CHUNKED && !H5F_addr_defined(dataset->shared->layout.u.chunk.addr)))
- && IS_H5FD_MPI(dataset->ent.file)) {
- if (H5D_alloc_storage(dataset->ent.file, dxpl_id, dataset,H5D_ALLOC_OPEN, TRUE, FALSE)<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL, "unable to initialize file storage")
- }
+ && IS_H5FD_MPI(dataset->oloc.file)) {
+ if(H5D_alloc_storage(dataset->oloc.file, dxpl_id, dataset,H5D_ALLOC_OPEN, TRUE, FALSE)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize file storage")
+ } /* end if */
/* Get the dataset's DCPL cache info */
- if (H5D_get_dcpl_cache(dataset->shared->dcpl_id,&dataset->shared->dcpl_cache)<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, NULL, "can't fill DCPL cache")
-
- /* Success */
- ret_value = dataset;
+ if(H5D_get_dcpl_cache(dataset->shared->dcpl_id,&dataset->shared->dcpl_cache)<0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill DCPL cache")
done:
/* Release fill value information */
- if (H5O_reset(H5O_FILL_ID, &fill) <0)
- HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, NULL, "unable to release fill-value info")
+ if(H5O_reset(H5O_FILL_ID, &fill) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to release fill-value info")
- if (ret_value==NULL && dataset) {
- if (H5F_addr_defined(dataset->ent.header)) {
- if(H5O_close(&(dataset->ent))<0)
- HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release object header")
+ if(ret_value < 0) {
+ if(H5F_addr_defined(dataset->oloc.addr)) {
+ if(H5O_close(&(dataset->oloc)) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release object header")
} /* end if */
- if (dataset->shared->space) {
- if(H5S_close(dataset->shared->space)<0)
- HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release dataspace")
+ if(dataset->shared->space) {
+ if(H5S_close(dataset->shared->space) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release dataspace")
} /* end if */
- if (dataset->shared->type) {
- if(H5I_dec_ref(dataset->shared->type_id)<0)
- HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, NULL, "unable to release datatype")
+ if(dataset->shared->type) {
+ if(H5I_dec_ref(dataset->shared->type_id) < 0)
+ HDONE_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release datatype")
} /* end if */
- dataset->ent.file = NULL;
- H5FL_FREE(H5D_t,dataset);
} /* end if */
+
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5D_open_oid() */
@@ -2757,7 +2764,7 @@ H5D_close(H5D_t *dataset)
FUNC_ENTER_NOAPI(H5D_close, FAIL)
/* check args */
- assert(dataset && dataset->ent.file && dataset->shared);
+ assert(dataset && dataset->oloc.file && dataset->shared);
assert(dataset->shared->fo_count >0);
/* Dump debugging info */
@@ -2775,7 +2782,7 @@ H5D_close(H5D_t *dataset)
/* Flush the raw data buffer, if its dirty */
if (dataset->shared->cache.contig.sieve_dirty) {
/* Write dirty data sieve buffer to file */
- if (H5F_block_write(dataset->ent.file, H5FD_MEM_DRAW, dataset->shared->cache.contig.sieve_loc,
+ if (H5F_block_write(dataset->oloc.file, H5FD_MEM_DRAW, dataset->shared->cache.contig.sieve_loc,
dataset->shared->cache.contig.sieve_size, H5AC_dxpl_id, dataset->shared->cache.contig.sieve_buf) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "block write failed")
@@ -2800,7 +2807,7 @@ H5D_close(H5D_t *dataset)
case H5D_COMPACT:
/* Update header message of layout for compact dataset. */
if(dataset->shared->layout.u.compact.dirty) {
- if(H5O_modify(&(dataset->ent), H5O_LAYOUT_ID, 0, 0, H5O_UPDATE_TIME, &(dataset->shared->layout), H5AC_dxpl_id)<0)
+ if(H5O_modify(&(dataset->oloc), H5O_LAYOUT_ID, 0, 0, H5O_UPDATE_TIME, &(dataset->shared->layout), H5AC_dxpl_id)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "unable to update layout message")
dataset->shared->layout.u.compact.dirty = FALSE;
} /* end if */
@@ -2824,15 +2831,15 @@ H5D_close(H5D_t *dataset)
H5I_dec_ref(dataset->shared->dcpl_id) < 0);
/* Remove the dataset from the list of opened objects in the file */
- if(H5FO_top_decr(dataset->ent.file, dataset->ent.header) < 0)
+ if(H5FO_top_decr(dataset->oloc.file, dataset->oloc.addr) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't decrement count for object")
- if(H5FO_delete(dataset->ent.file, H5AC_dxpl_id, dataset->ent.header)<0)
+ if(H5FO_delete(dataset->oloc.file, H5AC_dxpl_id, dataset->oloc.addr) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't remove dataset from list of open objects")
/* Close the dataset object */
/* (This closes the file, if this is the last object open) */
- if(H5O_close(&(dataset->ent))<0)
- HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release object header");
+ if(H5O_close(&(dataset->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CLOSEERROR, FAIL, "unable to release object header")
/*
* Free memory. Before freeing the memory set the file pointer to NULL.
@@ -2840,25 +2847,25 @@ H5D_close(H5D_t *dataset)
* sure we're not accessing an already freed dataset (see the assert()
* above).
*/
- dataset->ent.file = NULL;
+ dataset->oloc.file = NULL;
H5FL_FREE(H5D_shared_t,dataset->shared);
} /* end if */
else
{
/* Decrement the ref. count for this object in the top file */
- if(H5FO_top_decr(dataset->ent.file, dataset->ent.header) < 0)
+ if(H5FO_top_decr(dataset->oloc.file, dataset->oloc.addr) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTRELEASE, FAIL, "can't decrement count for object")
/* Check reference count for this object in the top file */
- if(H5FO_top_count(dataset->ent.file, dataset->ent.header) == 0)
- if(H5O_close(&(dataset->ent)) < 0)
+ if(H5FO_top_count(dataset->oloc.file, dataset->oloc.addr) == 0)
+ if(H5O_close(&(dataset->oloc)) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to close")
-
- if(H5G_free_ent_name(&dataset->ent)<0)
- free_failed=TRUE;
} /* end else */
+ if(H5G_name_free(&(dataset->path)) < 0)
+ free_failed=TRUE;
+
H5FL_FREE(H5D_t,dataset);
if (free_failed)
@@ -2903,12 +2910,12 @@ H5D_extend (H5D_t *dataset, const hsize_t *size, hid_t dxpl_id)
if(! dataset->shared->checked_filters)
{
if(H5P_is_fill_value_defined(&(dataset->shared->fill), &fill_status) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Couldn't retrieve fill value from dataset.");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Couldn't retrieve fill value from dataset.")
if(fill_status == H5D_FILL_VALUE_DEFAULT || fill_status == H5D_FILL_VALUE_USER_DEFINED)
{
if( H5Pget_fill_time(dataset->shared->dcpl_id, &fill_time) < 0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Couldn't retrieve fill time from dataset.");
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "Couldn't retrieve fill time from dataset.")
if(fill_time == H5D_FILL_TIME_ALLOC ||
(fill_time == H5D_FILL_TIME_IFSET && fill_status == H5D_FILL_VALUE_USER_DEFINED) )
@@ -2935,8 +2942,8 @@ H5D_extend (H5D_t *dataset, const hsize_t *size, hid_t dxpl_id)
if (changed>0){
/* Save the new dataspace in the file if necessary */
- if (H5S_modify (&(dataset->ent), space, TRUE, dxpl_id)<0)
- HGOTO_ERROR (H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update file with new dataspace")
+ if(H5S_modify (&(dataset->oloc), space, TRUE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update file with new dataspace")
/* Update the index values for the cached chunks for this dataset */
if(H5D_CHUNKED == dataset->shared->layout.type)
@@ -2944,8 +2951,8 @@ H5D_extend (H5D_t *dataset, const hsize_t *size, hid_t dxpl_id)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update cached chunk indices")
/* Allocate space for the new parts of the dataset, if appropriate */
- if(dataset->shared->alloc_time==H5D_ALLOC_TIME_EARLY || IS_H5FD_MPI(dataset->ent.file))
- if (H5D_alloc_storage(dataset->ent.file, dxpl_id, dataset, H5D_ALLOC_EXTEND, TRUE, FALSE)<0)
+ if(dataset->shared->alloc_time == H5D_ALLOC_TIME_EARLY || IS_H5FD_MPI(dataset->oloc.file))
+ if(H5D_alloc_storage(dataset->oloc.file, dxpl_id, dataset, H5D_ALLOC_EXTEND, TRUE, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value")
} /* end if */
@@ -2955,12 +2962,11 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5D_entof
+ * Function: H5D_oloc
*
- * Purpose: Returns a pointer to the entry for a dataset.
- *
- * Return: Success: Ptr to entry
+ * Purpose: Returns a pointer to the object location for a dataset.
*
+ * Return: Success: Ptr to location
* Failure: NULL
*
* Programmer: Robb Matzke
@@ -2968,23 +2974,46 @@ done:
*
*-------------------------------------------------------------------------
*/
-H5G_entry_t *
-H5D_entof (H5D_t *dataset)
+H5O_loc_t *
+H5D_oloc(H5D_t *dataset)
{
/* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_entof)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_oloc)
- FUNC_LEAVE_NOAPI( dataset ? &(dataset->ent) : (H5G_entry_t *)NULL)
-}
+ FUNC_LEAVE_NOAPI(dataset ? &(dataset->oloc) : (H5O_loc_t *)NULL)
+} /* end H5D_oloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_nameof
+ *
+ * Purpose: Returns a pointer to the group hier. path for a dataset.
+ *
+ * Return: Success: Ptr to entry
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 12, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+H5G_name_t *
+H5D_nameof(H5D_t *dataset)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_nameof)
+
+ FUNC_LEAVE_NOAPI(dataset ? &(dataset->path) : (H5G_name_t *)NULL)
+} /* end H5D_nameof() */
/*-------------------------------------------------------------------------
* Function: H5D_typeof
*
- * Purpose: Returns a pointer to the dataset's data type. The data type
+ * Purpose: Returns a pointer to the dataset's datatype. The datatype
* is not copied.
*
- * Return: Success: Ptr to the dataset's data type, uncopied.
+ * Return: Success: Ptr to the dataset's datatype, uncopied.
*
* Failure: NULL
*
@@ -3026,11 +3055,11 @@ H5D_get_file (const H5D_t *dset)
/* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_get_file)
- assert (dset);
- assert (dset->ent.file);
+ HDassert(dset);
+ HDassert(dset->oloc.file);
- FUNC_LEAVE_NOAPI(dset->ent.file)
-}
+ FUNC_LEAVE_NOAPI(dset->oloc.file)
+} /* end H5D_get_file() */
/*-------------------------------------------------------------------------
@@ -3101,9 +3130,9 @@ H5D_alloc_storage (H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_allo
* indicate that space should be allocated, so the
* B-tree gets expanded. -QAK
*/
- if((dset->shared->alloc_time==H5D_ALLOC_TIME_EARLY ||
- IS_H5FD_MPI(dset->ent.file)) &&
- time_alloc==H5D_ALLOC_EXTEND)
+ if((dset->shared->alloc_time == H5D_ALLOC_TIME_EARLY ||
+ IS_H5FD_MPI(dset->oloc.file)) &&
+ time_alloc == H5D_ALLOC_EXTEND)
{
init_space=1;
}
@@ -3170,9 +3199,9 @@ H5D_alloc_storage (H5F_t *f, hid_t dxpl_id, H5D_t *dset/*in,out*/, H5D_time_allo
/* Also update header message for layout with new address, if we
* set the address. (this is improves forward compatibility).
*/
- if(time_alloc!=H5D_ALLOC_CREATE && addr_set)
- if (H5O_modify (&(dset->ent), H5O_LAYOUT_ID, 0, H5O_FLAG_CONSTANT, update_time, &(dset->shared->layout), dxpl_id) < 0)
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message")
+ if(time_alloc != H5D_ALLOC_CREATE && addr_set)
+ if(H5O_modify(&(dset->oloc), H5O_LAYOUT_ID, 0, H5O_FLAG_CONSTANT, update_time, &(dset->shared->layout), dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update layout message")
} /* end if */
done:
@@ -3508,18 +3537,18 @@ H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator_t op,
H5TRACE5("e","xiixx",buf,type_id,space_id,op,operator_data);
/* Check args */
- if (NULL==op)
+ if(NULL==op)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid operator")
- if (buf==NULL)
+ if(buf==NULL)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid buffer")
- if (H5I_DATATYPE != H5I_get_type(type_id))
+ if(H5I_DATATYPE != H5I_get_type(type_id))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid datatype")
- if (NULL == (space = H5I_object_verify(space_id, H5I_DATASPACE)))
+ if(NULL == (space = H5I_object_verify(space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace")
- if( !(H5S_has_extent(space)) )
+ if(!(H5S_has_extent(space)) )
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set")
- ret_value=H5S_select_iterate(buf,type_id,space,op,operator_data);
+ ret_value = H5S_select_iterate(buf,type_id,space,op,operator_data);
done:
FUNC_LEAVE_API(ret_value)
@@ -3565,7 +3594,7 @@ H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf)
/* Get the allocation info */
if(H5T_vlen_get_alloc_info(plist_id,&vl_alloc_info)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info");
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTGET, FAIL, "unable to retrieve VL allocation info")
/* Call H5Diterate with args, etc. */
ret_value=H5Diterate(buf,type_id,space_id,H5T_vlen_reclaim,vl_alloc_info);
@@ -3639,29 +3668,29 @@ done:
static herr_t
H5D_vlen_get_buf_size(void UNUSED *elem, hid_t type_id, unsigned UNUSED ndim, const hsize_t *point, void *op_data)
{
- H5D_vlen_bufsize_t *vlen_bufsize=(H5D_vlen_bufsize_t *)op_data;
+ H5D_vlen_bufsize_t *vlen_bufsize = (H5D_vlen_bufsize_t *)op_data;
H5T_t *dt = NULL;
- herr_t ret_value=0; /* The correct return value, if this function succeeds */
+ herr_t ret_value = 0; /* The correct return value, if this function succeeds */
FUNC_ENTER_NOAPI(H5D_vlen_get_buf_size, FAIL)
- assert(op_data);
- assert(H5I_DATATYPE == H5I_get_type(type_id));
+ HDassert(op_data);
+ HDassert(H5I_DATATYPE == H5I_get_type(type_id));
/* Check args */
- if (NULL==(dt=H5I_object(type_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
+ if(NULL == (dt = H5I_object(type_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/* Make certain there is enough fixed-length buffer available */
- if ((vlen_bufsize->fl_tbuf=H5FL_BLK_REALLOC(vlen_fl_buf,vlen_bufsize->fl_tbuf,H5T_get_size(dt)))==NULL)
+ if((vlen_bufsize->fl_tbuf=H5FL_BLK_REALLOC(vlen_fl_buf, vlen_bufsize->fl_tbuf, H5T_get_size(dt))) == NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't resize tbuf")
/* Select point to read in */
- if (H5Sselect_elements(vlen_bufsize->fspace_id,H5S_SELECT_SET,1,(const hsize_t **)point)<0)
+ if(H5Sselect_elements(vlen_bufsize->fspace_id, H5S_SELECT_SET, 1, (const hsize_t **)point)<0)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't select point")
/* Read in the point (with the custom VL memory allocator) */
- if(H5Dread(vlen_bufsize->dataset_id,type_id,vlen_bufsize->mspace_id,vlen_bufsize->fspace_id,vlen_bufsize->xfer_pid,vlen_bufsize->fl_tbuf)<0)
+ if(H5Dread(vlen_bufsize->dataset_id, type_id, vlen_bufsize->mspace_id, vlen_bufsize->fspace_id, vlen_bufsize->xfer_pid, vlen_bufsize->fl_tbuf)<0)
HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "can't read point")
done:
@@ -3786,12 +3815,9 @@ done:
* Return: Success: SUCCEED, Failure: FAIL
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
- * Robb Matzke
*
* Date: April 9, 2002
*
- * Comments: Public function, calls private H5D_set_extent
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -3831,8 +3857,6 @@ done:
*
* Date: April 9, 2002
*
- * Comments: Private function
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -3887,7 +3911,7 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
*-------------------------------------------------------------------------
*/
/* Save the new dataspace in the file if necessary */
- if(H5S_modify(&(dset->ent), space, TRUE, dxpl_id) < 0)
+ if(H5S_modify(&(dset->oloc), space, TRUE, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to update file with new dataspace")
/* Update the index values for the cached chunks for this dataset */
@@ -3897,7 +3921,7 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id)
/* Allocate space for the new parts of the dataset, if appropriate */
if(expand && dset->shared->alloc_time==H5D_ALLOC_TIME_EARLY)
- if(H5D_alloc_storage(dset->ent.file, dxpl_id, dset, H5D_ALLOC_EXTEND, TRUE, FALSE) < 0)
+ if(H5D_alloc_storage(dset->oloc.file, dxpl_id, dset, H5D_ALLOC_EXTEND, TRUE, FALSE) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset storage")
@@ -4002,7 +4026,7 @@ H5D_flush(const H5F_t *f, hid_t dxpl_id, unsigned flags)
case H5D_COMPACT:
if(dataset->shared->layout.u.compact.dirty) {
- if(H5O_modify(&(dataset->ent), H5O_LAYOUT_ID, 0, 0, H5O_UPDATE_TIME, &(dataset->shared->layout), dxpl_id)<0)
+ if(H5O_modify(&(dataset->oloc), H5O_LAYOUT_ID, 0, 0, H5O_UPDATE_TIME, &(dataset->shared->layout), dxpl_id)<0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to update layout message")
dataset->shared->layout.u.compact.dirty = FALSE;
} /* end if */
@@ -4043,23 +4067,23 @@ done:
herr_t
H5Ddebug(hid_t dset_id)
{
- H5D_t *dset=NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5D_t *dset = NULL;
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Ddebug, FAIL)
H5TRACE1("e","i",dset_id);
/* Check args */
- if (NULL==(dset=H5I_object_verify(dset_id, H5I_DATASET)))
+ if(NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
/* Print B-tree information */
- if (H5D_CHUNKED==dset->shared->layout.type) {
- (void)H5D_istore_dump_btree(dset->ent.file, H5AC_dxpl_id, stdout, dset->shared->layout.u.chunk.ndims, dset->shared->layout.u.chunk.addr);
- } else if (H5D_CONTIGUOUS==dset->shared->layout.type) {
+ if(H5D_CHUNKED == dset->shared->layout.type)
+ (void)H5D_istore_dump_btree(dset->oloc.file, H5AC_dxpl_id, stdout, dset->shared->layout.u.chunk.ndims, dset->shared->layout.u.chunk.addr);
+ else if(H5D_CONTIGUOUS == dset->shared->layout.type)
HDfprintf(stdout, " %-10s %a\n", "Address:", dset->shared->layout.u.contig.addr);
- }
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Ddebug() */
+
diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c
index bd3b358..fd05e8c 100644
--- a/src/H5Dcontig.c
+++ b/src/H5Dcontig.c
@@ -155,13 +155,13 @@ H5D_contig_fill(H5D_t *dset, hid_t dxpl_id)
#ifdef H5_HAVE_PARALLEL
/* Retrieve MPI parameters */
- if(IS_H5FD_MPI(dset->ent.file)) {
+ if(IS_H5FD_MPI(dset->oloc.file)) {
/* Get the MPI communicator */
- if (MPI_COMM_NULL == (mpi_comm=H5F_mpi_get_comm(dset->ent.file)))
+ if(MPI_COMM_NULL == (mpi_comm = H5F_mpi_get_comm(dset->oloc.file)))
HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "Can't retrieve MPI communicator")
/* Get the MPI rank */
- if ((mpi_rank=H5F_mpi_get_rank(dset->ent.file))<0)
+ if((mpi_rank = H5F_mpi_get_rank(dset->oloc.file)) < 0)
HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "Can't retrieve MPI rank")
/* Set the MPI-capable file driver flag */
@@ -421,7 +421,7 @@ H5D_contig_readvv(const H5D_io_info_t *io_info,
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
void *_buf)
{
- H5F_t *file=io_info->dset->ent.file; /* File for dataset */
+ H5F_t *file = io_info->dset->oloc.file; /* File for dataset */
H5D_rdcdc_t *dset_contig=&(io_info->dset->shared->cache.contig); /* Cached information about contiguous data */
const H5D_contig_storage_t *store_contig=&(io_info->store->contig); /* Contiguous storage info for this I/O operation */
unsigned char *buf=(unsigned char *)_buf; /* Pointer to buffer to fill */
@@ -686,7 +686,7 @@ H5D_contig_writevv(const H5D_io_info_t *io_info,
size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[],
const void *_buf)
{
- H5F_t *file=io_info->dset->ent.file; /* File for dataset */
+ H5F_t *file = io_info->dset->oloc.file; /* File for dataset */
H5D_rdcdc_t *dset_contig=&(io_info->dset->shared->cache.contig); /* Cached information about contiguous data */
const H5D_contig_storage_t *store_contig=&(io_info->store->contig); /* Contiguous storage info for this I/O operation */
const unsigned char *buf=_buf; /* Pointer to buffer to fill */
@@ -750,6 +750,10 @@ H5D_contig_writevv(const H5D_io_info_t *io_info,
/* Allocate room for the data sieve buffer */
if (NULL==(dset_contig->sieve_buf=H5FL_BLK_MALLOC(sieve_buf,dset_contig->sieve_buf_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+#ifdef H5_USING_PURIFY
+if(dset_contig->sieve_size > size)
+ HDmemset(dset_contig->sieve_buf + size, 0, (dset_contig->sieve_size - size));
+#endif /* H5_USING_PURIFY */
/* Determine the new sieve buffer size & location */
dset_contig->sieve_loc=addr;
diff --git a/src/H5Dio.c b/src/H5Dio.c
index fdbfd0e..21face4 100644
--- a/src/H5Dio.c
+++ b/src/H5Dio.c
@@ -466,20 +466,20 @@ H5Dread(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
plist_id,buf);
/* check arguments */
- if (NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
+ if(NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
- if (NULL == dset->ent.file)
+ if(NULL == dset->oloc.file)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
- if (H5S_ALL != mem_space_id) {
- if (NULL == (mem_space = H5I_object_verify(mem_space_id, H5I_DATASPACE)))
+ if(H5S_ALL != mem_space_id) {
+ if(NULL == (mem_space = H5I_object_verify(mem_space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
/* Check for valid selection */
if(H5S_SELECT_VALID(mem_space)!=TRUE)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "selection+offset not within extent")
- }
- if (H5S_ALL != file_space_id) {
- if (NULL == (file_space = H5I_object_verify(file_space_id, H5I_DATASPACE)))
+ } /* end if */
+ if(H5S_ALL != file_space_id) {
+ if(NULL == (file_space = H5I_object_verify(file_space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
/* Check for valid selection */
@@ -550,38 +550,38 @@ H5Dwrite(hid_t dset_id, hid_t mem_type_id, hid_t mem_space_id,
plist_id,buf);
/* check arguments */
- if (NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
+ if(NULL == (dset = H5I_object_verify(dset_id, H5I_DATASET)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
- if (NULL == dset->ent.file)
+ if(NULL == dset->oloc.file)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset")
- if (H5S_ALL != mem_space_id) {
- if (NULL == (mem_space = H5I_object_verify(mem_space_id, H5I_DATASPACE)))
+ if(H5S_ALL != mem_space_id) {
+ if(NULL == (mem_space = H5I_object_verify(mem_space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
/* Check for valid selection */
if (H5S_SELECT_VALID(mem_space)!=TRUE)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "memory selection+offset not within extent")
- }
- if (H5S_ALL != file_space_id) {
- if (NULL == (file_space = H5I_object_verify(file_space_id, H5I_DATASPACE)))
+ } /* end if */
+ if(H5S_ALL != file_space_id) {
+ if(NULL == (file_space = H5I_object_verify(file_space_id, H5I_DATASPACE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data space")
/* Check for valid selection */
- if (H5S_SELECT_VALID(file_space)!=TRUE)
+ if(H5S_SELECT_VALID(file_space)!=TRUE)
HGOTO_ERROR(H5E_DATASPACE, H5E_BADRANGE, FAIL, "file selection+offset not within extent")
- }
+ } /* end if */
/* Get the default dataset transfer property list if the user didn't provide one */
- if (H5P_DEFAULT == plist_id)
+ if(H5P_DEFAULT == plist_id)
plist_id= H5P_DATASET_XFER_DEFAULT;
else
- if (TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
+ if(TRUE!=H5P_isa_class(plist_id,H5P_DATASET_XFER))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not xfer parms")
- if (!buf && H5S_GET_SELECT_NPOINTS(file_space)!=0)
+ if(!buf && H5S_GET_SELECT_NPOINTS(file_space)!=0)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no output buffer")
/* write raw data */
- if (H5D_write(dset, mem_type_id, mem_space, file_space, plist_id, buf) < 0)
+ if(H5D_write(dset, mem_type_id, mem_space, file_space, plist_id, buf) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "can't write data")
done:
@@ -611,7 +611,9 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
H5T_path_t *tpath = NULL; /*type conversion info */
const H5T_t *mem_type = NULL; /* Memory datatype */
H5D_io_info_t io_info; /* Dataset I/O info */
+#ifdef H5_HAVE_PARALLEL
hbool_t io_info_init = FALSE; /* Whether the I/O info has been initialized */
+#endif /*H5_HAVE_PARALLEL*/
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
H5D_dxpl_cache_t *dxpl_cache=&_dxpl_cache; /* Data transfer property cache */
herr_t ret_value = SUCCEED; /* Return value */
@@ -619,27 +621,27 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
FUNC_ENTER_NOAPI_NOINIT(H5D_read)
/* check args */
- assert(dataset && dataset->ent.file);
+ HDassert(dataset && dataset->oloc.file);
/* Get memory datatype */
- if (NULL == (mem_type = H5I_object_verify(mem_type_id, H5I_DATATYPE)))
+ if(NULL == (mem_type = H5I_object_verify(mem_type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
- if (!file_space)
+ if(!file_space)
file_space = dataset->shared->space;
- if (!mem_space)
+ if(!mem_space)
mem_space = file_space;
if((snelmts = H5S_GET_SELECT_NPOINTS(mem_space))<0)
HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection")
H5_ASSIGN_OVERFLOW(nelmts,snelmts,hssize_t,hsize_t);
/* Fill the DXPL cache values for later use */
- if (H5D_get_dxpl_cache(dxpl_id,&dxpl_cache)<0)
+ if(H5D_get_dxpl_cache(dxpl_id,&dxpl_cache)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
#ifdef H5_HAVE_PARALLEL
/* Collective access is not permissible without a MPI based VFD */
- if (dxpl_cache->xfer_mode==H5FD_MPIO_COLLECTIVE && !IS_H5FD_MPI(dataset->ent.file))
+ if (dxpl_cache->xfer_mode==H5FD_MPIO_COLLECTIVE && !IS_H5FD_MPI(dataset->oloc.file))
HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "collective access for MPI-based drivers only")
#endif /*H5_HAVE_PARALLEL*/
@@ -701,7 +703,9 @@ H5D_read(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
/* Set up I/O operation */
if(H5D_ioinfo_init(dataset,dxpl_cache,dxpl_id,mem_space,file_space,tpath,&io_info)<0)
HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to set up I/O operation")
+#ifdef H5_HAVE_PARALLEL
io_info_init = TRUE;
+#endif /*H5_HAVE_PARALLEL*/
/* Determine correct I/O routine to invoke */
if(dataset->shared->layout.type!=H5D_CHUNKED) {
@@ -749,7 +753,9 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
H5T_path_t *tpath = NULL; /*type conversion info */
const H5T_t *mem_type = NULL; /* Memory datatype */
H5D_io_info_t io_info; /* Dataset I/O info */
+#ifdef H5_HAVE_PARALLEL
hbool_t io_info_init = FALSE; /* Whether the I/O info has been initialized */
+#endif /*H5_HAVE_PARALLEL*/
H5D_dxpl_cache_t _dxpl_cache; /* Data transfer property cache buffer */
H5D_dxpl_cache_t *dxpl_cache=&_dxpl_cache; /* Data transfer property cache */
herr_t ret_value = SUCCEED; /* Return value */
@@ -757,31 +763,30 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
FUNC_ENTER_NOAPI_NOINIT(H5D_write)
/* check args */
- assert(dataset && dataset->ent.file);
+ HDassert(dataset && dataset->oloc.file);
/* Get the memory datatype */
- if (NULL == (mem_type = H5I_object_verify(mem_type_id, H5I_DATATYPE)))
+ if(NULL == (mem_type = H5I_object_verify(mem_type_id, H5I_DATATYPE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type")
/* All filters in the DCPL must have encoding enabled. */
- if(! dataset->shared->checked_filters)
- {
+ if(!dataset->shared->checked_filters) {
if(H5Z_can_apply(dataset->shared->dcpl_id, dataset->shared->type_id) <0)
HGOTO_ERROR(H5E_PLINE, H5E_CANAPPLY, FAIL, "can't apply filters")
dataset->shared->checked_filters = TRUE;
- }
+ } /* end if */
/* Check if we are allowed to write to this file */
- if (0==(H5F_get_intent(dataset->ent.file) & H5F_ACC_RDWR))
+ if(0==(H5F_get_intent(dataset->oloc.file) & H5F_ACC_RDWR))
HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Fill the DXPL cache values for later use */
- if (H5D_get_dxpl_cache(dxpl_id,&dxpl_cache)<0)
+ if(H5D_get_dxpl_cache(dxpl_id,&dxpl_cache) < 0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't fill dxpl cache")
/* Various MPI based checks */
- if (IS_H5FD_MPI(dataset->ent.file)) {
+ if(IS_H5FD_MPI(dataset->oloc.file)) {
/* If MPI based VFD is used, no VL datatype support yet. */
/* This is because they use the global heap in the file and we don't */
/* support parallel access of that yet */
@@ -835,17 +840,17 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
hbool_t full_overwrite; /* Whether we are over-writing all the elements */
/* Get the number of elements in file dataset's dataspace */
- if((file_nelmts=H5S_GET_EXTENT_NPOINTS(file_space))<0)
+ if((file_nelmts = H5S_GET_EXTENT_NPOINTS(file_space)) < 0)
HGOTO_ERROR (H5E_DATASET, H5E_BADVALUE, FAIL, "can't retrieve number of elements in file dataset")
/* Always allow fill values to be written if the dataset has a VL datatype */
if(H5T_detect_class(dataset->shared->type, H5T_VLEN))
- full_overwrite=FALSE;
+ full_overwrite = FALSE;
else
- full_overwrite=(hsize_t)file_nelmts==nelmts ? TRUE : FALSE;
+ full_overwrite = (hsize_t)file_nelmts==nelmts ? TRUE : FALSE;
/* Allocate storage */
- if(H5D_alloc_storage(dataset->ent.file,dxpl_id,dataset,H5D_ALLOC_WRITE, TRUE, full_overwrite)<0)
+ if(H5D_alloc_storage(dataset->oloc.file, dxpl_id, dataset, H5D_ALLOC_WRITE, TRUE, full_overwrite)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize storage")
} /* end if */
@@ -863,7 +868,9 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
/* Set up I/O operation */
if(H5D_ioinfo_init(dataset,dxpl_cache,dxpl_id,mem_space,file_space,tpath,&io_info)<0)
HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to set up I/O operation")
+#ifdef H5_HAVE_PARALLEL
io_info_init = TRUE;
+#endif /*H5_HAVE_PARALLEL*/
/* Determine correct I/O routine to invoke */
if(dataset->shared->layout.type!=H5D_CHUNKED) {
@@ -888,7 +895,7 @@ H5D_write(H5D_t *dataset, hid_t mem_type_id, const H5S_t *mem_space,
* Update modification time. We have to do this explicitly because
* writing to a dataset doesn't necessarily change the object header.
*/
- if (H5O_touch(&(dataset->ent), FALSE, dxpl_id)<0)
+ if (H5O_touch(&(dataset->oloc), FALSE, dxpl_id)<0)
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to update modification time")
#endif /* OLD_WAY */
@@ -3020,7 +3027,7 @@ H5D_ioinfo_init(H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id,
/* check args */
HDassert(dset);
- HDassert(dset->ent.file);
+ HDassert(dset->oloc.file);
HDassert(mem_space);
HDassert(file_space);
HDassert(tpath);
@@ -3039,11 +3046,11 @@ H5D_ioinfo_init(H5D_t *dset, const H5D_dxpl_cache_t *dxpl_cache, hid_t dxpl_id,
/* Start in the "not modified" xfer_mode state */
io_info->xfer_mode_changed = FALSE;
- if(IS_H5FD_MPI(dset->ent.file)) {
+ if(IS_H5FD_MPI(dset->oloc.file)) {
htri_t opt; /* Flag whether a selection is optimizable */
/* Get MPI communicator */
- if((io_info->comm = H5F_mpi_get_comm(dset->ent.file)) == MPI_COMM_NULL)
+ if((io_info->comm = H5F_mpi_get_comm(dset->oloc.file)) == MPI_COMM_NULL)
HGOTO_ERROR(H5E_DATASPACE, H5E_CANTGET, FAIL, "can't retrieve MPI communicator")
/*
diff --git a/src/H5Distore.c b/src/H5Distore.c
index b0d60d6..54fd2a1 100644
--- a/src/H5Distore.c
+++ b/src/H5Distore.c
@@ -1069,9 +1069,9 @@ H5D_istore_flush_entry(const H5D_io_info_t *io_info, H5D_rdcc_ent_t *ent, hbool_
* Create the chunk it if it doesn't exist, or reallocate the chunk if
* its size changed. Then write the data into the file.
*/
- if (H5B_insert(io_info->dset->ent.file, io_info->dxpl_id, H5B_ISTORE, io_info->dset->shared->layout.u.chunk.addr, &udata)<0)
+ if(H5B_insert(io_info->dset->oloc.file, io_info->dxpl_id, H5B_ISTORE, io_info->dset->shared->layout.u.chunk.addr, &udata)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk")
- if (H5F_block_write(io_info->dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, io_info->dxpl_id, buf)<0)
+ if(H5F_block_write(io_info->dset->oloc.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, io_info->dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
/* Mark cache entry as clean */
@@ -1416,7 +1416,7 @@ H5D_istore_prune (const H5D_io_info_t *io_info, size_t size)
* begins. The pointers participating in the list traversal are each
* given a chance at preemption before any of the pointers are advanced.
*/
- w[0] = (int)(rdcc->nused * H5F_RDCC_W0(io_info->dset->ent.file));
+ w[0] = (int)(rdcc->nused * H5F_RDCC_W0(io_info->dset->oloc.file));
p[0] = rdcc->head;
p[1] = NULL;
@@ -1613,16 +1613,16 @@ H5D_istore_lock(const H5D_io_info_t *io_info,
/* Chunk size on disk isn't [likely] the same size as the final chunk
* size in memory, so allocate memory big enough. */
chunk_alloc = udata->common.key.nbytes;
- if (NULL==(chunk = H5D_istore_chunk_alloc (chunk_alloc,pline)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk")
- if (H5F_block_read(dset->ent.file, H5FD_MEM_DRAW, chunk_addr, udata->common.key.nbytes, io_info->dxpl_id, chunk)<0)
- HGOTO_ERROR (H5E_IO, H5E_READERROR, NULL, "unable to read raw data chunk")
-
- if (pline->nused)
- if (H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &(udata->common.key.filter_mask), io_info->dxpl_cache->err_detect,
- io_info->dxpl_cache->filter_cb, &(udata->common.key.nbytes), &chunk_alloc, &chunk)<0) {
+ if(NULL == (chunk = H5D_istore_chunk_alloc (chunk_alloc, pline)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for raw data chunk")
+ if(H5F_block_read(dset->oloc.file, H5FD_MEM_DRAW, chunk_addr, udata->common.key.nbytes, io_info->dxpl_id, chunk) < 0)
+ HGOTO_ERROR(H5E_IO, H5E_READERROR, NULL, "unable to read raw data chunk")
+
+ if(pline->nused) {
+ if(H5Z_pipeline(pline, H5Z_FLAG_REVERSE, &(udata->common.key.filter_mask), io_info->dxpl_cache->err_detect,
+ io_info->dxpl_cache->filter_cb, &(udata->common.key.nbytes), &chunk_alloc, &chunk) < 0)
HGOTO_ERROR(H5E_PLINE, H5E_READERROR, NULL, "data pipeline read failed")
- }
+ } /* end if */
#ifdef H5D_ISTORE_DEBUG
rdcc->nmisses++;
#endif /* H5D_ISTORE_DEBUG */
@@ -1923,7 +1923,7 @@ HDfprintf(stderr,"%s: buf=%p\n",FUNC,buf);
* read-through of only the elements requested.
*/
if (dset->shared->dcpl_cache.pline.nused==0 && ((dset->shared->layout.u.chunk.size>dset->shared->cache.chunk.nbytes && chunk_addr!=HADDR_UNDEF)
- || (IS_H5FD_MPI(dset->ent.file) && (H5F_ACC_RDWR & H5F_get_intent(dset->ent.file))))) {
+ || (IS_H5FD_MPI(dset->oloc.file) && (H5F_ACC_RDWR & H5F_get_intent(dset->oloc.file))))) {
H5D_io_info_t chk_io_info; /* Temporary I/O info object */
H5D_storage_t chk_store; /* Chunk storage information */
@@ -1960,7 +1960,7 @@ HDfprintf(stderr,"%s: buf=%p\n",FUNC,buf);
/* Check if the chunk is in the cache (but hasn't been written to disk yet) */
if (rdcc->nslots>0) {
- unsigned idx=H5D_HASH(dset->shared,io_info->store->chunk.index); /* Cache entry index */
+ unsigned idx=H5D_HASH(dset->shared, io_info->store->chunk.index); /* Cache entry index */
H5D_rdcc_ent_t *ent = rdcc->slot[idx]; /* Cache entry */
/* Potential match... */
@@ -2114,7 +2114,7 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a
*/
#ifdef H5_HAVE_PARALLEL
/* Additional sanity checks when operating in parallel */
- if(IS_H5FD_MPI(dset->ent.file)) {
+ if(IS_H5FD_MPI(dset->oloc.file)) {
if (chunk_addr==HADDR_UNDEF)
HGOTO_ERROR (H5E_IO, H5E_WRITEERROR, FAIL, "unable to locate raw data chunk")
if (dset->shared->dcpl_cache.pline.nused>0)
@@ -2123,7 +2123,7 @@ HDfprintf(stderr,"%s: mem_offset_arr[%Zu]=%Hu\n",FUNC,*mem_curr_seq,mem_offset_a
#endif /* H5_HAVE_PARALLEL */
if (dset->shared->dcpl_cache.pline.nused==0 && ((dset->shared->layout.u.chunk.size>dset->shared->cache.chunk.nbytes && chunk_addr!=HADDR_UNDEF)
- || (IS_H5FD_MPI(dset->ent.file) && (H5F_ACC_RDWR & H5F_get_intent(dset->ent.file))))) {
+ || (IS_H5FD_MPI(dset->oloc.file) && (H5F_ACC_RDWR & H5F_get_intent(dset->oloc.file))))) {
H5D_io_info_t chk_io_info; /* Temporary I/O info object */
H5D_storage_t chk_store; /* Chunk storage information */
@@ -2291,7 +2291,7 @@ H5D_istore_allocated(H5D_t *dset, hid_t dxpl_id)
HDmemset(&udata, 0, sizeof udata);
udata.common.mesg = &dset->shared->layout;
- if (H5B_iterate(dset->ent.file, dxpl_id, H5B_ISTORE, H5D_istore_iter_allocated, dset->shared->layout.u.chunk.addr, &udata)<0)
+ if(H5B_iterate(dset->oloc.file, dxpl_id, H5B_ISTORE, H5D_istore_iter_allocated, dset->shared->layout.u.chunk.addr, &udata) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, 0, "unable to iterate over chunk B-tree")
/* Set return value */
@@ -2341,7 +2341,7 @@ H5D_istore_get_addr(const H5D_io_info_t *io_info, H5D_istore_ud1_t *_udata)
udata->addr = HADDR_UNDEF;
/* Go get the chunk information */
- if (H5B_find (io_info->dset->ent.file, io_info->dxpl_id, H5B_ISTORE, io_info->dset->shared->layout.u.chunk.addr, udata)<0) {
+ if (H5B_find (io_info->dset->oloc.file, io_info->dxpl_id, H5B_ISTORE, io_info->dset->shared->layout.u.chunk.addr, udata)<0) {
/* Note: don't push error on stack, leave that to next higher level,
* since many times the B-tree is searched in order to determine
* if a chunk exists in the B-tree or not. -QAK
@@ -2516,13 +2516,13 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
#ifdef H5_HAVE_PARALLEL
/* Retrieve MPI parameters */
- if(IS_H5FD_MPI(dset->ent.file)) {
+ if(IS_H5FD_MPI(dset->oloc.file)) {
/* Get the MPI communicator */
- if (MPI_COMM_NULL == (mpi_comm=H5F_mpi_get_comm(dset->ent.file)))
+ if(MPI_COMM_NULL == (mpi_comm = H5F_mpi_get_comm(dset->oloc.file)))
HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "Can't retrieve MPI communicator")
/* Get the MPI rank */
- if ((mpi_rank=H5F_mpi_get_rank(dset->ent.file))<0)
+ if((mpi_rank = H5F_mpi_get_rank(dset->oloc.file))<0)
HGOTO_ERROR(H5E_INTERNAL, H5E_MPI, FAIL, "Can't retrieve MPI rank")
/* Set the MPI-capable file driver flag */
@@ -2627,7 +2627,7 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
udata.common.key.offset[u] = chunk_offset[u];
/* Allocate the chunk with all processes */
- if (H5B_insert(dset->ent.file, dxpl_id, H5B_ISTORE, dset->shared->layout.u.chunk.addr, &udata)<0)
+ if(H5B_insert(dset->oloc.file, dxpl_id, H5B_ISTORE, dset->shared->layout.u.chunk.addr, &udata)<0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to allocate chunk")
/* Check if fill values should be written to blocks */
@@ -2638,7 +2638,7 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
/* Write the chunks out from only one process */
/* !! Use the internal "independent" DXPL!! -QAK */
if(H5_PAR_META_WRITE==mpi_rank) {
- if (H5F_block_write(dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, H5AC_ind_dxpl_id, chunk)<0)
+ if(H5F_block_write(dset->oloc.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, H5AC_ind_dxpl_id, chunk) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
} /* end if */
@@ -2647,7 +2647,7 @@ H5D_istore_allocate(H5D_t *dset, hid_t dxpl_id, hbool_t full_overwrite)
} /* end if */
else {
#endif /* H5_HAVE_PARALLEL */
- if (H5F_block_write(dset->ent.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, dxpl_id, chunk)<0)
+ if(H5F_block_write(dset->oloc.file, H5FD_MEM_DRAW, udata.addr, udata.common.key.nbytes, dxpl_id, chunk) < 0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "unable to write raw data to file")
#ifdef H5_HAVE_PARALLEL
} /* end else */
@@ -2852,7 +2852,7 @@ H5D_istore_prune_by_extent(const H5D_io_info_t *io_info)
udata.common.mesg = &dset->shared->layout;
udata.dims = curr_dims;
- if(H5B_iterate(dset->ent.file, io_info->dxpl_id, H5B_ISTORE, H5D_istore_prune_extent, dset->shared->layout.u.chunk.addr, &udata) < 0)
+ if(H5B_iterate(dset->oloc.file, io_info->dxpl_id, H5B_ISTORE, H5D_istore_prune_extent, dset->shared->layout.u.chunk.addr, &udata) < 0)
HGOTO_ERROR(H5E_IO, H5E_CANTINIT, 0, "unable to iterate over B-tree")
done:
diff --git a/src/H5Dmpio.c b/src/H5Dmpio.c
index f4b3450..9d8821a 100644
--- a/src/H5Dmpio.c
+++ b/src/H5Dmpio.c
@@ -106,7 +106,7 @@ H5D_mpio_opt_possible( const H5D_io_info_t *io_info,
/* Optimized MPI types flag must be set and it is must be collective IO */
/* (Don't allow parallel I/O for the MPI-posix driver, since it doesn't do real collective I/O) */
- if (!(H5S_mpi_opt_types_g && io_info->dxpl_cache->xfer_mode==H5FD_MPIO_COLLECTIVE && !IS_H5FD_MPIPOSIX(io_info->dset->ent.file))) {
+ if (!(H5S_mpi_opt_types_g && io_info->dxpl_cache->xfer_mode==H5FD_MPIO_COLLECTIVE && !IS_H5FD_MPIPOSIX(io_info->dset->oloc.file))) {
local_opinion = FALSE;
goto broadcast;
} /* end if */
@@ -230,7 +230,7 @@ H5D_mpio_spaces_xfer(H5D_io_info_t *io_info, size_t elmt_size,
assert (file_space);
assert (mem_space);
assert (buf);
- assert (IS_H5FD_MPIO(io_info->dset->ent.file));
+ assert (IS_H5FD_MPIO(io_info->dset->oloc.file));
/* Make certain we have the correct type of property list */
assert(TRUE==H5P_isa_class(io_info->dxpl_id,H5P_DATASET_XFER));
@@ -260,7 +260,7 @@ H5D_mpio_spaces_xfer(H5D_io_info_t *io_info, size_t elmt_size,
assert(io_info->dset->shared->layout.type == H5D_CHUNKED);
chunk_addr=H5D_istore_get_addr(io_info,NULL);
- addr = H5F_BASE_ADDR(io_info->dset->ent.file) + chunk_addr + mpi_file_offset;
+ addr = H5F_BASE_ADDR(io_info->dset->oloc.file) + chunk_addr + mpi_file_offset;
}
/*
@@ -276,10 +276,10 @@ H5D_mpio_spaces_xfer(H5D_io_info_t *io_info, size_t elmt_size,
/* transfer the data */
if (do_write) {
- if (H5F_block_write(io_info->dset->ent.file, H5FD_MEM_DRAW, addr, mpi_buf_count, io_info->dxpl_id, buf) <0)
+ if (H5F_block_write(io_info->dset->oloc.file, H5FD_MEM_DRAW, addr, mpi_buf_count, io_info->dxpl_id, buf) <0)
HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL,"MPI write failed");
} else {
- if (H5F_block_read (io_info->dset->ent.file, H5FD_MEM_DRAW, addr, mpi_buf_count, io_info->dxpl_id, buf) <0)
+ if (H5F_block_read (io_info->dset->oloc.file, H5FD_MEM_DRAW, addr, mpi_buf_count, io_info->dxpl_id, buf) <0)
HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL,"MPI read failed");
}
diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h
index 651f2b8..30efde1 100644
--- a/src/H5Dpkg.h
+++ b/src/H5Dpkg.h
@@ -174,7 +174,8 @@ typedef struct H5D_shared_t {
} H5D_shared_t;
struct H5D_t {
- H5G_entry_t ent; /* cached object header stuff */
+ H5O_loc_t oloc; /* Object header location */
+ H5G_name_t path; /* Group hierarchy path */
H5D_shared_t *shared; /* cached information from file */
};
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index dcd7f86..a9367dc 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -221,10 +221,11 @@ typedef struct H5D_dcpl_cache_t {
/* Library Private Prototypes */
/******************************/
H5_DLL herr_t H5D_init(void);
-H5_DLL H5D_t *H5D_open(const H5G_entry_t *ent, hid_t dxpl_id);
+H5_DLL H5D_t *H5D_open(const H5G_loc_t *loc, hid_t dxpl_id);
H5_DLL herr_t H5D_close(H5D_t *dataset);
-H5_DLL htri_t H5D_isa(H5G_entry_t *ent, hid_t dxpl_id);
-H5_DLL H5G_entry_t *H5D_entof(H5D_t *dataset);
+H5_DLL htri_t H5D_isa(H5O_loc_t *loc, hid_t dxpl_id);
+H5_DLL H5O_loc_t *H5D_oloc(H5D_t *dataset);
+H5_DLL H5G_name_t *H5D_nameof(H5D_t *dataset);
H5_DLL H5T_t *H5D_typeof(const H5D_t *dset);
H5_DLL herr_t H5D_crt_copy(hid_t new_plist_t, hid_t old_plist_t,
void *copy_data);
diff --git a/src/H5Edefin.h b/src/H5Edefin.h
index 03065e6..12582f4 100644
--- a/src/H5Edefin.h
+++ b/src/H5Edefin.h
@@ -89,6 +89,7 @@ hid_t H5E_ALIGNMENT_g = FAIL; /* Alignment error */
hid_t H5E_BADMESG_g = FAIL; /* Unrecognized message */
hid_t H5E_CANTDELETE_g = FAIL; /* Can't delete message */
hid_t H5E_BADITER_g = FAIL; /* Iteration failed */
+hid_t H5E_CANTPACK_g = FAIL; /* Can't pack messages */
/* FPHDF5 errors */
hid_t H5E_CANTRECV_g = FAIL; /* Can't receive messages from processes */
diff --git a/src/H5Einit.h b/src/H5Einit.h
index 0efa7e6..bf31088 100644
--- a/src/H5Einit.h
+++ b/src/H5Einit.h
@@ -315,6 +315,11 @@ if((msg = H5E_create_msg(cls, H5E_MINOR, "Iteration failed"))==NULL)
HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
if((H5E_BADITER_g = H5I_register(H5I_ERROR_MSG, msg))<0)
HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
+assert(H5E_CANTPACK_g==(-1));
+if((msg = H5E_create_msg(cls, H5E_MINOR, "Can't pack messages"))==NULL)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTINIT, FAIL, "error message initialization failed")
+if((H5E_CANTPACK_g = H5I_register(H5I_ERROR_MSG, msg))<0)
+ HGOTO_ERROR(H5E_ERROR, H5E_CANTREGISTER, FAIL, "can't register error message")
/* FPHDF5 errors */
assert(H5E_CANTRECV_g==(-1));
diff --git a/src/H5Epubgen.h b/src/H5Epubgen.h
index f694109..4245a5c 100644
--- a/src/H5Epubgen.h
+++ b/src/H5Epubgen.h
@@ -143,12 +143,14 @@ H5_DLLVAR hid_t H5E_DUPCLASS_g; /* Duplicate class name in parent class */
#define H5E_BADMESG (H5OPEN H5E_BADMESG_g)
#define H5E_CANTDELETE (H5OPEN H5E_CANTDELETE_g)
#define H5E_BADITER (H5OPEN H5E_BADITER_g)
+#define H5E_CANTPACK (H5OPEN H5E_CANTPACK_g)
H5_DLLVAR hid_t H5E_LINKCOUNT_g; /* Bad object header link count */
H5_DLLVAR hid_t H5E_VERSION_g; /* Wrong version number */
H5_DLLVAR hid_t H5E_ALIGNMENT_g; /* Alignment error */
H5_DLLVAR hid_t H5E_BADMESG_g; /* Unrecognized message */
H5_DLLVAR hid_t H5E_CANTDELETE_g; /* Can't delete message */
H5_DLLVAR hid_t H5E_BADITER_g; /* Iteration failed */
+H5_DLLVAR hid_t H5E_CANTPACK_g; /* Can't pack messages */
/* FPHDF5 errors */
#define H5E_CANTRECV (H5OPEN H5E_CANTRECV_g)
diff --git a/src/H5Eterm.h b/src/H5Eterm.h
index e36a5ab..00eee70 100644
--- a/src/H5Eterm.h
+++ b/src/H5Eterm.h
@@ -90,7 +90,8 @@ H5E_VERSION_g=
H5E_ALIGNMENT_g=
H5E_BADMESG_g=
H5E_CANTDELETE_g=
-H5E_BADITER_g=
+H5E_BADITER_g=
+H5E_CANTPACK_g=
/* FPHDF5 errors */
H5E_CANTRECV_g=
diff --git a/src/H5F.c b/src/H5F.c
index 9665e1a..3f79fa1 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -28,8 +28,8 @@
#include "H5FDprivate.h" /* File drivers */
#include "H5FLprivate.h" /* Free lists */
#include "H5FPprivate.h" /* Flexible parallel */
-#include "H5Iprivate.h" /* IDs */
#include "H5Gprivate.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
#include "H5Pprivate.h" /* Property lists */
#include "H5Tprivate.h" /* Datatypes */
@@ -1157,23 +1157,23 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key)
HGOTO_DONE(TRUE) /* Indicate that the iterator should stop */
}
} else { /* either count opened object IDs or put the IDs on the list */
- H5G_entry_t *ent; /* Group entry info for object */
+ H5O_loc_t *oloc; /* Group entry info for object */
switch(olist->obj_type) {
case H5I_ATTR:
- ent = H5A_entof((H5A_t*)obj_ptr);
+ oloc = H5A_oloc((H5A_t*)obj_ptr);
break;
case H5I_GROUP:
- ent = H5G_entof((H5G_t*)obj_ptr);
+ oloc = H5G_oloc((H5G_t*)obj_ptr);
break;
case H5I_DATASET:
- ent = H5D_entof((H5D_t*)obj_ptr);
+ oloc = H5D_oloc((H5D_t*)obj_ptr);
break;
case H5I_DATATYPE:
if(H5T_is_named((H5T_t*)obj_ptr)==TRUE)
- ent = H5T_entof((H5T_t*)obj_ptr);
+ oloc = H5T_oloc((H5T_t*)obj_ptr);
else
- ent = NULL;
+ oloc = NULL;
break;
default:
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object")
@@ -1182,11 +1182,11 @@ H5F_get_objects_cb(void *obj_ptr, hid_t obj_id, void *key)
if((olist->file_info.local &&
( (!olist->file_info.ptr.file && olist->obj_type==H5I_DATATYPE && H5T_is_immutable((H5T_t*)obj_ptr)==FALSE)
|| (!olist->file_info.ptr.file && olist->obj_type!=H5I_DATATYPE)
- || (ent && ent->file == olist->file_info.ptr.file) ))
+ || (oloc && oloc->file == olist->file_info.ptr.file) ))
|| (!olist->file_info.local &&
((!olist->file_info.ptr.shared && olist->obj_type==H5I_DATATYPE && H5T_is_immutable((H5T_t*)obj_ptr)==FALSE)
|| (!olist->file_info.ptr.shared && olist->obj_type!=H5I_DATATYPE)
- || (ent && ent->file && ent->file->shared == olist->file_info.ptr.shared) ))) {
+ || (oloc && oloc->file && oloc->file->shared == olist->file_info.ptr.shared) ))) {
/* Add the object's ID to the ID list, if appropriate */
if(olist->obj_id_list) {
olist->obj_id_list[olist->list_index] = obj_id;
@@ -1749,7 +1749,9 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
H5F_t *file = NULL; /*the success return value */
H5F_file_t *shared = NULL; /*shared part of `file' */
H5FD_t *lf = NULL; /*file driver part of `shared' */
- H5G_entry_t root_ent; /*root symbol table entry */
+ H5G_loc_t root_loc; /*root location */
+ H5O_loc_t root_oloc; /*root object location */
+ H5G_name_t root_path; /*root group hier. path */
unsigned tent_flags; /*tentative flags */
H5FD_class_t *drvr; /*file driver class info */
hbool_t driver_has_cmp; /*`cmp' callback defined? */
@@ -1760,6 +1762,10 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
FUNC_ENTER_NOAPI(H5F_open, NULL)
+ /* Set up root location to fill in */
+ root_loc.oloc = &root_oloc;
+ root_loc.path = &root_path;
+
/*
* If the driver has a `cmp' method then the driver is capable of
* determining when two file handles refer to the same file and the
@@ -1951,7 +1957,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
if (!H5FD_fphdf5_is_captain(lf)) {
/* Allocate room for the superblock buffer */
H5_CHECK_OVERFLOW(super_info.size, hsize_t, size_t);
- if((buf=H5MM_malloc((size_t)super_info.size))==NULL)
+ if((buf = H5MM_malloc((size_t)super_info.size))==NULL)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for superblock buffer")
} /* end if */
@@ -1962,7 +1968,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
HMPI_GOTO_ERROR(NULL, "MPI_Bcast failed", mrc)
if (!H5FD_fphdf5_is_captain(lf)) {
- if (H5F_read_superblock(file, dxpl_id, &root_ent, super_info.addr,
+ if (H5F_read_superblock(file, dxpl_id, &root_loc, super_info.addr,
buf, (size_t)super_info.size) < 0)
HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock")
}
@@ -1973,12 +1979,10 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
* JRM - 4/13/04
*/
if ( (mrc = MPI_Barrier(H5FP_SAP_BARRIER_COMM)) != MPI_SUCCESS )
- {
HMPI_GOTO_ERROR(NULL, "MPI_Barrier failed", mrc)
- }
if (!H5FD_fphdf5_is_captain(lf)) {
- if (H5G_mkroot(file, dxpl_id, &root_ent) < 0)
+ if (H5G_mkroot(file, dxpl_id, &root_loc) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "unable to create/open root group")
}
@@ -1992,7 +1996,7 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
#endif /* H5_HAVE_FPHDF5 */
/* Read the superblock if it hasn't been read before. */
- if (H5F_read_superblock(file, dxpl_id, &root_ent, HADDR_UNDEF, NULL, (size_t)0) < 0)
+ if(H5F_read_superblock(file, dxpl_id, &root_loc, HADDR_UNDEF, NULL, (size_t)0) < 0)
HGOTO_ERROR(H5E_FILE, H5E_READERROR, NULL, "unable to read superblock")
#ifdef H5_HAVE_FPHDF5
@@ -2001,14 +2005,13 @@ H5F_open(const char *name, unsigned flags, hid_t fcpl_id, hid_t fapl_id, hid_t d
* race conditions with allocations, make sure that everyone is done
* reading the superblock before we proceed.
*/
- if ( (mrc = MPI_Barrier(H5FP_SAP_BARRIER_COMM)) != MPI_SUCCESS ) {
+ if ( (mrc = MPI_Barrier(H5FP_SAP_BARRIER_COMM)) != MPI_SUCCESS )
HMPI_GOTO_ERROR(NULL, "MPI_Barrier failed", mrc)
- }
- }
+ } /* end if */
#endif /* H5_HAVE_FPHDF5 */
/* Make sure we can open the root group */
- if (H5G_mkroot(file, dxpl_id, &root_ent)<0)
+ if (H5G_mkroot(file, dxpl_id, &root_loc)<0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to read root group")
}
@@ -2270,61 +2273,61 @@ H5Fflush(hid_t object_id, H5F_scope_t scope)
H5T_t *type = NULL;
H5D_t *dset = NULL;
H5A_t *attr = NULL;
- H5G_entry_t *ent = NULL;
+ H5O_loc_t *oloc = NULL;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Fflush, FAIL)
H5TRACE2("e","iFs",object_id,scope);
- switch (H5I_get_type(object_id)) {
+ switch(H5I_get_type(object_id)) {
case H5I_FILE:
- if (NULL==(f=H5I_object(object_id)))
+ if(NULL == (f = H5I_object(object_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid file identifier")
break;
case H5I_GROUP:
- if (NULL==(grp=H5I_object(object_id)))
+ if(NULL == (grp = H5I_object(object_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid group identifier")
- ent = H5G_entof(grp);
+ oloc = H5G_oloc(grp);
break;
case H5I_DATATYPE:
- if (NULL==(type=H5I_object(object_id)))
+ if(NULL == (type = H5I_object(object_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid type identifier")
- ent = H5T_entof(type);
+ oloc = H5T_oloc(type);
break;
case H5I_DATASET:
- if (NULL==(dset=H5I_object(object_id)))
+ if(NULL == (dset = H5I_object(object_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier")
- ent = H5D_entof(dset);
+ oloc = H5D_oloc(dset);
break;
case H5I_ATTR:
- if (NULL==(attr=H5I_object(object_id)))
+ if(NULL == (attr = H5I_object(object_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid attribute identifier")
- ent = H5A_entof(attr);
+ oloc = H5A_oloc(attr);
break;
default:
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file or file object")
- }
+ } /* end switch */
- if (!f) {
- if (!ent)
+ if(!f) {
+ if(!oloc)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "object is not assocated with a file")
- f = ent->file;
- }
- if (!f)
+ f = oloc->file;
+ } /* end if */
+ if(!f)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "object is not associated with a file")
/* Flush the file */
- if (H5F_flush(f, H5AC_dxpl_id, scope, H5F_FLUSH_NONE) < 0)
+ if(H5F_flush(f, H5AC_dxpl_id, scope, H5F_FLUSH_NONE) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "flush failed")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Fflush() */
/*-------------------------------------------------------------------------
@@ -3245,7 +3248,6 @@ done:
* Programmer: Raymond Lu
* Oct 29, 2003
*
- * Modifications:
*-------------------------------------------------------------------------
*/
hid_t
@@ -3255,17 +3257,17 @@ H5F_get_id(H5F_t *file)
FUNC_ENTER_NOAPI_NOINIT(H5F_get_id)
- assert(file);
+ HDassert(file);
if(file->file_id == -1) {
/* Get an atom for the file */
- if ((file->file_id = H5I_register(H5I_FILE, file))<0)
+ if((file->file_id = H5I_register(H5I_FILE, file)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to atomize file")
} else {
/* Increment reference count on atom. */
- if (H5I_inc_ref(file->file_id)<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed")
- }
+ if(H5I_inc_ref(file->file_id)<0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed")
+ } /* end else */
ret_value = file->file_id;
@@ -3507,6 +3509,37 @@ H5F_sieve_buf_size(const H5F_t *f)
/*-------------------------------------------------------------------------
+ * Function: H5F_gc_ref
+ *
+ * Purpose: Replaced a macro to retrieve the "garbage collect
+ * references flag" now that the generic properties are being used
+ * to store the values.
+ *
+ * Return: Success: The "garbage collect references flag"
+ * is returned.
+ *
+ * Failure: (should not happen)
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jul 8 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+unsigned
+H5F_gc_ref(const H5F_t *f)
+{
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_gc_ref)
+
+ HDassert(f);
+ HDassert(f->shared);
+
+ FUNC_LEAVE_NOAPI(f->shared->gc_ref)
+} /* end H5F_gc_ref() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5F_get_fcpl
*
* Purpose: Retrieve the value of a file's FCPL.
@@ -4148,9 +4181,8 @@ done:
ssize_t
H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size)
{
- H5G_entry_t *ent; /*symbol table entry */
- H5F_t *f; /* Top file in mount hierarchy */
- size_t len=0;
+ H5F_t *f; /* Top file in mount hierarchy */
+ size_t len;
ssize_t ret_value;
FUNC_ENTER_API (H5Fget_name, FAIL)
@@ -4161,14 +4193,16 @@ H5Fget_name(hid_t obj_id, char *name/*out*/, size_t size)
* the top file in a mount hierarchy)
*/
if(H5I_get_type(obj_id) == H5I_FILE ) {
- if (NULL==(f=H5I_object(obj_id)))
+ if(NULL == (f = H5I_object(obj_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
} /* end if */
else {
+ H5G_loc_t loc; /* Object location */
+
/* Get symbol table entry */
- if((ent = H5G_loc(obj_id))==NULL)
+ if(H5G_loc(obj_id, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a valid object ID")
- f = ent->file;
+ f = loc.oloc->file;
} /* end else */
len = HDstrlen(f->name);
diff --git a/src/H5FDcore.c b/src/H5FDcore.c
index 492e06f..713a3ff 100644
--- a/src/H5FDcore.c
+++ b/src/H5FDcore.c
@@ -776,6 +776,9 @@ H5FD_core_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had
x = H5MM_malloc(new_eof);
else
x = H5MM_realloc(file->mem, new_eof);
+#ifdef H5_USING_PURIFY
+HDmemset(x + file->eof, 0, (size_t)(new_eof - file->eof));
+#endif /* H5_USING_PURIFY */
if (!x)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate memory block")
file->mem = x;
diff --git a/src/H5FDmulti.c b/src/H5FDmulti.c
index a1a065e..652bd53 100644
--- a/src/H5FDmulti.c
+++ b/src/H5FDmulti.c
@@ -779,8 +779,8 @@ H5FD_multi_sb_encode(H5FD_t *_file, char *name/*out*/,
assert(7==H5FD_MEM_NTYPES);
for (m=H5FD_MEM_SUPER; m<H5FD_MEM_NTYPES; m=(H5FD_mem_t)(m+1))
buf[m-1] = (unsigned char)file->fa.memb_map[m];
+ buf[6] = 0;
buf[7] = 0;
- buf[8] = 0;
/*
* Copy the starting addresses and EOA values into the buffer in order of
diff --git a/src/H5Fdbg.c b/src/H5Fdbg.c
index 4048ba0..3700067 100644
--- a/src/H5Fdbg.c
+++ b/src/H5Fdbg.c
@@ -19,11 +19,13 @@
*/
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
+#include "H5Gpkg.h" /* Groups */
#include "H5Iprivate.h" /* ID Functions */
#include "H5Pprivate.h" /* Property lists */
@@ -132,7 +134,20 @@ H5F_debug(H5F_t *f, hid_t dxpl_id, FILE * stream, int indent, int fwidth)
"Root group symbol table entry:",
f->shared->root_grp ? "" : "(none)");
if (f->shared->root_grp) {
- H5G_ent_debug(f, dxpl_id, H5G_entof(f->shared->root_grp), stream,
+ H5O_loc_t *root_oloc; /* Root object location */
+ H5G_entry_t root_ent; /* Constructed root symbol table entry */
+
+ /* Reset the root group entry */
+ H5G_ent_reset(&root_ent);
+
+ /* Build up a simulated root group symbol table entry */
+ root_oloc = H5G_oloc(f->shared->root_grp);
+ HDassert(root_oloc);
+ root_ent.type = H5G_NOTHING_CACHED;
+ root_ent.header = root_oloc->addr;
+ root_ent.file = f;
+
+ H5G_ent_debug(f, dxpl_id, &root_ent, stream,
indent+3, MAX(0, fwidth-3), HADDR_UNDEF);
}
diff --git a/src/H5Fmount.c b/src/H5Fmount.c
index c876b15..ebb76fb 100644
--- a/src/H5Fmount.c
+++ b/src/H5Fmount.c
@@ -28,6 +28,10 @@
#include "H5MMprivate.h" /* Memory management */
/* PRIVATE PROTOTYPES */
+static herr_t H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child,
+ hid_t plist_id, hid_t dxpl_id);
+static herr_t H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id);
+static void H5F_mount_count_ids_recurse(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs);
/*--------------------------------------------------------------------------
@@ -62,8 +66,6 @@ H5F_init_mount_interface(void)
* Programmer: Quincey Koziol
* Saturday, July 2, 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -108,56 +110,54 @@ done:
* Programmer: Robb Matzke
* Tuesday, October 6, 1998
*
- * Modifications:
- *
- * Robb Matzke, 1998-10-14
- * The reference count for the mounted H5F_t is incremented.
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_mount(H5G_entry_t *loc, const char *name, H5F_t *child,
+H5F_mount(H5G_loc_t *loc, const char *name, H5F_t *child,
hid_t UNUSED plist_id, hid_t dxpl_id)
{
H5G_t *mount_point = NULL; /*mount point group */
- H5G_entry_t *mp_ent = NULL; /*mount point symbol table entry*/
H5F_t *ancestor = NULL; /*ancestor files */
H5F_t *parent = NULL; /*file containing mount point */
unsigned lt, rt, md; /*binary search indices */
int cmp; /*binary search comparison value*/
- H5G_entry_t *ent = NULL; /*temporary symbol table entry */
- H5G_entry_t mp_open_ent; /* entry of moint point to be opened */
+ H5G_loc_t mp_loc; /* entry of moint point to be opened */
+ H5G_name_t mp_path; /* Mount point group hier. path */
+ H5O_loc_t mp_oloc; /* Mount point object location */
+ H5O_loc_t *mnt_oloc; /* Mount point object location */
H5RS_str_t *name_r; /* Ref-counted version of name */
herr_t ret_value = SUCCEED; /*return value */
FUNC_ENTER_NOAPI_NOINIT(H5F_mount)
- assert(loc);
- assert(name && *name);
- assert(child);
- assert(TRUE==H5P_isa_class(plist_id,H5P_MOUNT));
+ HDassert(loc);
+ HDassert(name && *name);
+ HDassert(child);
+ HDassert(TRUE == H5P_isa_class(plist_id,H5P_MOUNT));
+
+ /* Set up dataset location to fill in */
+ mp_loc.oloc = &mp_oloc;
+ mp_loc.path = &mp_path;
+ H5G_loc_reset(&mp_loc);
/*
* Check that the child isn't mounted, that the mount point exists, that
* the parent & child files have the same file close degree, and
* that the mount wouldn't introduce a cycle in the mount tree.
*/
- if (child->mtab.parent)
+ if(child->mtab.parent)
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "file is already mounted")
- if (H5G_find(loc, name, &mp_open_ent/*out*/, H5AC_dxpl_id) < 0)
+ if(H5G_loc_find(loc, name, &mp_loc/*out*/, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
- if (NULL==(mount_point=H5G_open(&mp_open_ent, dxpl_id)))
+ if(NULL == (mount_point = H5G_open(&mp_loc, dxpl_id)))
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount point not found")
parent = H5G_fileof(mount_point);
- mp_ent = H5G_entof(mount_point);
- for (ancestor=parent; ancestor; ancestor=ancestor->mtab.parent) {
- if (ancestor==child)
+ mnt_oloc = H5G_oloc(mount_point);
+ for(ancestor = parent; ancestor; ancestor = ancestor->mtab.parent) {
+ if(ancestor == child)
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount would introduce a cycle")
- }
+ } /* end for */
if(parent->shared->fc_degree != child->shared->fc_degree)
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mounted file has different file close degree than parent")
@@ -168,62 +168,63 @@ H5F_mount(H5G_entry_t *loc, const char *name, H5F_t *child,
* `md' will be the index where the child should be inserted.
*/
lt = md = 0;
- rt=parent->mtab.nmounts;
+ rt = parent->mtab.nmounts;
cmp = -1;
- while (lt<rt && cmp) {
- md = (lt+rt)/2;
- ent = H5G_entof(parent->mtab.child[md].group);
- cmp = H5F_addr_cmp(mp_ent->header, ent->header);
- if (cmp<0) {
+ while(lt < rt && cmp) {
+ H5O_loc_t *oloc; /*temporary symbol table entry */
+
+ md = (lt + rt) / 2;
+ oloc = H5G_oloc(parent->mtab.child[md].group);
+ cmp = H5F_addr_cmp(mnt_oloc->addr, oloc->addr);
+ if(cmp < 0)
rt = md;
- } else if (cmp>0) {
- lt = md+1;
- }
- }
- if (cmp>0)
+ else if(cmp > 0)
+ lt = md + 1;
+ } /* end while */
+ if(cmp > 0)
md++;
- if (!cmp)
+ if(!cmp)
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount point is already in use")
/* Make room in the table */
- if (parent->mtab.nmounts>=parent->mtab.nalloc) {
+ if(parent->mtab.nmounts>=parent->mtab.nalloc) {
unsigned n = MAX(16, 2*parent->mtab.nalloc);
H5F_mount_t *x = H5MM_realloc(parent->mtab.child,
- n*sizeof(parent->mtab.child[0]));
+ n * sizeof(parent->mtab.child[0]));
if (!x)
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for mount table")
parent->mtab.child = x;
parent->mtab.nalloc = n;
- }
+ } /* end if */
/* Insert into table */
- HDmemmove(parent->mtab.child+md+1, parent->mtab.child+md,
- (parent->mtab.nmounts-md)*sizeof(parent->mtab.child[0]));
+ HDmemmove(parent->mtab.child + md + 1, parent->mtab.child + md,
+ (parent->mtab.nmounts-md) * sizeof(parent->mtab.child[0]));
parent->mtab.nmounts++;
parent->mtab.child[md].group = mount_point;
parent->mtab.child[md].file = child;
child->mtab.parent = parent;
/* Set the group's mountpoint flag */
- if(H5G_mount(parent->mtab.child[md].group)<0)
+ if(H5G_mount(parent->mtab.child[md].group) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to set group mounted flag")
/* Search the open IDs and replace names for mount operation */
/* We pass H5G_UNKNOWN as object type; search all IDs */
- name_r=H5RS_wrap(name);
- assert(name_r);
- if (H5G_replace_name( H5G_UNKNOWN, loc, name_r, NULL, NULL, NULL, OP_MOUNT )<0)
+ name_r = H5RS_wrap(name);
+ HDassert(name_r);
+ if(H5G_name_replace(H5G_UNKNOWN, loc, name_r, NULL, NULL, NULL, OP_MOUNT) < 0)
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to replace name")
- if(H5RS_decr(name_r)<0)
+ if(H5RS_decr(name_r) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTDEC, FAIL, "unable to decrement name string")
done:
- if (ret_value<0 && mount_point)
- if(H5G_close(mount_point)<0)
+ if(ret_value < 0 && mount_point)
+ if(H5G_close(mount_point) < 0)
HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close mounted group")
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5F_mount() */
/*-------------------------------------------------------------------------
@@ -242,50 +243,46 @@ done:
* Programmer: Robb Matzke
* Tuesday, October 6, 1998
*
- * Modifications:
- *
- * Robb Matzke, 1998-10-14
- * The ref count for the child is decremented by calling H5F_close().
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5F_unmount(H5G_entry_t *loc, const char *name, hid_t dxpl_id)
+H5F_unmount(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
{
- H5G_t *mounted = NULL; /*mount point group */
H5G_t *child_group = NULL; /* Child's group in parent mtab */
H5F_t *child_file = NULL; /* Child's file in parent mtab */
- H5G_entry_t *mnt_ent = NULL; /*mounted symbol table entry */
H5F_t *child = NULL; /*mounted file */
H5F_t *parent = NULL; /*file where mounted */
- H5G_entry_t *ent = NULL; /*temporary symbol table entry */
- H5G_entry_t mnt_open_ent; /* entry used to open mount point*/
+ H5O_loc_t *mnt_oloc; /* symbol table entry for root of mounted file */
+ H5G_name_t mp_path; /* Mount point group hier. path */
+ H5O_loc_t mp_oloc; /* Mount point object location */
+ H5G_loc_t mp_loc; /* entry used to open mount point*/
+ hbool_t mp_loc_setup = FALSE; /* Whether mount point location is set up */
int child_idx; /* Index of child in parent's mtab */
herr_t ret_value = SUCCEED; /*return value */
FUNC_ENTER_NOAPI_NOINIT(H5F_unmount)
- assert(loc);
- assert(name && *name);
+ HDassert(loc);
+ HDassert(name && *name);
+
+ /* Set up mount point location to fill in */
+ mp_loc.oloc = &mp_oloc;
+ mp_loc.path = &mp_path;
+ H5G_loc_reset(&mp_loc);
/*
* Get the mount point, or more precisely the root of the mounted file.
* If we get the root group and the file has a parent in the mount tree,
* then we must have found the mount point.
*/
- if (H5G_find(loc, name, &mnt_open_ent/*out*/, H5AC_dxpl_id) < 0)
+ if(H5G_loc_find(loc, name, &mp_loc/*out*/, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
- if (NULL==(mounted=H5G_open(&mnt_open_ent, dxpl_id)))
- HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "mount point not found")
- child = H5G_fileof(mounted);
- mnt_ent = H5G_entof(mounted);
- ent = H5G_entof(child->shared->root_grp);
+ mp_loc_setup = TRUE;
+ child = mp_loc.oloc->file;
+ mnt_oloc = H5G_oloc(child->shared->root_grp);
child_idx = -1;
- if (child->mtab.parent && H5F_addr_eq(mnt_ent->header, ent->header)) {
+ if(child->mtab.parent && H5F_addr_eq(mp_oloc.addr, mnt_oloc->addr)) {
unsigned u; /*counters */
/*
@@ -293,15 +290,15 @@ H5F_unmount(H5G_entry_t *loc, const char *name, hid_t dxpl_id)
* lookup in the parent's mount table to find the correct entry.
*/
parent = child->mtab.parent;
- for (u=0; u<parent->mtab.nmounts; u++) {
- if (parent->mtab.child[u].file==child) {
+ for(u = 0; u < parent->mtab.nmounts; u++) {
+ if(parent->mtab.child[u].file == child) {
/* Found the correct index */
child_idx = u;
break;
- }
- }
+ } /* end if */
+ } /* end for */
} else {
- unsigned lt, rt, md=0; /*binary search indices */
+ unsigned lt, rt, md = 0; /*binary search indices */
int cmp; /*binary search comparison value*/
/*
@@ -312,130 +309,58 @@ H5F_unmount(H5G_entry_t *loc, const char *name, hid_t dxpl_id)
lt = 0;
rt = parent->mtab.nmounts;
cmp = -1;
- while (lt<rt && cmp) {
- md = (lt+rt)/2;
- ent = H5G_entof(parent->mtab.child[md].group);
- cmp = H5F_addr_cmp(mnt_ent->header, ent->header);
- if (cmp<0) {
+ while(lt < rt && cmp) {
+ md = (lt + rt) / 2;
+ mnt_oloc = H5G_oloc(parent->mtab.child[md].group);
+ cmp = H5F_addr_cmp(mp_oloc.addr, mnt_oloc->addr);
+ if (cmp<0)
rt = md;
- } else {
- lt = md+1;
- }
- }
- if (cmp)
+ else
+ lt = md + 1;
+ } /* end while */
+ if(cmp)
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "not a mount point")
- /* Found the correct index */
+ /* Found the correct index, set the info about the child */
child_idx = md;
- mnt_ent = ent;
- }
-
+ H5G_loc_free(&mp_loc);
+ mp_loc_setup = FALSE;
+ mp_loc.oloc = mnt_oloc;
+ mp_loc.path = H5G_nameof(parent->mtab.child[md].group);
+ } /* end else */
HDassert(child_idx >= 0);
/* Search the open IDs replace names to reflect unmount operation */
- if (H5G_replace_name(H5G_UNKNOWN, mnt_ent, mnt_ent->user_path_r, NULL, NULL, NULL, OP_UNMOUNT )<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name ")
+ if(H5G_name_replace(H5G_UNKNOWN, &mp_loc, mp_loc.path->user_path_r, NULL, NULL, NULL, OP_UNMOUNT) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name")
/* Save the information about the child from the mount table */
child_group = parent->mtab.child[child_idx].group;
child_file = parent->mtab.child[child_idx].file;
/* Eliminate the mount point from the table */
- HDmemmove(parent->mtab.child+child_idx, parent->mtab.child+child_idx+1,
- (parent->mtab.nmounts-child_idx)*sizeof(parent->mtab.child[0]));
+ HDmemmove(parent->mtab.child + child_idx, parent->mtab.child + child_idx + 1,
+ (parent->mtab.nmounts-child_idx) * sizeof(parent->mtab.child[0]));
parent->mtab.nmounts -= 1;
/* Unmount the child file from the parent file */
- if(H5G_unmount(child_group)<0)
+ if(H5G_unmount(child_group) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to reset group mounted flag")
- if(H5G_close(child_group)<0)
+ if(H5G_close(child_group) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "unable to close unmounted group")
/* Detach child file from parent & see if it should close */
child_file->mtab.parent = NULL;
- if(H5F_try_close(child_file)<0)
+ if(H5F_try_close(child_file) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "unable to close unmounted file")
done:
- if (mounted)
- if(H5G_close(mounted)<0 && ret_value>=0)
- HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEOBJ, FAIL, "can't close group")
+ /* Free the mount point location's information, if it's been set up */
+ if(mp_loc_setup)
+ H5G_loc_free(&mp_loc);
FUNC_LEAVE_NOAPI(ret_value)
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5F_mountpoint
- *
- * Purpose: If ENT is a mount point then copy the entry for the root
- * group of the mounted file into ENT.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * Tuesday, October 6, 1998
- *
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added `id to name' support.
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5F_mountpoint(H5G_entry_t *find/*in,out*/)
-{
- H5F_t *parent = find->file;
- unsigned lt, rt, md=0;
- int cmp;
- H5G_entry_t *ent = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5F_mountpoint, FAIL)
-
- assert(find);
-
- /*
- * The loop is necessary because we might have file1 mounted at the root
- * of file2, which is mounted somewhere in file3.
- */
- do {
- /*
- * Use a binary search to find the potential mount point in the mount
- * table for the parent
- */
- lt = 0;
- rt = parent->mtab.nmounts;
- cmp = -1;
- while (lt<rt && cmp) {
- md = (lt+rt)/2;
- ent = H5G_entof(parent->mtab.child[md].group);
- cmp = H5F_addr_cmp(find->header, ent->header);
- if (cmp<0) {
- rt = md;
- } else {
- lt = md+1;
- }
- }
-
- /* Copy root info over to ENT */
- if (0==cmp) {
- /* Get the entry for the root group in the child's file */
- ent = H5G_entof(parent->mtab.child[md].file->shared->root_grp);
-
- /* Don't lose the user path of the group when we copy the root group's entry */
- if(H5G_ent_copy(find,ent,H5G_COPY_LIMITED)<0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy group entry")
-
- /* Switch to child's file */
- parent = ent->file;
- }
- } while (!cmp);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5F_unmount() */
/*-------------------------------------------------------------------------
@@ -444,30 +369,27 @@ done:
* Purpose: Check if a file has mounted files within it.
*
* Return: Success: TRUE/FALSE
- * Failure: Negative
+ * Failure: (can't happen)
*
* Programmer: Quincey Koziol
* Thursday, January 2, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-htri_t
+hbool_t
H5F_has_mount(const H5F_t *file)
{
- htri_t ret_value; /* Return value */
+ hbool_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5F_has_mount, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_has_mount)
- assert(file);
+ HDassert(file);
- if(file->mtab.nmounts>0)
- ret_value=TRUE;
+ if(file->mtab.nmounts > 0)
+ ret_value = TRUE;
else
- ret_value=FALSE;
+ ret_value = FALSE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_has_mount() */
@@ -478,30 +400,27 @@ done:
* Purpose: Check if a file is mounted within another file.
*
* Return: Success: TRUE/FALSE
- * Failure: Negative
+ * Failure: (can't happen)
*
* Programmer: Quincey Koziol
* Thursday, January 2, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-htri_t
+hbool_t
H5F_is_mount(const H5F_t *file)
{
- htri_t ret_value; /* Return value */
+ hbool_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5F_is_mount, FAIL)
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_is_mount)
- assert(file);
+ HDassert(file);
- if(file->mtab.parent!=NULL)
- ret_value=TRUE;
+ if(file->mtab.parent != NULL)
+ ret_value = TRUE;
else
- ret_value=FALSE;
+ ret_value = FALSE;
-done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5F_is_mount() */
@@ -517,26 +436,24 @@ done:
* Programmer: Robb Matzke
* Tuesday, October 6, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id)
{
- H5G_entry_t *loc = NULL;
- H5F_t *child = NULL;
+ H5G_loc_t loc;
+ H5F_t *child = NULL;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Fmount, FAIL)
H5TRACE4("e","isii",loc_id,name,child_id,plist_id);
/* Check arguments */
- if (NULL==(loc=H5G_loc(loc_id)))
+ if(H5G_loc(loc_id, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
- if (!name || !*name)
+ if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
- if (NULL==(child=H5I_object_verify(child_id,H5I_FILE)))
+ if(NULL == (child = H5I_object_verify(child_id,H5I_FILE)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file")
if(H5P_DEFAULT == plist_id)
plist_id = H5P_MOUNT_DEFAULT;
@@ -545,12 +462,12 @@ H5Fmount(hid_t loc_id, const char *name, hid_t child_id, hid_t plist_id)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not property list")
/* Do the mount */
- if (H5F_mount(loc, name, child, plist_id, H5AC_dxpl_id)<0)
+ if(H5F_mount(&loc, name, child, plist_id, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to mount file")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Fmount() */
/*-------------------------------------------------------------------------
@@ -570,32 +487,30 @@ done:
* Programmer: Robb Matzke
* Tuesday, October 6, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Funmount(hid_t loc_id, const char *name)
{
- H5G_entry_t *loc = NULL;
+ H5G_loc_t loc;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Funmount, FAIL)
H5TRACE2("e","is",loc_id,name);
/* Check args */
- if (NULL==(loc=H5G_loc(loc_id)))
+ if(H5G_loc(loc_id, &loc) < 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
- if (!name || !*name)
+ if(!name || !*name)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
/* Unmount */
- if (H5F_unmount(loc, name, H5AC_dxpl_id)<0)
+ if (H5F_unmount(&loc, name, H5AC_dxpl_id) < 0)
HGOTO_ERROR(H5E_FILE, H5E_MOUNT, FAIL, "unable to unmount file")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Funmount() */
/*-------------------------------------------------------------------------
@@ -609,8 +524,6 @@ done:
* Programmer: Quincey Koziol
* Tuesday, July 19, 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static void
@@ -658,8 +571,6 @@ H5F_mount_count_ids_recurse(H5F_t *f, unsigned *nopen_files, unsigned *nopen_obj
* Programmer: Quincey Koziol
* Tues, July 19, 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h
index 4cac069..10facbf 100644
--- a/src/H5Fpkg.h
+++ b/src/H5Fpkg.h
@@ -58,7 +58,7 @@
#endif
/* Maximum size of super-block buffer */
-#define H5F_SUPERBLOCK_SIZE 256
+#define H5F_SUPERBLOCK_SIZE 128
#define H5F_DRVINFOBLOCK_SIZE 1024
/* Define the HDF5 file signature */
@@ -169,7 +169,6 @@ H5_DLL herr_t H5F_try_close(H5F_t *f);
H5_DLL haddr_t H5F_locate_signature(H5FD_t *file, hid_t dxpl_id);
/* File mount related routines */
-H5_DLL herr_t H5F_mountpoint(struct H5G_entry_t *find/*in,out*/);
H5_DLL herr_t H5F_close_mounts(H5F_t *f);
H5_DLL int H5F_term_unmount_cb(void *obj_ptr, hid_t obj_id, void *key);
H5_DLL herr_t H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nopen_objs);
@@ -177,7 +176,7 @@ H5_DLL herr_t H5F_mount_count_ids(H5F_t *f, unsigned *nopen_files, unsigned *nop
/* Superblock related routines */
H5_DLL hsize_t H5F_init_superblock(const H5F_t *f, hid_t dxpl_id);
H5_DLL herr_t H5F_write_superblock(H5F_t *f, hid_t dxpl_id, uint8_t *buf);
-H5_DLL herr_t H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_entry_t *root_ent, haddr_t addr, uint8_t *buf, size_t buf_size);
+H5_DLL herr_t H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr, uint8_t *buf, size_t buf_size);
/* Shared file list related routines */
H5_DLL herr_t H5F_sfile_add(H5F_file_t *shared);
diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h
index 53d3f05..2359cb9 100644
--- a/src/H5Fprivate.h
+++ b/src/H5Fprivate.h
@@ -218,6 +218,7 @@ typedef struct H5F_t H5F_t;
#define H5F_BASE_ADDR(F) ((F)->shared->base_addr)
/* Sieve buffer size for datasets */
#define H5F_SIEVE_BUF_SIZE(F) ((F)->shared->sieve_buf_size)
+#define H5F_GC_REF(F) ((F)->shared->gc_ref)
#else /* H5F_PACKAGE */
#define H5F_FCPL(F) (H5F_get_fcpl(F))
#define H5F_SIZEOF_ADDR(F) (H5F_sizeof_addr(F))
@@ -231,6 +232,7 @@ typedef struct H5F_t H5F_t;
#define H5F_GRP_BTREE_SHARED(F) (H5F_grp_btree_shared(F))
#define H5F_BASE_ADDR(F) (H5F_get_base_addr(F))
#define H5F_SIEVE_BUF_SIZE(F) (H5F_sieve_buf_size(F))
+#define H5F_GC_REF(F) (H5F_gc_ref(F))
#endif /* H5F_PACKAGE */
@@ -452,8 +454,8 @@ H5_DLL int H5F_mpi_get_size(const H5F_t *f);
#endif /* H5_HAVE_PARALLEL */
/* Functions than check file mounting information */
-H5_DLL htri_t H5F_is_mount(const H5F_t *file);
-H5_DLL htri_t H5F_has_mount(const H5F_t *file);
+H5_DLL hbool_t H5F_is_mount(const H5F_t *file);
+H5_DLL hbool_t H5F_has_mount(const H5F_t *file);
/* Functions than retrieve values set from the FCPL */
H5_DLL hid_t H5F_get_fcpl(const H5F_t *f);
@@ -467,6 +469,7 @@ H5_DLL size_t H5F_rdcc_nelmts(const H5F_t *f);
H5_DLL double H5F_rdcc_w0(const H5F_t *f);
H5_DLL struct H5RC_t *H5F_grp_btree_shared(const H5F_t *f);
H5_DLL size_t H5F_sieve_buf_size(const H5F_t *f);
+H5_DLL unsigned H5F_gc_ref(const H5F_t *f);
/* Functions that operate on blocks of bytes wrt super block */
H5_DLL herr_t H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr,
diff --git a/src/H5Fsuper.c b/src/H5Fsuper.c
index 1676fe3..d7d0e6e 100644
--- a/src/H5Fsuper.c
+++ b/src/H5Fsuper.c
@@ -66,17 +66,10 @@ H5F_init_super_interface(void)
* wendling@ncsa.uiuc.edu
* Sept 12, 2003
*
- * Modifications:
- * Raymond Lu
- * May 24, 2005
- * Started to check if driver(only family and multi drivers)
- * matches driver information saved in the superblock. Wrong
- * driver will result in a failure.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_entry_t *root_ent, haddr_t addr, uint8_t *buf, size_t buf_size)
+H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc, haddr_t addr, uint8_t *buf, size_t buf_size)
{
haddr_t stored_eoa; /*relative end-of-addr in file */
haddr_t eof; /*end of file address */
@@ -248,7 +241,7 @@ H5F_read_superblock(H5F_t *f, hid_t dxpl_id, H5G_entry_t *root_ent, haddr_t addr
H5F_addr_decode(f, (const uint8_t **)&p, &shared->freespace_addr/*out*/);
H5F_addr_decode(f, (const uint8_t **)&p, &stored_eoa/*out*/);
H5F_addr_decode(f, (const uint8_t **)&p, &shared->driver_addr/*out*/);
- if (H5G_ent_decode(f, (const uint8_t **)&p, root_ent/*out*/) < 0)
+ if(H5G_obj_ent_decode(f, (const uint8_t **)&p, root_loc->oloc/*out*/) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, FAIL, "unable to read root symbol entry")
/*
@@ -490,8 +483,6 @@ done:
* wendling@ncsa.uiuc.edu
* Sept 12, 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -561,7 +552,7 @@ H5F_write_superblock(H5F_t *f, hid_t dxpl_id, uint8_t *buf)
H5F_addr_encode(f, &p, f->shared->freespace_addr);
H5F_addr_encode(f, &p, H5FD_get_eoa(f->shared->lf));
H5F_addr_encode(f, &p, f->shared->driver_addr);
- if(H5G_ent_encode(f, &p, H5G_entof(f->shared->root_grp))<0)
+ if(H5G_obj_ent_encode(f, &p, H5G_oloc(f->shared->root_grp))<0)
HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, FAIL, "unable to encode root group information")
H5_ASSIGN_OVERFLOW(superblock_size, p - sbuf, int, size_t);
diff --git a/src/H5G.c b/src/H5G.c
index 90e08db..8aa1044 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -71,30 +71,17 @@
* +--------------+------------+--------------------------------+
*
*
- * Modifications:
- *
- * Robb Matzke, 5 Aug 1997
- * Added calls to H5E.
- *
- * Robb Matzke, 30 Aug 1997
- * Added `Errors:' field to function prologues.
- *
- * Pedro Vicente, 22 Aug 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
-#define H5G_PACKAGE /*suppress error about including H5Gpkg */
#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
/* Interface initialization */
#define H5_INTERFACE_INIT_FUNC H5G_init_interface
/* Packages needed by this file... */
#include "H5private.h" /* Generic Functions */
-#include "H5Aprivate.h" /* Attributes */
-#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
#include "H5FLprivate.h" /* Free Lists */
@@ -108,102 +95,93 @@
#define H5G_INIT_HEAP 8192
#define H5G_RESERVED_ATOMS 0
-/*
- * During name lookups (see H5G_namei()) we sometimes want information about
- * a symbolic link or a mount point. The normal operation is to follow the
- * symbolic link or mount point and return information about its target.
- */
-#define H5G_TARGET_NORMAL 0x0000
-#define H5G_TARGET_SLINK 0x0001
-#define H5G_TARGET_MOUNT 0x0002
-#define H5G_CRT_INTMD_GROUP 0x0004
-
/* Local typedefs */
-/* Struct only used by change name callback function */
-typedef struct H5G_names_t {
- H5G_entry_t *loc;
- H5RS_str_t *src_name;
- H5G_entry_t *src_loc;
- H5RS_str_t *dst_name;
- H5G_entry_t *dst_loc;
- H5G_names_op_t op;
-} H5G_names_t;
-
-/* Enum for H5G_namei actions */
-typedef enum {
- H5G_NAMEI_TRAVERSE, /* Just traverse groups */
- H5G_NAMEI_INSERT /* Insert entry in group */
-} H5G_namei_act_t ;
-
-/*
- * This table contains a list of object types, descriptions, and the
- * functions that determine if some object is a particular type. The table
- * is allocated dynamically.
- */
-typedef struct H5G_typeinfo_t {
- H5G_obj_t type; /*one of the public H5G_* types */
- htri_t (*isa)(H5G_entry_t*, hid_t); /*function to determine type */
- char *desc; /*description of object type */
-} H5G_typeinfo_t;
+/* User data for path traversal routine for "insertion file" routine */
+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 *src_name; /* Source name for moving object */
+ H5G_loc_t *src_loc; /* Source location for moving object */
+ 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 */
+ hbool_t follow_link; /* Whether we are following a link or not */
+ 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 */
+ hid_t dxpl_id; /* Dataset transfer property list */
+} H5G_trav_ud7_t;
/* Package variables */
/* Local variables */
-static H5G_typeinfo_t *H5G_type_g = NULL; /*object typing info */
-static size_t H5G_ntypes_g = 0; /*entries in type table */
-static size_t H5G_atypes_g = 0; /*entries allocated */
-static char *H5G_comp_g = NULL; /*component buffer */
-static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */
/* Declare a free list to manage the H5G_t struct */
H5FL_DEFINE(H5G_t);
H5FL_DEFINE(H5G_shared_t);
-/* Declare extern the PQ free list for the wrapped strings */
-H5FL_BLK_EXTERN(str_buf);
-
-/* Declare a free list to manage haddr_t's */
-H5FL_DEFINE(haddr_t);
-
/* Private prototypes */
-static herr_t H5G_register_type(H5G_obj_t type, htri_t(*isa)(H5G_entry_t*, hid_t),
- const char *desc);
-static const char * H5G_component(const char *name, size_t *size_p);
-static const char * H5G_basename(const char *name, size_t *size_p);
static char * H5G_normalize(const char *name);
-static herr_t H5G_namei(const H5G_entry_t *loc_ent, const char *name,
- const char **rest/*out*/, H5G_entry_t *grp_ent/*out*/, H5G_entry_t *obj_ent/*out*/,
- unsigned target, int *nlinks/*out*/, H5G_namei_act_t action,
- H5G_entry_t *ent, hid_t dxpl_id);
-static herr_t H5G_traverse_slink(H5G_entry_t *grp_ent/*in,out*/,
- H5G_entry_t *obj_ent/*in,out*/, int *nlinks/*in,out*/, hid_t dxpl_id);
-static H5G_t *H5G_create(H5G_entry_t *loc, const char *name, hid_t dxpl_id,
+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 htri_t H5G_isa(H5G_entry_t *ent, hid_t dxpl_id);
-static htri_t H5G_link_isa(H5G_entry_t *ent, hid_t dxpl_id);
-static H5G_t * H5G_open_oid(H5G_entry_t *ent, hid_t dxpl_id);
-static H5G_t *H5G_rootof(H5F_t *f);
-static herr_t H5G_link(H5G_entry_t *cur_loc, const char *cur_name,
- H5G_entry_t *new_loc, const char *new_name, H5G_link_t type,
- unsigned namei_flags, hid_t dxpl_id);
-static herr_t H5G_get_num_objs(H5G_entry_t *grp, hsize_t *num_objs, hid_t dxpl_id);
-static ssize_t H5G_get_objname_by_idx(H5G_entry_t *loc, hsize_t idx, char* name, size_t size, hid_t dxpl_id);
-static H5G_obj_t H5G_get_objtype_by_idx(H5G_entry_t *loc, hsize_t idx, hid_t dxpl_id);
-static herr_t H5G_linkval(H5G_entry_t *loc, const char *name, size_t size,
+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_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_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(H5G_loc_t *cur_loc, const char *cur_name,
+ H5G_loc_t *new_loc, const char *new_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_entry_t *loc, const char *name,
+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_entry_t *loc, const char *name,
+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(H5G_entry_t *loc, const char *name, hid_t dxpl_id);
-static herr_t H5G_move(H5G_entry_t *src_loc, const char *src_name,
- H5G_entry_t *dst_loc, const char *dst_name, hid_t dxpl_id);
-static htri_t H5G_common_path(const H5RS_str_t *fullpath_r,
- const H5RS_str_t *prefix_r);
-static H5RS_str_t *H5G_build_fullpath(const H5RS_str_t *prefix_r, const H5RS_str_t *name_r);
-static int H5G_replace_ent(void *obj_ptr, hid_t obj_id, void *key);
-static herr_t H5G_copy(H5G_entry_t *ent_src, H5G_entry_t *loc_dst,
+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 *name_dst, hid_t plist_id);
@@ -239,19 +217,19 @@ static herr_t H5G_copy(H5G_entry_t *ent_src, H5G_entry_t *loc_dst,
hid_t
H5Gcreate(hid_t loc_id, const char *name, size_t size_hint)
{
- H5G_entry_t *loc = NULL;
- H5G_t *grp = NULL;
- hid_t tmp_gcpl = (-1); /* Temporary group creation property list */
- hid_t ret_value;
+ H5G_loc_t loc;
+ H5G_t *grp = NULL;
+ hid_t tmp_gcpl = (-1); /* Temporary group creation property list */
+ hid_t ret_value;
- FUNC_ENTER_API(H5Gcreate, FAIL);
+ FUNC_ENTER_API(H5Gcreate, FAIL)
H5TRACE3("i","isz",loc_id,name,size_hint);
/* Check arguments */
- if (NULL==(loc=H5G_loc (loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if (!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given");
+ 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 if we need to create a non-standard GCPL */
if(size_hint > 0) {
@@ -277,16 +255,16 @@ H5Gcreate(hid_t loc_id, const char *name, size_t size_hint)
/* Set the non-default local heap size hint */
ginfo.lheap_size_hint = size_hint;
if(H5P_set(gc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set group info")
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set group info")
} /* end if */
else
tmp_gcpl = H5P_GROUP_CREATE_DEFAULT;
/* Create the group */
- if (NULL == (grp = H5G_create(loc, name, 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)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group");
+ if(NULL == (grp = H5G_create(&loc, name, 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)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
done:
if(tmp_gcpl > 0 && tmp_gcpl != H5P_GROUP_CREATE_DEFAULT)
@@ -298,8 +276,8 @@ done:
H5G_close(grp);
} /* end if */
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gcreate() */
/*-------------------------------------------------------------------------
@@ -334,16 +312,16 @@ done:
hid_t
H5Gcreate_expand(hid_t loc_id, const char *name, hid_t gcpl_id, hid_t gapl_id)
{
- H5G_entry_t *loc = NULL;
- H5G_t *grp = NULL;
- hid_t ret_value;
+ H5G_loc_t loc;
+ H5G_t *grp = NULL;
+ hid_t ret_value;
FUNC_ENTER_API(H5Gcreate_expand, FAIL)
/* Check arguments */
- if (NULL==(loc=H5G_loc (loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
- if (!name || !*name)
+ 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 */
@@ -362,13 +340,13 @@ 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, name, 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)
+ if((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
done:
- if(ret_value<0) {
+ if(ret_value < 0) {
if(grp!=NULL)
H5G_close(grp);
} /* end if */
@@ -399,40 +377,57 @@ done:
hid_t
H5Gopen(hid_t loc_id, const char *name)
{
- hid_t ret_value = FAIL;
H5G_t *grp = NULL;
- H5G_entry_t *loc = NULL;
- H5G_entry_t ent;
+ H5G_loc_t loc;
+ H5G_loc_t grp_loc; /* Location used to open group */
+ H5G_name_t grp_path; /* Opened object group hier. path */
+ H5O_loc_t grp_oloc; /* Opened object object location */
+ hbool_t ent_found = FALSE; /* Entry at 'name' found */
+ hid_t ret_value = FAIL;
- FUNC_ENTER_API(H5Gopen, FAIL);
+ FUNC_ENTER_API(H5Gopen, FAIL)
H5TRACE2("i","is",loc_id,name);
/* Check args */
- if (NULL==(loc=H5G_loc(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if (!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Set up opened group location to fill in */
+ grp_loc.oloc = &grp_oloc;
+ grp_loc.path = &grp_path;
+ H5G_loc_reset(&grp_loc);
- /* Open the parent group, making sure it's a group */
- if (H5G_find(loc, name, &ent/*out*/, H5AC_dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found");
+ /* Find the group object */
+ if(H5G_loc_find(&loc, name, &grp_loc/*out*/, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
+ ent_found = TRUE;
+
+ /* Check that the object found is the correct type */
+ if(H5O_obj_type(&grp_oloc, H5AC_dxpl_id) != H5G_GROUP)
+ HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "not a group")
/* Open the group */
- if ((grp = H5G_open(&ent, H5AC_dxpl_id))==NULL)
- HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group");
+ if((grp = H5G_open(&grp_loc, H5AC_dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
/* Register an atom for the group */
- if ((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
- HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group");
+ if((ret_value = H5I_register(H5I_GROUP, grp)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
done:
- if(ret_value<0) {
- if(grp!=NULL)
+ if(ret_value < 0) {
+ if(grp != NULL)
H5G_close(grp);
+ else {
+ if(ent_found)
+ H5G_name_free(&grp_path);
+ } /* end else */
} /* end if */
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* H5Gopen() */
/*-------------------------------------------------------------------------
@@ -497,76 +492,47 @@ done:
* Programmer: Robb Matzke
* Monday, March 23, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Giterate(hid_t loc_id, const char *name, int *idx_p,
H5G_iterate_t op, void *op_data)
{
- H5O_stab_t stab; /*info about B-tree */
- int idx;
- H5G_bt_it_ud1_t udata;
- H5G_t *grp = NULL;
- herr_t ret_value;
+ int last_obj; /* Index of last object looked at */
+ int idx; /* Internal location to hold index */
+ herr_t ret_value;
- FUNC_ENTER_API(H5Giterate, FAIL);
+ FUNC_ENTER_API(H5Giterate, FAIL)
H5TRACE5("e","is*Isxx",loc_id,name,idx_p,op,op_data);
/* Check args */
- if (!name || !*name)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified");
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
idx = (idx_p == NULL ? 0 : *idx_p);
- if (!idx_p)
- idx_p = &idx;
- if (idx<0)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified");
- if (!op)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified");
-
- /*
- * Open the group on which to operate. We also create a group ID which
- * we can pass to the application-defined operator.
- */
- if ((udata.group_id = H5Gopen (loc_id, name)) <0)
- HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group");
- if ((grp=H5I_object(udata.group_id))==NULL) {
- H5Gclose(udata.group_id);
- HGOTO_ERROR (H5E_ATOM, H5E_BADATOM, FAIL, "bad group atom");
- }
-
- /* Get the B-tree info */
- if (NULL==H5O_read (&(grp->ent), H5O_STAB_ID, 0, &stab, H5AC_dxpl_id))
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address")
+ if(idx < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
+ if(!op)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no operator specified")
- /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */
- udata.skip = idx;
- udata.heap_addr = stab.heap_addr;
- udata.op = op;
- udata.op_data = op_data;
+ /* Set number of objects looked at to zero */
+ last_obj = 0;
- /* Set the number of entries looked at to zero */
- udata.final_ent = 0;
-
- /* Iterate over the group members */
- if ((ret_value = H5B_iterate (H5G_fileof(grp), H5AC_dxpl_id, H5B_SNODE,
- H5G_node_iterate, stab.btree_addr, &udata))<0)
- HERROR (H5E_SYM, H5E_CANTNEXT, "iteration operator failed");
-
- H5I_dec_ref (udata.group_id); /*also closes 'grp'*/
+ /* Call private function. */
+ if((ret_value = H5G_obj_iterate(loc_id, name, idx, &last_obj, op, op_data, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "group iteration failed")
/* Check for too high of a starting index (ex post facto :-) */
/* (Skipping exactly as many entries as are in the group is currently an error) */
- if(idx>0 && idx>=udata.final_ent)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified");
+ if(idx > 0 && idx >= last_obj)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index specified")
/* Set the index we stopped at */
- *idx_p=udata.final_ent;
+ if(idx_p)
+ *idx_p=last_obj;
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Giterate() */
/*-------------------------------------------------------------------------
@@ -582,33 +548,32 @@ done:
* Programmer: Raymond Lu
* Nov 20, 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Gget_num_objs(hid_t loc_id, hsize_t *num_objs)
{
- H5G_entry_t *loc = NULL; /* Pointer to symbol table entry */
+ H5G_loc_t loc; /* Location of object */
herr_t ret_value;
- FUNC_ENTER_API(H5Gget_num_objs, FAIL);
+ FUNC_ENTER_API(H5Gget_num_objs, FAIL)
H5TRACE2("e","i*h",loc_id,num_objs);
/* Check args */
- if (NULL==(loc=H5G_loc (loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID");
- if(H5G_get_type(loc,H5AC_ind_dxpl_id)!=H5G_GROUP)
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a group");
- if (!num_objs)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "nil pointer");
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID")
+ if(H5O_obj_type(loc.oloc, H5AC_ind_dxpl_id) != H5G_GROUP)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
+ if(!num_objs)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "nil pointer")
/* Call private function. */
- ret_value = H5G_get_num_objs(loc, num_objs, H5AC_ind_dxpl_id);
+ if((ret_value = H5G_obj_count(loc.oloc, num_objs, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "can't determine ")
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gget_num_objs() */
/*-------------------------------------------------------------------------
@@ -638,24 +603,25 @@ done:
ssize_t
H5Gget_objname_by_idx(hid_t loc_id, hsize_t idx, char *name, size_t size)
{
- H5G_entry_t *loc = NULL; /* Pointer to symbol table entry */
- ssize_t ret_value = FAIL;
+ H5G_loc_t loc; /* Object location */
+ ssize_t ret_value;
- FUNC_ENTER_API(H5Gget_objname_by_idx, FAIL);
+ FUNC_ENTER_API(H5Gget_objname_by_idx, FAIL)
H5TRACE4("Zs","ihsz",loc_id,idx,name,size);
/* Check args */
- if (NULL==(loc=H5G_loc (loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID");
- if(H5G_get_type(loc,H5AC_ind_dxpl_id)!=H5G_GROUP)
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a group");
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location ID")
+ if(H5O_obj_type(loc.oloc, H5AC_ind_dxpl_id) != H5G_GROUP)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
- /*call private function*/
- ret_value = H5G_get_objname_by_idx(loc, idx, name, size, H5AC_ind_dxpl_id);
+ /* Call internal function*/
+ if((ret_value = H5G_obj_get_name_by_idx(loc.oloc, idx, name, size, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "can't get object name")
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gget_objname_by_idx() */
/*-------------------------------------------------------------------------
@@ -678,25 +644,25 @@ done:
H5G_obj_t
H5Gget_objtype_by_idx(hid_t loc_id, hsize_t idx)
{
- H5G_entry_t *loc = NULL; /* Pointer to symbol table entry */
+ H5G_loc_t loc; /* Object location */
H5G_obj_t ret_value;
- FUNC_ENTER_API(H5Gget_objtype_by_idx, H5G_UNKNOWN);
+ FUNC_ENTER_API(H5Gget_objtype_by_idx, H5G_UNKNOWN)
H5TRACE2("Go","ih",loc_id,idx);
/* Check args */
- if (NULL==(loc=H5G_loc (loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a location ID");
- if(H5G_get_type(loc,H5AC_ind_dxpl_id)!=H5G_GROUP)
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a group");
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a location ID")
+ if(H5O_obj_type(loc.oloc, H5AC_ind_dxpl_id) != H5G_GROUP)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a group")
- /*call private function*/
- ret_value = H5G_get_objtype_by_idx(loc, idx, H5AC_ind_dxpl_id);
+ /* Call internal function*/
+ if((ret_value = H5G_obj_get_type_by_idx(loc.oloc, idx, H5AC_ind_dxpl_id)) == H5G_UNKNOWN)
+ HGOTO_ERROR(H5E_SYM, H5E_BADTYPE, FAIL, "can't get object type")
done:
- FUNC_LEAVE_API(ret_value);
-
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gget_objtype_by_idx() */
/*-------------------------------------------------------------------------
@@ -724,39 +690,40 @@ herr_t
H5Gmove2(hid_t src_loc_id, const char *src_name, hid_t dst_loc_id,
const char *dst_name)
{
- H5G_entry_t *src_loc=NULL;
- H5G_entry_t *dst_loc=NULL;
+ 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);
+ 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 && NULL==(src_loc=H5G_loc(src_loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if (dst_loc_id != H5G_SAME_LOC && NULL==(dst_loc=H5G_loc(dst_loc_id)))
- 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");
-
- 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 = dst_loc;
- }
- else if(dst_loc_id == H5G_SAME_LOC) {
- dst_loc = src_loc;
- }
- else if(src_loc->file != dst_loc->file)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file.");
-
- if (H5G_move(src_loc, src_name, dst_loc, dst_name, H5AC_dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to change object 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);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gmove2() */
/*-------------------------------------------------------------------------
@@ -790,43 +757,43 @@ 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_entry_t *cur_loc = NULL;
- H5G_entry_t *new_loc = NULL;
+ 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);
+ 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 && NULL==(cur_loc=H5G_loc(cur_loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if (new_loc_id != H5G_SAME_LOC && NULL==(new_loc=H5G_loc(new_loc_id)))
- 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");
-
- 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 = new_loc;
- }
- else if(new_loc_id == H5G_SAME_LOC) {
- new_loc = cur_loc;
- }
- else if(cur_loc->file != new_loc->file)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "source and destination should be in the same file.");
-
- if (H5G_link(cur_loc, cur_name, new_loc, new_name, type, H5G_TARGET_NORMAL, H5AC_dxpl_id) <0)
- HGOTO_ERROR (H5E_SYM, H5E_LINK, FAIL, "unable to create link");
+ 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);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Glink2() */
/*-------------------------------------------------------------------------
@@ -851,25 +818,25 @@ done:
herr_t
H5Gunlink(hid_t loc_id, const char *name)
{
- H5G_entry_t *loc = NULL;
+ H5G_loc_t loc;
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_API(H5Gunlink, FAIL);
+ FUNC_ENTER_API(H5Gunlink, FAIL)
H5TRACE2("e","is",loc_id,name);
/* Check arguments */
- if (NULL==(loc=H5G_loc(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if (!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
+ 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");
+ 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);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gunlink() */
/*-------------------------------------------------------------------------
@@ -893,25 +860,25 @@ herr_t
H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link,
H5G_stat_t *statbuf/*out*/)
{
- H5G_entry_t *loc = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5G_loc_t loc;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(H5Gget_objinfo, FAIL);
+ FUNC_ENTER_API(H5Gget_objinfo, FAIL)
H5TRACE4("e","isbx",loc_id,name,follow_link,statbuf);
/* Check arguments */
- if (NULL==(loc=H5G_loc (loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if (!name || !*name)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified");
+ 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 specified")
/* Get info */
- if (H5G_get_objinfo (loc, name, follow_link, statbuf, H5AC_ind_dxpl_id)<0)
- HGOTO_ERROR (H5E_ARGS, H5E_CANTINIT, FAIL, "cannot stat object");
+ if(H5G_get_objinfo(&loc, name, follow_link, statbuf, H5AC_ind_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "cannot stat object")
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gget_objinfo() */
/*-------------------------------------------------------------------------
@@ -935,25 +902,25 @@ done:
herr_t
H5Gget_linkval(hid_t loc_id, const char *name, size_t size, char *buf/*out*/)
{
- H5G_entry_t *loc = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5G_loc_t loc;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(H5Gget_linkval, FAIL);
+ FUNC_ENTER_API(H5Gget_linkval, FAIL)
H5TRACE4("e","iszx",loc_id,name,size,buf);
/* Check arguments */
- if (NULL==(loc=H5G_loc (loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if (!name || !*name)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified");
+ 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");
+ 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);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gget_linkval() */
/*-------------------------------------------------------------------------
@@ -969,30 +936,28 @@ done:
* Programmer: Robb Matzke
* Monday, July 20, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Gset_comment(hid_t loc_id, const char *name, const char *comment)
{
- H5G_entry_t *loc = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ H5G_loc_t loc;
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_API(H5Gset_comment, FAIL);
+ FUNC_ENTER_API(H5Gset_comment, FAIL)
H5TRACE3("e","iss",loc_id,name,comment);
- if (NULL==(loc=H5G_loc(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if (!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified");
+ 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 specified")
- if (H5G_set_comment(loc, name, comment, H5AC_dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to set comment value");
+ if(H5G_set_comment(&loc, name, comment, H5AC_dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to set comment value")
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gset_comment() */
/*-------------------------------------------------------------------------
@@ -1014,32 +979,99 @@ done:
* Programmer: Robb Matzke
* Monday, July 20, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
int
H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize, char *buf)
{
- H5G_entry_t *loc = NULL;
+ H5G_loc_t loc;
int ret_value;
- FUNC_ENTER_API(H5Gget_comment, FAIL);
+ FUNC_ENTER_API(H5Gget_comment, FAIL)
H5TRACE4("Is","iszs",loc_id,name,bufsize,buf);
- if (NULL==(loc=H5G_loc(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if (!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified");
- if (bufsize>0 && !buf)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no buffer specified");
+ 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 specified")
+ if(bufsize > 0 && !buf)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no buffer specified")
- if ((ret_value=H5G_get_comment(loc, name, bufsize, buf, H5AC_ind_dxpl_id))<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to get comment value");
+ if((ret_value = H5G_get_comment(&loc, name, bufsize, buf, H5AC_ind_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to get comment value")
done:
- FUNC_LEAVE_API(ret_value);
-}
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gget_comment() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Gget_create_plist
+ *
+ * Purpose: Returns a copy of the group creation property list.
+ *
+ * Return: Success: ID for a copy of the group creation
+ * property list. The property list ID should be
+ * released by calling H5Pclose().
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, October 25, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Gget_create_plist(hid_t group_id)
+{
+ htri_t ginfo_exists = 0;
+ H5G_t *grp = NULL;
+ H5P_genplist_t *gcpl_plist;
+ H5P_genplist_t *new_plist;
+ hid_t new_gcpl_id = FAIL;
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER_API(H5Gget_create_plist, FAIL)
+ H5TRACE1("i","i", group_id);
+
+ /* Check args */
+ if(NULL == (grp = H5I_object_verify(group_id, H5I_GROUP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
+
+ /* Copy the default group creation property list */
+ if(NULL == (gcpl_plist = H5I_object(H5P_LST_GROUP_CREATE_g)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get default group creation property list")
+ if((new_gcpl_id = H5P_copy_plist(gcpl_plist)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to copy the creation property list")
+ if(NULL == (new_plist = H5I_object(new_gcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
+
+ /* Check for the group having a group info message */
+ if((ginfo_exists = H5O_exists(&(grp->oloc), H5O_GINFO_ID, 0, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
+ if(ginfo_exists) {
+ H5O_ginfo_t ginfo; /* Group info message */
+
+ /* Read the group info */
+ if(NULL == H5O_read(&(grp->oloc), H5O_GINFO_ID, 0, &ginfo, H5AC_dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info")
+
+ /* Set the group info for the property list */
+ if(H5P_set(new_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set group info")
+ } /* end if */
+
+ /* Set the return value */
+ ret_value = new_gcpl_id;
+
+done:
+ if(ret_value < 0) {
+ if(new_gcpl_id > 0)
+ (void)H5I_dec_ref(new_gcpl_id);
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Gget_create_plist() */
/*-------------------------------------------------------------------------
@@ -1055,18 +1087,19 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5Gcopy(hid_t id_src, hid_t loc_dst, const char *name_dst, hid_t plist_id)
+H5Gcopy(hid_t src_id, hid_t dst_id, const char *name_dst, hid_t plist_id)
{
- H5G_entry_t *ent_src = NULL, *ent_dst=NULL;
- herr_t ret_value = SUCCEED; /* Return value */
+ H5G_loc_t src_loc; /* Source object group location */
+ H5G_loc_t dst_loc; /* Destination group location */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Gcopy, FAIL)
/* Check arguments */
- if(NULL == (ent_src = H5G_loc(id_src)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
- if(NULL == (ent_dst = H5G_loc(loc_dst)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(H5G_loc(src_id, &src_loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(H5G_loc(dst_id, &dst_loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
if(!name_dst || !*name_dst)
HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
@@ -1078,7 +1111,7 @@ else
if(TRUE != H5P_isa_class(plist_id, H5P_DATATYPE_CREATE))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not object create property list")
- if(H5G_copy(ent_src, ent_dst, name_dst, plist_id) < 0)
+ if(H5G_copy(&src_loc, &dst_loc, name_dst, plist_id) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
done:
@@ -1103,21 +1136,20 @@ done:
* Programmer: Robb Matzke
* Monday, January 5, 1998
*
- * Modifications:
+ * Notes: The group creation properties are registered in the property
+ * list interface initialization routine (H5P_init_interface)
+ * so that the file creation property class can inherit from it
+ * correctly. (Which allows the file creation property list to
+ * control the group creation properties of the root group of
+ * a file) QAK - 24/10/2005
*
*-------------------------------------------------------------------------
*/
static herr_t
H5G_init_interface(void)
{
- /* Group creation property class variables. In sequence, they are,
- * - Creation property list class to modify
- * - Default value for "group info"
- */
H5P_genclass_t *crt_pclass;
- H5O_ginfo_t ginfo = H5G_CRT_GROUP_INFO_DEF;
- size_t nprops; /* Number of properties */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5G_init_interface);
@@ -1126,16 +1158,6 @@ H5G_init_interface(void)
(H5I_free_t)H5G_close) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to initialize interface");
- /*
- * Initialize the type info table. Begin with the most general types and
- * end with the most specific. For instance, any object that has a data
- * type message is a datatype but only some of them are datasets.
- */
- H5G_register_type(H5G_TYPE, H5T_isa, "datatype");
- H5G_register_type(H5G_GROUP, H5G_isa, "group");
- H5G_register_type(H5G_DATASET, H5D_isa, "dataset");
- H5G_register_type(H5G_LINK, H5G_link_isa, "link");
-
/* ========== group Creation Property Class Initialization ============*/
assert(H5P_CLS_GROUP_CREATE_g!=-1);
@@ -1143,18 +1165,6 @@ H5G_init_interface(void)
if(NULL == (crt_pclass = H5I_object(H5P_CLS_GROUP_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 group info */
- if(H5P_register(crt_pclass,H5G_CRT_GROUP_INFO_NAME,H5G_CRT_GROUP_INFO_SIZE,
- &ginfo,NULL,NULL,NULL,NULL,NULL,NULL,NULL)<0)
- HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
- } /* end if */
-
/* Only register the default property list if it hasn't been created yet */
if(H5P_LST_GROUP_CREATE_g==(-1)) {
/* Register the default group creation property list */
@@ -1180,118 +1190,33 @@ done:
* Programmer: Robb Matzke
* Monday, January 5, 1998
*
- * Modifications:
- * Robb Matzke, 2002-03-28
- * Free the global component buffer.
*-------------------------------------------------------------------------
*/
int
H5G_term_interface(void)
{
- size_t i;
- int n=0;
+ int n = 0;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_term_interface);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_term_interface)
if (H5_interface_initialize_g) {
- if ((n=H5I_nmembers(H5I_GROUP))) {
+ if ((n = H5I_nmembers(H5I_GROUP))) {
H5I_clear_type(H5I_GROUP, FALSE);
} else {
- /* Empty the object type table */
- for (i=0; i<H5G_ntypes_g; i++)
- H5MM_xfree(H5G_type_g[i].desc);
- H5G_ntypes_g = H5G_atypes_g = 0;
- H5G_type_g = H5MM_xfree(H5G_type_g);
-
/* Destroy the group object id group */
H5I_dec_type_ref(H5I_GROUP);
/* Free the global component buffer */
- H5G_comp_g = H5MM_xfree(H5G_comp_g);
- H5G_comp_alloc_g = 0;
+ H5G_traverse_term_interface();
/* Mark closed */
H5_interface_initialize_g = 0;
n = 1; /*H5I*/
- }
- }
-
- FUNC_LEAVE_NOAPI(n);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_register_type
- *
- * Purpose: Register a new object type so H5G_get_type() can detect it.
- * One should always register a general type before a more
- * specific type. For instance, any object that has a datatype
- * message is a datatype, but only some of those objects are
- * datasets.
- *
- * Return: Success: Non-negative
- *
- * Failure: Negative
- *
- * Programmer: Robb Matzke
- * Wednesday, November 4, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5G_register_type(H5G_obj_t type, htri_t(*isa)(H5G_entry_t*, hid_t), const char *_desc)
-{
- char *desc = NULL;
- size_t i;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_register_type);
-
- assert(type>=0);
- assert(isa);
- assert(_desc);
-
- /* Copy the description */
- if (NULL==(desc=H5MM_strdup(_desc)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for object type description");
-
- /*
- * If the type is already registered then just update its entry without
- * moving it to the end
- */
- for (i=0; i<H5G_ntypes_g; i++) {
- if (H5G_type_g[i].type==type) {
- H5G_type_g[i].isa = isa;
- H5MM_xfree(H5G_type_g[i].desc);
- H5G_type_g[i].desc = desc;
- HGOTO_DONE(SUCCEED);
- }
- }
-
- /* Increase table size */
- if (H5G_ntypes_g>=H5G_atypes_g) {
- size_t n = MAX(32, 2*H5G_atypes_g);
- H5G_typeinfo_t *x = H5MM_realloc(H5G_type_g,
- n*sizeof(H5G_typeinfo_t));
- if (!x)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for objec type table");
- H5G_atypes_g = n;
- H5G_type_g = x;
- }
-
- /* Add a new entry */
- H5G_type_g[H5G_ntypes_g].type = type;
- H5G_type_g[H5G_ntypes_g].isa = isa;
- H5G_type_g[H5G_ntypes_g].desc = desc; /*already copied*/
- H5G_ntypes_g++;
+ } /* end else */
+ } /* end if */
-done:
- if (ret_value<0)
- H5MM_xfree(desc);
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(n)
+} /* end H5G_term_interface() */
/*-------------------------------------------------------------------------
@@ -1302,8 +1227,6 @@ done:
* the size in characters of the component through SIZE_P not
* counting leading slashes or the null terminator.
*
- * Errors:
- *
* Return: Success: Ptr into NAME.
*
* Failure: Ptr to the null terminator of NAME.
@@ -1312,15 +1235,13 @@ done:
* matzke@llnl.gov
* Aug 11 1997
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-static const char *
+const char *
H5G_component(const char *name, size_t *size_p)
{
/* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_component);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_component)
assert(name);
@@ -1329,54 +1250,8 @@ H5G_component(const char *name, size_t *size_p)
if (size_p)
*size_p = HDstrcspn(name, "/");
- FUNC_LEAVE_NOAPI(name);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_basename
- *
- * Purpose: Returns a pointer to the last component of the specified
- * name. The length of the component is returned through SIZE_P.
- * The base name is followed by zero or more slashes and a null
- * terminator, but SIZE_P does not count the slashes or the null
- * terminator.
- *
- * Note: The base name of the root directory is a single slash.
- *
- * Return: Success: Ptr to base name.
- *
- * Failure: Ptr to the null terminator.
- *
- * Programmer: Robb Matzke
- * Thursday, September 17, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static const char *
-H5G_basename(const char *name, size_t *size_p)
-{
- size_t i;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_basename);
-
- /* Find the end of the base name */
- i = HDstrlen(name);
- while (i>0 && '/'==name[i-1])
- --i;
-
- /* Skip backward over base name */
- while (i>0 && '/'!=name[i-1])
- --i;
-
- /* Watch out for root special case */
- if ('/'==name[i] && size_p)
- *size_p = 1;
-
- FUNC_LEAVE_NOAPI(name+i);
-}
+ FUNC_LEAVE_NOAPI(name)
+} /* end H5G_component() */
/*-------------------------------------------------------------------------
@@ -1446,411 +1321,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5G_namei
- *
- * Purpose: Translates a name to a symbol table entry.
- *
- * If the specified name can be fully resolved, then this
- * function returns the symbol table entry for the named object
- * through the OBJ_ENT argument. The symbol table entry for the
- * group containing the named object is returned through the
- * GRP_ENT argument if it is non-null. However, if the name
- * refers to the root object then the GRP_ENT will be
- * initialized with an undefined object header address. The
- * REST argument, if present, will point to the null terminator
- * of NAME.
- *
- * If the specified name cannot be fully resolved, then OBJ_ENT
- * is initialized with the undefined object header address. The
- * REST argument will point into the NAME argument to the start
- * of the component that could not be located. The GRP_ENT will
- * contain the entry for the symbol table that was being
- * searched at the time of the failure and will have an
- * undefined object header address if the search failed at the
- * root object. For instance, if NAME is `/foo/bar/baz' and the
- * root directory exists and contains an entry for `foo', and
- * foo is a group that contains an entry for bar, but bar is not
- * a group, then the results will be that REST points to `baz',
- * OBJ_ENT has an undefined object header address, and GRP_ENT
- * is the symbol table entry for `bar' in `/foo'.
- *
- * Every file has a root group whose name is `/'. Components of
- * a name are separated from one another by one or more slashes
- * (/). Slashes at the end of a name are ignored. If the name
- * begins with a slash then the search begins at the root group
- * of the file containing LOC_ENT. Otherwise it begins at
- * LOC_ENT. The component `.' is a no-op, but `..' is not
- * understood by this function (unless it appears as an entry in
- * the symbol table).
- *
- * Symbolic links are followed automatically, but if TARGET
- * includes the H5G_TARGET_SLINK bit and the last component of
- * the name is a symbolic link then that link is not followed.
- * The *NLINKS value is decremented each time a link is followed
- * and link traversal fails if the value would become negative.
- * If NLINKS is the null pointer then a default value is used.
- *
- * Mounted files are handled by calling H5F_mountpoint() after
- * each step of the translation. If the input argument to that
- * function is a mount point then the argument shall be replaced
- * with information about the root group of the mounted file.
- * But if TARGET includes the H5G_TARGET_MOUNT bit and the last
- * component of the name is a mount point then H5F_mountpoint()
- * is not called and information about the mount point itself is
- * returned.
- *
- * Errors:
- *
- * Return: Success: Non-negative if name can be fully resolved.
- * See above for values of REST, GRP_ENT, and
- * OBJ_ENT. NLINKS has been decremented for
- * each symbolic link that was followed.
- *
- * Failure: Negative if the name could not be fully
- * resolved. See above for values of REST,
- * GRP_ENT, and OBJ_ENT.
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 11 1997
- *
- * Modifications:
- * Robb Matzke, 2002-03-28
- * The component name buffer on the stack has been replaced by
- * a dynamically allocated buffer on the heap in order to
- * remove limitations on the length of a name component.
- * There are two reasons that the buffer pointer is global:
- * (1) We want to be able to reuse the buffer without
- * allocating and freeing it each time this function is
- * called.
- * (2) We need to be able to free it from H5G_term_interface()
- * when the library terminates.
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Modified to deep copies of symbol table entries
- * Added `id to name' support.
- *
- * Quincey Koziol, 2003-01-06
- * Added "action" and "ent" parameters to allow different actions when
- * working on the last component of a name. (Specifically, this allows
- * inserting an entry into a group, instead of trying to look it up)
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5G_namei(const H5G_entry_t *loc_ent, const char *name, const char **rest/*out*/,
- H5G_entry_t *grp_ent/*out*/, H5G_entry_t *obj_ent/*out*/,
- unsigned target, int *nlinks/*out*/, H5G_namei_act_t action,
- H5G_entry_t *ent, hid_t dxpl_id)
-{
- H5G_entry_t _grp_ent; /*entry for current group */
- H5G_entry_t _obj_ent; /*entry found */
- size_t nchars; /*component name length */
- int _nlinks = H5G_NLINKS;
- const char *s = NULL;
- unsigned null_obj; /* Flag to indicate this function was called with obj_ent set to NULL */
- unsigned null_grp; /* Flag to indicate this function was called with grp_ent set to NULL */
- unsigned obj_copy = 0; /* Flag to indicate that the object entry is copied */
- unsigned group_copy = 0; /* Flag to indicate that the group entry is copied */
- unsigned last_comp = 0; /* Flag to indicate that a component is the last component in the name */
- unsigned did_insert = 0; /* Flag to indicate that H5G_stab_insert was called */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_namei);
-
- /* Set up "out" parameters */
- if (rest)
- *rest = name;
- if (!grp_ent) {
- grp_ent = &_grp_ent;
- null_grp = 1;
- } /* end if */
- else
- null_grp = 0;
- if (!obj_ent) {
- obj_ent = &_obj_ent;
- null_obj = 1;
- } /* end if */
- else
- null_obj = 0;
- if (!nlinks)
- nlinks = &_nlinks;
-
- /* Check args */
- if (!name || !*name)
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "no name given");
- if (!loc_ent)
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "no current working group");
-
- /*
- * Where does the searching start? For absolute names it starts at the
- * root of the file; for relative names it starts at CWG.
- */
- /* Check if we need to get the root group's entry */
- if ('/' == *name) {
- H5G_t *tmp_grp; /* Temporary pointer to root group of file */
-
- tmp_grp=H5G_rootof(loc_ent->file);
- assert(tmp_grp);
-
- /* Set the location entry to the root group's entry*/
- loc_ent=&(tmp_grp->ent);
- } /* end if */
-
- /* Deep copy of the symbol table entry (duplicates strings) */
- if (H5G_ent_copy(obj_ent, loc_ent,H5G_COPY_DEEP)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to copy entry");
- obj_copy = 1;
-
- H5G_ent_reset(grp_ent);
-
- /* traverse the name */
- while ((name = H5G_component(name, &nchars)) && *name) {
- /* Update the "rest of name" pointer */
- if (rest)
- *rest = name;
-
- /*
- * Copy the component name into a null-terminated buffer so
- * we can pass it down to the other symbol table functions.
- */
- if (nchars+1 > H5G_comp_alloc_g) {
- H5G_comp_alloc_g = MAX3(1024, 2*H5G_comp_alloc_g, nchars+1);
- H5G_comp_g = H5MM_realloc(H5G_comp_g, H5G_comp_alloc_g);
- if (!H5G_comp_g) {
- H5G_comp_alloc_g = 0;
- HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "unable to allocate component buffer");
- }
- }
- HDmemcpy(H5G_comp_g, name, nchars);
- H5G_comp_g[nchars] = '\0';
-
- /*
- * The special name `.' is a no-op.
- */
- if ('.' == H5G_comp_g[0] && !H5G_comp_g[1]) {
- name += nchars;
- continue;
- }
-
- /*
- * Advance to the next component of the name.
- */
- /* If we've already copied a new entry into the group entry,
- * it needs to be freed before overwriting it with another entry
- */
- if(group_copy)
- H5G_free_ent_name(grp_ent);
-
- /* Transfer "ownership" of the entry's information to the group entry */
- H5G_ent_copy(grp_ent,obj_ent,H5G_COPY_SHALLOW);
- H5G_ent_reset(obj_ent);
-
- /* Set flag that we've copied a new entry into the group entry */
- group_copy =1;
-
- /* Check if this is the last component of the name */
- if(!((s=H5G_component(name+nchars, NULL)) && *s))
- last_comp=1;
-
- switch(action) {
- case H5G_NAMEI_TRAVERSE:
- if (H5G_stab_find(grp_ent, H5G_comp_g, obj_ent/*out*/, dxpl_id )<0) {
- /*
- * Component was not found in the current symbol table, possibly
- * because GRP_ENT isn't a symbol table.
- */
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found");
- }
- break;
-
- case H5G_NAMEI_INSERT:
- if(!last_comp) {
- if (H5G_stab_find(grp_ent, H5G_comp_g, obj_ent/*out*/, dxpl_id )<0) {
- /* If an intermediate group doesn't exist & flag is set, create the group */
- if (target & H5G_CRT_INTMD_GROUP) {
- H5G_entry_t new_ent;
-
- /* Reset group entry */
- H5G_ent_reset(&new_ent);
-
- /* Create the intermediate group */
- if (H5G_stab_create(grp_ent->file, dxpl_id, 0, &new_ent/*out*/) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create grp");
-
- /* Insert new group into current group's symbol table */
- if (H5G_stab_insert(grp_ent, H5G_comp_g, &new_ent, TRUE, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert intermediate group");
-
- /* Keep newly created group's entry, so we can traverse into it */
- if (H5G_ent_copy(obj_ent, &new_ent, H5G_COPY_DEEP)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to copy entry");
-
- /* Close new group */
- if (H5O_close(&new_ent) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close");
- }
- else
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found");
- }
- } /* end if */
- else {
- did_insert = 1;
- if (H5G_stab_insert(grp_ent, H5G_comp_g, ent, TRUE, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert name");
- HGOTO_DONE(SUCCEED);
- } /* end else */
- break;
- } /* end switch */
-
- /*
- * If we found a symbolic link then we should follow it. But if this
- * 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_CACHED_SLINK==obj_ent->type &&
- (0==(target & H5G_TARGET_SLINK) || !last_comp)) {
- if ((*nlinks)-- <= 0)
- HGOTO_ERROR (H5E_SYM, H5E_SLINK, FAIL, "too many links");
- if (H5G_traverse_slink (grp_ent, obj_ent, nlinks, dxpl_id)<0)
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "symbolic link traversal failed");
- }
-
- /*
- * Resolve mount points to the mounted group. Do not do this step if
- * the H5G_TARGET_MOUNT bit of TARGET is set and this is the last
- * component of the name.
- */
- if (0==(target & H5G_TARGET_MOUNT) || !last_comp)
- H5F_mountpoint(obj_ent/*in,out*/);
-
- /* next component */
- name += nchars;
- } /* end while */
-
- /* Update the "rest of name" pointer */
- if (rest)
- *rest = name; /*final null */
-
- /* If this was an insert, make sure that the insert function was actually
- * called (this catches no-op names like "." and "/") */
- if(action == H5G_NAMEI_INSERT && !did_insert)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "group already exists");
-
-done:
- /* If we started with a NULL obj_ent, free the entry information */
- if(null_obj || (ret_value < 0 && obj_copy))
- H5G_free_ent_name(obj_ent);
- /* If we started with a NULL grp_ent and we copied something into it, free the entry information */
- if(null_grp && group_copy)
- H5G_free_ent_name(grp_ent);
-
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_traverse_slink
- *
- * Purpose: Traverses symbolic link. The link head appears in the group
- * whose entry is GRP_ENT and the link head entry is OBJ_ENT.
- *
- * Return: Success: Non-negative, OBJ_ENT will contain information
- * about the object to which the link points and
- * GRP_ENT will contain the information about
- * the group in which the link tail appears.
- *
- * Failure: Negative
- *
- * Programmer: Robb Matzke
- * Friday, April 10, 1998
- *
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added `id to name' support.
- *
- * John Mainzer - 6/8/05
- * Modified function to use the new dirtied parmeter of
- * H5AC_unprotect(), which allows management of the is_dirty
- * field of the cache info to be moved into the cache code.
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
- H5G_entry_t *obj_ent/*in,out*/,
- int *nlinks/*in,out*/, hid_t dxpl_id)
-{
- H5O_stab_t stab_mesg; /*info about local heap */
- const char *clv = NULL; /*cached link value */
- char *linkval = NULL; /*the copied link value */
- H5G_entry_t tmp_grp_ent; /* Temporary copy of group entry */
- H5RS_str_t *tmp_user_path_r=NULL, *tmp_canon_path_r=NULL; /* Temporary pointer to object's user path & canonical path */
- const H5HL_t *heap;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_slink);
-
- /* Portably initialize the temporary group entry */
- H5G_ent_reset(&tmp_grp_ent);
-
- /* Get the link value */
- if (NULL==H5O_read (grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id))
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address");
-
- if (NULL == (heap = H5HL_protect(grp_ent->file, dxpl_id, stab_mesg.heap_addr)))
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value")
-
- clv = H5HL_offset_into(grp_ent->file, heap, obj_ent->cache.slink.lval_offset);
-
- linkval = H5MM_xstrdup (clv);
- assert(linkval);
-
- if (H5HL_unprotect(grp_ent->file, dxpl_id, heap, stab_mesg.heap_addr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value")
-
- /* Hold the entry's name (& old_name) to restore later */
- tmp_user_path_r=obj_ent->user_path_r;
- obj_ent->user_path_r=NULL;
- tmp_canon_path_r=obj_ent->canon_path_r;
- obj_ent->canon_path_r=NULL;
-
- /* Free the names for the group entry */
- H5G_free_ent_name(grp_ent);
-
- /* Clone the group entry, so we can track the names properly */
- H5G_ent_copy(&tmp_grp_ent,grp_ent,H5G_COPY_DEEP);
-
- /* Traverse the link */
- if (H5G_namei (&tmp_grp_ent, linkval, NULL, grp_ent, obj_ent, H5G_TARGET_NORMAL, nlinks, H5G_NAMEI_TRAVERSE, NULL, dxpl_id))
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link");
-
- /* Free the entry's names, we will use the original name for the object */
- H5G_free_ent_name(obj_ent);
-
- /* Restore previous name for object */
- obj_ent->user_path_r = tmp_user_path_r;
- tmp_user_path_r=NULL;
- obj_ent->canon_path_r = tmp_canon_path_r;
- tmp_canon_path_r=NULL;
-
-done:
- /* Error cleanup */
- if(tmp_user_path_r)
- H5RS_decr(tmp_user_path_r);
- if(tmp_canon_path_r)
- H5RS_decr(tmp_canon_path_r);
-
- /* Release cloned copy of group entry */
- H5G_free_ent_name(&tmp_grp_ent);
-
- H5MM_xfree (linkval);
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5G_mkroot
*
* Purpose: Creates a root group in an empty file and opens it. If a
@@ -1866,78 +1336,91 @@ done:
* matzke@llnl.gov
* Aug 11 1997
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5G_mkroot (H5F_t *f, hid_t dxpl_id, H5G_entry_t *ent)
+H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *loc)
{
- H5G_entry_t new_root; /*new root object */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5O_loc_t new_root_oloc; /* New root object location */
+ H5G_name_t new_root_path; /* New root path */
+ H5G_loc_t new_root_loc; /* New root location information */
+ H5G_loc_t root_loc; /* Root location information */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5G_mkroot, FAIL);
+ FUNC_ENTER_NOAPI(H5G_mkroot, FAIL)
/* check args */
- assert(f);
- if (f->shared->root_grp)
- HGOTO_DONE(SUCCEED);
+ HDassert(f);
+ if(f->shared->root_grp)
+ HGOTO_DONE(SUCCEED)
/* Create information needed for group nodes */
- if(H5G_node_init(f)<0)
+ if(H5G_node_init(f) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group node info")
/*
* If there is no root object then create one. The root group always starts
* with a hard link count of one since it's pointed to by the boot block.
*/
- if (!ent) {
- ent = &new_root;
- H5G_ent_reset(ent);
- if (H5G_stab_create (f, dxpl_id, (size_t)H5G_SIZE_HINT, ent/*out*/)<0)
- HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to create root group");
- if (1 != H5O_link (ent, 1, dxpl_id))
- HGOTO_ERROR (H5E_SYM, H5E_LINK, FAIL, "internal error (wrong link count)");
+ if (loc == NULL) {
+ H5P_genplist_t *fc_plist; /* File creation property list */
+ H5O_ginfo_t ginfo; /* Group info parameters */
+
+ /* Get the file creation property list */
+ /* (Which is a sub-class of the group creation property class) */
+ if(NULL == (fc_plist = H5I_object(f->shared->fcpl_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
+
+ /* Get the group info property */
+ if(H5P_get(fc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info")
+
+ /* Set up group location for root group */
+ new_root_loc.oloc = &new_root_oloc;
+ new_root_loc.path = &new_root_path;
+ H5G_loc_reset(&new_root_loc);
+ loc = &new_root_loc;
+
+ if(H5G_obj_create(f, dxpl_id, &ginfo, loc->oloc/*out*/) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry")
+ if(1 != H5O_link(loc->oloc, 1, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "internal error (wrong link count)")
} else {
/*
* Open the root object as a group.
*/
- if (H5O_open (ent)<0)
- HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open root group");
- }
+ if(H5O_open(loc->oloc) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open root group")
+ } /* end else */
/* Create the path names for the root group's entry */
- ent->user_path_r=H5RS_create("/");
- assert(ent->user_path_r);
- ent->canon_path_r=H5RS_create("/");
- assert(ent->canon_path_r);
- ent->user_path_hidden=0;
+ H5G_name_init(loc->path, "/");
/*
* Create the group pointer. Also decrement the open object count so we
* don't count the root group as an open object. The root group will
* never be closed.
*/
- if (NULL==(f->shared->root_grp = H5FL_CALLOC (H5G_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- if (NULL==(f->shared->root_grp->shared = H5FL_CALLOC (H5G_shared_t))) {
+ if(NULL == (f->shared->root_grp = H5FL_CALLOC(H5G_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ if(NULL == (f->shared->root_grp->shared = H5FL_CALLOC(H5G_shared_t))) {
H5FL_FREE(H5G_t, f->shared->root_grp);
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- }
- /* Shallow copy (take ownership) of the group entry object */
- if(H5G_ent_copy(&(f->shared->root_grp->ent), ent, H5G_COPY_SHALLOW)<0)
- HGOTO_ERROR (H5E_SYM, H5E_CANTCOPY, FAIL, "can't copy group entry")
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ } /* end if */
+
+ /* Shallow copy (take ownership) of the group object info */
+ root_loc.oloc = &(f->shared->root_grp->oloc);
+ root_loc.path = &(f->shared->root_grp->path);
+ if(H5G_loc_copy(&root_loc, loc, H5G_COPY_SHALLOW) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, FAIL, "can't copy group object location")
f->shared->root_grp->shared->fo_count = 1;
- assert (1==f->nopen_objs);
+ HDassert(1 == f->nopen_objs);
f->nopen_objs = 0;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_mkroot() */
/*-------------------------------------------------------------------------
@@ -1946,8 +1429,6 @@ done:
* Purpose: Creates a new empty group with the specified name. The name
* is either an absolute name or is relative to LOC.
*
- * Errors:
- *
* Return: Success: A handle for the group. The group is opened
* and should eventually be close by calling
* H5G_close().
@@ -1958,85 +1439,88 @@ done:
* matzke@llnl.gov
* Aug 11 1997
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
static H5G_t *
-H5G_create(H5G_entry_t *loc, const char *name,
+H5G_create(H5G_loc_t *loc, const char *name,
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 */
- unsigned stab_init=0; /* Flag to indicate that the symbol table was created successfully */
+ H5O_ginfo_t ginfo; /* Group info */
+ 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);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_create)
/* check args */
- assert(loc);
- assert(name && *name);
- assert(gcpl_id != H5P_DEFAULT);
+ HDassert(loc);
+ HDassert(name && *name);
+ HDassert(gcpl_id != H5P_DEFAULT);
#ifdef LATER
- assert(gapl_id != H5P_DEFAULT);
+ HDassert(gapl_id != H5P_DEFAULT);
#endif /* LATER */
/* create an open group */
- if (NULL==(grp = H5FL_CALLOC(H5G_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if (NULL==(grp->shared = H5FL_CALLOC(H5G_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ if(NULL == (grp = H5FL_CALLOC(H5G_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ 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");
-
- /* Create the group entry */
- if (H5G_stab_create(file, dxpl_id, (size_t)H5G_SIZE_HINT, &(grp->ent)/*out*/) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create grp");
- stab_init=1; /* Indicate that the symbol table information is valid */
+ 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)))
+ if(NULL == (gc_plist = H5I_object(gcpl_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a property list")
- /* insert child name into parent */
- if(H5G_insert(loc,name,&(grp->ent), dxpl_id, gc_plist)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, NULL, "can't insert group");
+ /* Get the group info property */
+ if(H5P_get(gc_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get group info")
+
+ /* Create the group object header */
+ if(H5G_obj_create(file, dxpl_id, &ginfo, &(grp->oloc)/*out*/) < 0)
+ 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->ent.file, grp->ent.header)<0)
+ 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->ent.file, grp->ent.header, grp->shared)<0)
+ if(H5FO_insert(grp->oloc.file, grp->oloc.addr, grp->shared) < 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;
+ ret_value = grp;
done:
- if(ret_value==NULL) {
+ if(ret_value == NULL) {
/* Check if we need to release the file-oriented symbol table info */
- if(stab_init) {
- if(H5O_close(&(grp->ent))<0)
- HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "unable to release object header");
- if(H5O_delete(file, dxpl_id,grp->ent.header)<0)
- HDONE_ERROR(H5E_SYM, H5E_CANTDELETE, NULL, "unable to delete object header");
+ if(oloc_init) {
+ if(H5O_close(&(grp->oloc)) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, NULL, "unable to release object header")
+ if(H5O_delete(file, dxpl_id, grp->oloc.addr) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTDELETE, NULL, "unable to delete object header")
} /* end if */
- if(grp!=NULL) {
+ if(grp != NULL) {
if(grp->shared != NULL)
H5FL_FREE(H5G_shared_t, grp->shared);
H5FL_FREE(H5G_t,grp);
- }
+ } /* end if */
} /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_create() */
/*-------------------------------------------------------------------------
@@ -2054,61 +1538,30 @@ done:
* Programmer: Robb Matzke
* Monday, November 2, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-static htri_t
-H5G_isa(H5G_entry_t *ent, hid_t dxpl_id)
+htri_t
+H5G_isa(H5O_loc_t *loc, hid_t dxpl_id)
{
+ htri_t stab_exists;
+ htri_t linfo_exists;
htri_t ret_value;
- FUNC_ENTER_NOAPI_NOINIT(H5G_isa);
-
- assert(ent);
-
- if ((ret_value=H5O_exists(ent, H5O_STAB_ID, 0, dxpl_id))<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_link_isa
- *
- * Purpose: Determines if an object has the requisite form for being
- * a soft link.
- *
- * Return: Success: TRUE if the symbol table entry is of type
- * H5G_LINK; FALSE otherwise.
- *
- * Failure: Shouldn't fail.
- *
- * Programmer: Quincey Koziol
- * Wednesday, June 23, 2004
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static htri_t
-H5G_link_isa(H5G_entry_t *ent, hid_t UNUSED dxpl_id)
-{
- htri_t ret_value;
+ FUNC_ENTER_NOAPI_NOINIT(H5G_isa)
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_link_isa);
+ HDassert(loc);
- assert(ent);
+ /* Check for any of the messages that indicate a group */
+ if((stab_exists = H5O_exists(loc, H5O_STAB_ID, 0, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
+ if((linfo_exists = H5O_exists(loc, H5O_LINFO_ID, 0, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
- if(ent->type == H5G_CACHED_SLINK)
- ret_value=TRUE;
- else
- ret_value=FALSE;
+ ret_value = (stab_exists > 0 || linfo_exists > 0);
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5G_link_isa() */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_isa() */
/*-------------------------------------------------------------------------
@@ -2124,58 +1577,54 @@ H5G_link_isa(H5G_entry_t *ent, hid_t UNUSED dxpl_id)
* Programmer: Robb Matzke
* Monday, January 5, 1998
*
- * Modifications:
- * Modified to call H5G_open_oid - QAK - 3/17/99
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
H5G_t *
-H5G_open(H5G_entry_t *ent, hid_t dxpl_id)
+H5G_open(H5G_loc_t *loc, hid_t dxpl_id)
{
H5G_t *grp = NULL;
- H5G_shared_t *shared_fo=NULL;
- H5G_t *ret_value=NULL;
+ H5G_shared_t *shared_fo = NULL;
+ H5G_t *ret_value = NULL;
- FUNC_ENTER_NOAPI(H5G_open, NULL);
+ FUNC_ENTER_NOAPI(H5G_open, NULL)
/* Check args */
- assert(ent);
+ HDassert(loc);
+
+ /* Allocate the group structure */
+ if(NULL == (grp = H5FL_CALLOC(H5G_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for group")
+
+ /* Shallow copy (take ownership) of the group location object */
+ if(H5O_loc_copy(&(grp->oloc), loc->oloc, H5O_COPY_SHALLOW) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy object location")
+ if(H5G_name_copy(&(grp->path), loc->path, H5G_COPY_SHALLOW) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy path")
/* Check if group was already open */
- if((shared_fo=H5FO_opened(ent->file, ent->header))==NULL) {
+ if((shared_fo = H5FO_opened(grp->oloc.file, grp->oloc.addr)) == NULL) {
/* Clear any errors from H5FO_opened() */
H5E_clear_stack(NULL);
/* Open the group object */
- if ((grp=H5G_open_oid(ent, dxpl_id)) ==NULL)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "not found");
+ if(H5G_open_oid(grp, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "not found")
/* Add group to list of open objects in file */
- if(H5FO_insert(grp->ent.file, grp->ent.header, grp->shared)<0)
- {
+ if(H5FO_insert(grp->oloc.file, grp->oloc.addr, grp->shared) < 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 */
/* Increment object count for the object in the top file */
- if(H5FO_top_incr(grp->ent.file, grp->ent.header) < 0)
+ if(H5FO_top_incr(grp->oloc.file, grp->oloc.addr) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINC, NULL, "can't increment object count")
/* Set open object count */
grp->shared->fo_count = 1;
- }
+ } /* end if */
else {
- if(NULL == (grp = H5FL_CALLOC(H5G_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for group")
-
- /* Shallow copy (take ownership) of the group entry object */
- if(H5G_ent_copy(&(grp->ent), ent, H5G_COPY_SHALLOW)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, NULL, "can't copy group entry")
-
/* Point to shared group info */
grp->shared = shared_fo;
@@ -2183,16 +1632,16 @@ H5G_open(H5G_entry_t *ent, hid_t dxpl_id)
shared_fo->fo_count++;
/* Check if the object has been opened through the top file yet */
- if(H5FO_top_count(grp->ent.file, grp->ent.header) == 0) {
+ if(H5FO_top_count(grp->oloc.file, grp->oloc.addr) == 0) {
/* Open the object through this top file */
- if(H5O_open(&(grp->ent)) < 0)
+ if(H5O_open(&(grp->oloc)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open object header")
} /* end if */
/* Increment object count for the object in the top file */
- if(H5FO_top_incr(grp->ent.file, grp->ent.header) < 0)
+ if(H5FO_top_incr(grp->oloc.file, grp->oloc.addr) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINC, NULL, "can't increment object count")
- }
+ } /* end else */
/* Set return value */
ret_value = grp;
@@ -2201,8 +1650,8 @@ done:
if (!ret_value && grp)
H5FL_FREE(H5G_t,grp);
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_open() */
/*-------------------------------------------------------------------------
@@ -2218,59 +1667,43 @@ done:
* Programmer: Quincey Koziol
* Wednesday, March 17, 1999
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added a deep copy of the symbol table entry
- *
*-------------------------------------------------------------------------
*/
-static H5G_t *
-H5G_open_oid(H5G_entry_t *ent, hid_t dxpl_id)
+static herr_t
+H5G_open_oid(H5G_t *grp, hid_t dxpl_id)
{
- H5G_t *grp = NULL;
- H5G_t *ret_value = NULL;
- hbool_t ent_opened = FALSE;
+ hbool_t obj_opened = FALSE;
+ herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI_NOINIT(H5G_open_oid);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_open_oid)
/* Check args */
- assert(ent);
-
- /* Open the object, making sure it's a group */
- if (NULL==(grp = H5FL_CALLOC(H5G_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if (NULL==(grp->shared = H5FL_CALLOC(H5G_shared_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ HDassert(grp);
- /* Copy over (take ownership) of the group entry object */
- H5G_ent_copy(&(grp->ent),ent,H5G_COPY_SHALLOW);
+ /* Allocate the shared information for the group */
+ if(NULL == (grp->shared = H5FL_CALLOC(H5G_shared_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Grab the object header */
- if (H5O_open(&(grp->ent)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to open group")
- ent_opened = TRUE;
+ if(H5O_open(&(grp->oloc)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
+ obj_opened = TRUE;
/* Check if this object has the right message(s) to be treated as a group */
- if(H5O_exists(&(grp->ent), H5O_STAB_ID, 0, dxpl_id) <= 0)
- HGOTO_ERROR (H5E_SYM, H5E_CANTOPENOBJ, NULL, "not a group")
-
- /* Set return value */
- ret_value = grp;
+ if(H5O_exists(&(grp->oloc), H5O_STAB_ID, 0, dxpl_id) <= 0
+ && H5O_exists(&(grp->oloc), H5O_LINFO_ID, 0, dxpl_id) <= 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "not a group")
done:
- if(!ret_value) {
- if(grp) {
- if(ent_opened)
- H5O_close(&(grp->ent));
- if(grp->shared)
- H5FL_FREE(H5G_shared_t, grp->shared);
- H5FL_FREE(H5G_t,grp);
- } /* end if */
+ if(ret_value < 0) {
+ if(obj_opened)
+ H5O_close(&(grp->oloc));
+ if(grp->shared)
+ H5FL_FREE(H5G_shared_t, grp->shared);
} /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_open_oid() */
/*-------------------------------------------------------------------------
@@ -2283,42 +1716,40 @@ done:
* Programmer: Robb Matzke
* Monday, January 5, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5G_close(H5G_t *grp)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5G_close, FAIL);
+ FUNC_ENTER_NOAPI(H5G_close, FAIL)
/* Check args */
- assert(grp && grp->shared);
- assert(grp->shared->fo_count > 0);
+ HDassert(grp && grp->shared);
+ HDassert(grp->shared->fo_count > 0);
--grp->shared->fo_count;
- if (0 == grp->shared->fo_count) {
- assert (grp!=H5G_rootof(H5G_fileof(grp)));
+ if(0 == grp->shared->fo_count) {
+ HDassert(grp != H5G_rootof(H5G_fileof(grp)));
/* Remove the group from the list of opened objects in the file */
- if(H5FO_top_decr(grp->ent.file, grp->ent.header) < 0)
+ if(H5FO_top_decr(grp->oloc.file, grp->oloc.addr) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't decrement count for object")
- if(H5FO_delete(grp->ent.file, H5AC_dxpl_id, grp->ent.header)<0)
+ if(H5FO_delete(grp->oloc.file, H5AC_dxpl_id, grp->oloc.addr) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't remove group from list of open objects")
- if(H5O_close(&(grp->ent)) < 0)
+ if(H5O_close(&(grp->oloc)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close")
- H5FL_FREE (H5G_shared_t, grp->shared);
+ H5FL_FREE(H5G_shared_t, grp->shared);
} else {
/* Decrement the ref. count for this object in the top file */
- if(H5FO_top_decr(grp->ent.file, grp->ent.header) < 0)
+ if(H5FO_top_decr(grp->oloc.file, grp->oloc.addr) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't decrement count for object")
/* Check reference count for this object in the top file */
- if(H5FO_top_count(grp->ent.file, grp->ent.header) == 0)
- if(H5O_close(&(grp->ent)) < 0)
+ if(H5FO_top_count(grp->oloc.file, grp->oloc.addr) == 0)
+ if(H5O_close(&(grp->oloc)) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to close")
/* If this group is a mount point and the mount point is the last open
@@ -2326,21 +1757,20 @@ H5G_close(H5G_t *grp)
*/
if(grp->shared->mounted && grp->shared->fo_count == 1) {
/* Attempt to close down the file hierarchy */
- if(H5F_try_close(grp->ent.file) < 0)
+ if(H5F_try_close(grp->oloc.file) < 0)
HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close")
} /* end if */
+ } /* end else */
- if(H5G_free_ent_name(&(grp->ent))<0)
- {
- H5FL_FREE (H5G_t,grp);
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't free group entry name");
- }
- }
+ if(H5G_name_free(&(grp->path)) < 0) {
+ H5FL_FREE(H5G_t,grp);
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't free group entry name")
+ } /* end if */
- H5FL_FREE (H5G_t,grp);
+ H5FL_FREE(H5G_t,grp);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_close() */
@@ -2364,18 +1794,18 @@ done:
herr_t
H5G_free(H5G_t *grp)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5G_free, FAIL);
+ FUNC_ENTER_NOAPI(H5G_free, FAIL)
- assert(grp && grp->shared);
+ HDassert(grp && grp->shared);
H5FL_FREE(H5G_shared_t, grp->shared);
H5FL_FREE(H5G_t, grp);
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_free() */
/*-------------------------------------------------------------------------
@@ -2398,275 +1828,238 @@ done:
*
*-------------------------------------------------------------------------
*/
-static H5G_t *
+H5G_t *
H5G_rootof(H5F_t *f)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_rootof);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_rootof)
- while (f->mtab.parent)
+ while(f->mtab.parent)
f = f->mtab.parent;
- FUNC_LEAVE_NOAPI(f->shared->root_grp);
-}
+ FUNC_LEAVE_NOAPI(f->shared->root_grp)
+} /* end H5G_rootof() */
/*-------------------------------------------------------------------------
- * Function: H5G_insert
- *
- * Purpose: Inserts a symbol table entry into the group graph.
+ * Function: H5G_oloc
*
- * Errors:
+ * Purpose: Returns a pointer to the object location for a group.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Success: Ptr to group entry
+ * Failure: NULL
*
* Programmer: Robb Matzke
- * Friday, September 19, 1997
- *
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002
- * Added `id to name' support.
- *
- * Peter Cao
- * May 09, 2005
- * Add flag 'crt_intmd_group' to support creating missing groups
+ * Tuesday, March 24, 1998
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5G_insert(H5G_entry_t *loc, const char *name, H5G_entry_t *ent, hid_t dxpl_id, H5P_genplist_t *oc_plist)
+H5O_loc_t *
+H5G_oloc(H5G_t *grp)
{
- herr_t ret_value=SUCCEED; /* Return value */
- unsigned target=H5G_TARGET_NORMAL;
-
- FUNC_ENTER_NOAPI(H5G_insert, FAIL);
-
- /* Check args. */
- assert (loc);
- assert (name && *name);
- assert (ent);
-
- /* 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 |= H5G_CRT_INTMD_GROUP;
- } /* end if */
-
- /*
- * Lookup and insert the name -- it shouldn't exist yet.
- */
- if (H5G_namei(loc, name, NULL, NULL, NULL, target, NULL, H5G_NAMEI_INSERT, ent, dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "already exists");
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_oloc)
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(grp ? &(grp->oloc) : NULL)
+} /* end H5G_oloc() */
/*-------------------------------------------------------------------------
- * Function: H5G_find
- *
- * Purpose: Finds an object with the specified NAME at location LOC. On
- * successful return, GRP_ENT (if non-null) will be initialized
- * with the symbol table information for the group in which the
- * object appears (it will have an undefined object header
- * address if the object is the root object) and OBJ_ENT will be
- * initialized with the symbol table entry for the object
- * (OBJ_ENT is optional when the caller is interested only in
- * the existence of the object).
- *
- * Errors:
+ * Function: H5G_nameof
*
- * Return: Success: Non-negative, see above for values of GRP_ENT
- * and OBJ_ENT.
+ * Purpose: Returns a pointer to the hier. name for a group.
*
- * Failure: Negative
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 12 1997
+ * Return: Success: Ptr to hier. name
+ * Failure: NULL
*
- * Modifications:
- * Removed the "H5G_entry_t *grp_ent" parameter, since it was unused
- * Quincey Koziol
- * Aug 29 2005
+ * Programmer: Quincey Koziol
+ * Monday, September 12, 2005
*
*-------------------------------------------------------------------------
*/
-herr_t
-H5G_find(H5G_entry_t *loc, const char *name,
- H5G_entry_t *obj_ent/*out*/, hid_t dxpl_id)
+H5G_name_t *
+H5G_nameof(H5G_t *grp)
{
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5G_find, FAIL);
-
- /* check args */
- assert (loc);
- assert (name && *name);
-
- if (H5G_namei(loc, name, NULL, NULL, obj_ent, H5G_TARGET_NORMAL, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
+ /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_nameof)
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(grp ? &(grp->path) : NULL)
+} /* end H5G_nameof() */
/*-------------------------------------------------------------------------
- * Function: H5G_entof
+ * Function: H5G_fileof
*
- * Purpose: Returns a pointer to the entry for a group.
+ * Purpose: Returns the file to which the specified group belongs.
*
- * Return: Success: Ptr to group entry
+ * Return: Success: File pointer.
*
* Failure: NULL
*
* Programmer: Robb Matzke
* Tuesday, March 24, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
-H5G_entry_t *
-H5G_entof (H5G_t *grp)
+H5F_t *
+H5G_fileof(H5G_t *grp)
{
/* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_entof);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_fileof)
- FUNC_LEAVE_NOAPI(grp ? &(grp->ent) : NULL);
-}
+ HDassert(grp);
+
+ FUNC_LEAVE_NOAPI(grp->oloc.file)
+} /* end H5G_fileof() */
/*-------------------------------------------------------------------------
- * Function: H5G_fileof
- *
- * Purpose: Returns the file to which the specified group belongs.
- *
- * Return: Success: File pointer.
+ * Function: H5G_insert_cb
*
- * Failure: NULL
+ * Purpose: Path traversal callback for inserting an object in a group.
*
- * Programmer: Robb Matzke
- * Tuesday, March 24, 1998
+ * Return: Non-negative on success/Negative on failure
*
- * Modifications:
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
*
*-------------------------------------------------------------------------
*/
-H5F_t *
-H5G_fileof (H5G_t *grp)
+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*/)
{
- /* Use FUNC_ENTER_NOAPI_NOINIT_NOFUNC here to avoid performance issues */
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_fileof);
+ H5G_trav_ud7_t *udata = (H5G_trav_ud7_t *)_udata; /* User data passed in */
+ herr_t ret_value = SUCCEED; /* Return value */
- assert (grp);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_insert_cb)
- FUNC_LEAVE_NOAPI(grp->ent.file);
-}
+ /* 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_loc
- *
- * Purpose: Given an object ID return a symbol table entry for the
- * object.
+ * Function: H5G_insert
*
- * Return: Success: Group pointer.
+ * Purpose: Inserts a symbol table entry into the group graph.
*
- * Failure: NULL
+ * Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
- * Tuesday, March 24, 1998
- *
- * Modifications:
+ * Friday, September 19, 1997
*
*-------------------------------------------------------------------------
*/
-H5G_entry_t *
-H5G_loc (hid_t loc_id)
+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)
{
- H5F_t *f;
- H5G_entry_t *ret_value=NULL;
- H5G_t *group=NULL;
- H5T_t *dt=NULL;
- H5D_t *dset=NULL;
- H5A_t *attr=NULL;
-
- FUNC_ENTER_NOAPI(H5G_loc, NULL);
-
- switch (H5I_get_type(loc_id)) {
- case H5I_FILE:
- if (NULL==(f=H5I_object (loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, NULL, "invalid file ID");
- if (NULL==(ret_value=H5G_entof(H5G_rootof(f))))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry for root group");
-
- /* Patch up root group's symbol table entry to reflect this file */
- /* (Since the root group info is only stored once for files which
- * share an underlying low-level file)
- */
- /* (but only for non-mounted files) */
- if(!f->mtab.parent)
- ret_value->file = f;
- break;
+ H5G_trav_ud7_t udata; /* User data for callback routine */
+ unsigned target_flags = H5G_TARGET_NORMAL;
+ herr_t ret_value = SUCCEED; /* Return value */
- case H5I_GENPROP_CLS:
- case H5I_GENPROP_LST:
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of property list");
+ FUNC_ENTER_NOAPI(H5G_insert, FAIL)
- case H5I_ERROR_CLASS:
- case H5I_ERROR_MSG:
- case H5I_ERROR_STACK:
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of error class, message or stack");
+ /* Check args. */
+ HDassert(loc);
+ HDassert(name && *name);
+ HDassert(obj_loc);
- case H5I_GROUP:
- if (NULL==(group=H5I_object (loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, NULL, "invalid group ID");
- if (NULL==(ret_value=H5G_entof(group)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of group");
- break;
+ /* Check for intermediate group creation flag present */
+ if(oc_plist != NULL) {
+ unsigned crt_intmd_group;
- case H5I_DATATYPE:
- if (NULL==(dt=H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid type ID");
- if (NULL==(ret_value=H5T_entof(dt)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of datatype");
- break;
+ 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")
- case H5I_DATASPACE:
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of dataspace");
+ if (crt_intmd_group > 0)
+ target_flags |= H5G_CRT_INTMD_GROUP;
+ } /* end if */
- case H5I_DATASET:
- if (NULL==(dset=H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid data ID");
- if (NULL==(ret_value=H5D_entof(dset)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of dataset");
- break;
+ /* Set up user data callback for path traversal */
+ udata.obj_loc = obj_loc;
+ udata.dxpl_id = dxpl_id;
- case H5I_ATTR:
- if (NULL==(attr=H5I_object(loc_id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid attribute ID");
- if (NULL==(ret_value=H5A_entof(attr)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of attribute");
- break;
+ /*
+ * 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")
- case H5I_REFERENCE:
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "unable to get symbol table entry of reference");
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_insert() */
- default:
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "invalid object ID");
- }
+
+/*-------------------------------------------------------------------------
+ * 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*/)
+{
+ 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 */
+ udata->lnk->name = name;
+
+ /* 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:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ 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_link_cb() */
/*-------------------------------------------------------------------------
@@ -2688,431 +2081,280 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_link (H5G_entry_t *cur_loc, const char *cur_name, H5G_entry_t *new_loc,
- const char *new_name, H5G_link_t type, unsigned namei_flags, hid_t dxpl_id)
+H5G_link(H5G_loc_t *cur_loc, const char *cur_name, H5G_loc_t *new_loc,
+ const char *new_name, H5G_link_t type, unsigned traverse_flags, hid_t dxpl_id)
{
- H5G_entry_t cur_obj; /*entry for the link tail */
- unsigned cur_obj_init=0; /* Flag to indicate that the current object is initialized */
- H5G_entry_t grp_ent; /*ent for grp containing link hd*/
- H5O_stab_t stab_mesg; /*symbol table message */
- const char *rest = NULL; /*last component of new name */
- char *norm_cur_name = NULL; /* Pointer to normalized current name */
- char *norm_new_name = NULL; /* Pointer to normalized current name */
- size_t nchars; /*characters in component */
- size_t offset; /*offset to sym-link value */
- herr_t ret_value=SUCCEED; /* Return value */
+ char *norm_cur_name = NULL; /* Pointer to normalized current name */
+ char *norm_new_name = NULL; /* Pointer to normalized current name */
+ H5G_trav_ud3_t udata; /* User data for callback */
+ H5O_link_t lnk; /* Link to insert */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5G_link);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_link)
/* Check args */
- assert (cur_loc);
- assert (new_loc);
- assert (cur_name && *cur_name);
- assert (new_name && *new_name);
+ HDassert(cur_loc);
+ HDassert(new_loc);
+ HDassert(cur_name && *cur_name);
+ HDassert(new_name && *new_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_new_name=H5G_normalize(new_name))==NULL)
- HGOTO_ERROR (H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name");
+ if((norm_cur_name = H5G_normalize(cur_name)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name")
+ if((norm_new_name = H5G_normalize(new_name)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name")
- switch (type) {
+ switch(type) {
case H5G_LINK_SOFT:
- /*
- * Lookup the the new_name so we can get the group which will contain
- * the new entry. The entry shouldn't exist yet.
- */
- if (H5G_namei(new_loc, norm_new_name, &rest, &grp_ent, NULL,
- H5G_TARGET_NORMAL, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)>=0)
- HGOTO_ERROR (H5E_SYM, H5E_EXISTS, FAIL, "already exists");
- H5E_clear_stack (NULL); /*it's okay that we didn't find it*/
- rest = H5G_component (rest, &nchars);
-
- /*
- * There should be one component left. Make sure it's null
- * terminated and that `rest' points to it.
- */
- assert(!rest[nchars]);
-
- /*
- * Add the link-value to the local heap for the symbol table which
- * will contain the link.
- */
- if (NULL==H5O_read (&grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id))
- HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to determine local heap address");
- if ((size_t)(-1)==(offset=H5HL_insert (grp_ent.file, dxpl_id,
- stab_mesg.heap_addr, HDstrlen(norm_cur_name)+1, norm_cur_name)))
- HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to write link value to local heap");
- H5O_reset (H5O_STAB_ID, &stab_mesg);
-
- /*
- * Create a symbol table entry for the link. The object header is
- * undefined and the cache contains the link-value offset.
- */
- H5G_ent_reset(&cur_obj);
- cur_obj.file = grp_ent.file;
- cur_obj.type = H5G_CACHED_SLINK;
- cur_obj.cache.slink.lval_offset = offset;
- cur_obj_init=1; /* Indicate that the cur_obj struct is initialized */
-
- /*
- * Insert the link head in the symbol table. This shouldn't ever
- * fail because we've already checked that the link head doesn't
- * exist and the file is writable (because the local heap is
- * writable). But if it does, the only side effect is that the local
- * heap has some extra garbage in it.
- *
- * Note: We don't increment the link count of the destination object
- */
- if (H5G_stab_insert (&grp_ent, rest, &cur_obj, FALSE, dxpl_id)<0)
- HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object");
+ /* Construct link information for eventual insertion */
+ lnk.type = H5G_LINK_SOFT;
+ lnk.u.soft.name = norm_cur_name;
+
+ /* Set up user data for creating soft link */
+ udata.file = NULL; /* no file info necessary for soft link */
break;
case H5G_LINK_HARD:
- if (H5G_namei(cur_loc, norm_cur_name, NULL, NULL, &cur_obj, namei_flags, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found");
- cur_obj_init=1; /* Indicate that the cur_obj struct is initialized */
- if (H5G_insert (new_loc, norm_new_name, &cur_obj, dxpl_id, NULL)<0)
- HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to create new name/link for object");
+ {
+ 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, &obj_oloc, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "source object not found")
+
+ /* Construct link information for eventual insertion */
+ lnk.type = H5G_LINK_HARD;
+ lnk.u.hard.addr = obj_oloc.addr;
+
+ /* Set up user data for creating hard link */
+ udata.file = obj_oloc.file;
+ } /* end case */
break;
default:
- HGOTO_ERROR (H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type");
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type")
+ } /* end switch */
+
+ /* Set up common link data */
+#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 */
-done:
- /* Free the group's ID to name buffer, if creating a soft link */
- if(type == H5G_LINK_SOFT)
- H5G_free_ent_name(&grp_ent);
+ /* Set up common user data */
+ udata.lnk = &lnk;
+ udata.dxpl_id = dxpl_id;
- /* Free the ID to name buffer */
- if(cur_obj_init)
- H5G_free_ent_name(&cur_obj);
+ /* Traverse the destination path & create new link */
+ if(H5G_traverse(new_loc, norm_new_name, H5G_TARGET_NORMAL, H5G_link_cb, &udata, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "can't insert link")
+done:
/* Free the normalized path names */
if(norm_cur_name)
H5MM_xfree(norm_cur_name);
if(norm_new_name)
H5MM_xfree(norm_new_name);
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link() */
/*-------------------------------------------------------------------------
- * Function: H5G_get_type
- *
- * Purpose: Returns the type of object pointed to by `ent'.
+ * Function: H5G_get_objinfo_cb
*
- * Return: Success: An object type defined in H5Gpublic.h
+ * Purpose: Callback for retrieving info about an object. This routine
+ * gets the info
*
- * Failure: H5G_UNKNOWN
- *
- * Programmer: Robb Matzke
- * Wednesday, November 4, 1998
+ * Return: Non-negative on success/Negative on failure
*
- * Modifications:
+ * Programmer: Quincey Koziol
+ * Tuesday, September 20, 2005
*
*-------------------------------------------------------------------------
*/
-H5G_obj_t
-H5G_get_type(H5G_entry_t *ent, hid_t dxpl_id)
+static herr_t
+H5G_get_objinfo_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t *lnk,
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/)
{
- htri_t isa;
- size_t i;
- H5G_obj_t ret_value=H5G_UNKNOWN; /* Return value */
-
- FUNC_ENTER_NOAPI(H5G_get_type, H5G_UNKNOWN);
-
- for (i=H5G_ntypes_g; i>0; --i) {
- if ((isa=(H5G_type_g[i-1].isa)(ent, dxpl_id))<0) {
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type");
- } else if (isa) {
- HGOTO_DONE(H5G_type_g[i-1].type);
- }
- }
-
- if (0==i)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ H5G_trav_ud4_t *udata = (H5G_trav_ud4_t *)_udata; /* User data passed in */
+ herr_t ret_value = SUCCEED; /* Return value */
-
-/*-------------------------------------------------------------------------
- * Function: H5G_get_objinfo
- *
- * Purpose: Returns information about an object.
- *
- * Return: Success: Non-negative with info about the object
- * returned through STATBUF if it isn't the null
- * pointer.
- *
- * Failure: Negative
- *
- * Programmer: Robb Matzke
- * Monday, April 13, 1998
- *
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002
- * Added `id to name' support.
- *
- * John Mainzer - 6/8/05
- * Modified function to use the new dirtied parmeter of
- * H5AC_unprotect(), which allows management of the is_dirty
- * field of the cache info to be moved into the cache code.
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link,
- H5G_stat_t *statbuf/*out*/, hid_t dxpl_id)
-{
- H5G_entry_t grp_ent, obj_ent;
- herr_t ret_value=SUCCEED; /* Return value */
+ FUNC_ENTER_NOAPI_NOINIT(H5G_get_objinfo_cb)
- FUNC_ENTER_NOAPI(H5G_get_objinfo, FAIL);
+ /* Check if the name in this group resolved to a valid link */
+ if(lnk == NULL && obj_loc == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
- assert (loc);
- assert (name && *name);
- if (statbuf) HDmemset (statbuf, 0, sizeof *statbuf);
+ /* Only modify user's buffer if it's available */
+ if(udata->statbuf) {
+ H5G_stat_t *statbuf = udata->statbuf; /* Convenience pointer for statbuf */
- /* Find the object's symbol table entry */
- if (H5G_namei(loc, name, NULL, &grp_ent/*out*/, &obj_ent/*out*/,
- (unsigned)(follow_link?H5G_TARGET_NORMAL:H5G_TARGET_SLINK), NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)<0)
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to stat object");
+ /* Reset buffer */
+ HDmemset(statbuf, 0, sizeof(H5G_stat_t));
- /*
- * Initialize the stat buf. Symbolic links aren't normal objects and
- * therefore don't have much of the normal info. However, the link value
- * length is specific to symbolic links.
- */
- if (statbuf) {
/* Common code to retrieve the file's fileno */
- if(H5F_get_fileno(obj_ent.file,&statbuf->fileno)<0)
- HGOTO_ERROR (H5E_FILE, H5E_BADVALUE, FAIL, "unable to read fileno");
-
- /* Retrieve information specific to each type of entry */
- if (H5G_CACHED_SLINK==obj_ent.type) {
- H5O_stab_t stab_mesg; /* Symbol table message info */
- const char *s; /* Pointer to link value */
- const H5HL_t *heap; /* Pointer to local heap for group */
-
- /* Named object is a symbolic link */
- if (NULL == H5O_read(&grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read symbolic link value")
+ /* (Use the object location's file info, if it's available) */
+ if(H5F_get_fileno((obj_loc ? obj_loc : grp_loc)->oloc->file, &statbuf->fileno) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_BADVALUE, FAIL, "unable to read fileno")
+
+ /* Get common info from link */
+ if(lnk != NULL) {
+ statbuf->cset = lnk->cset;
+ statbuf->ctime = lnk->ctime;
+ } /* end if */
+ else {
+ /* lookup must be on '.' */
+ HDassert(HDstrcmp(name, ".") == 0);
- /* Lock the local heap */
- if (NULL == (heap = H5HL_protect(grp_ent.file, dxpl_id, stab_mesg.heap_addr)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value")
+ /* Set "fake" hard link info */
+ statbuf->cset = H5T_CSET_ASCII;
+ statbuf->ctime = 0;
+ } /* end else */
- s = H5HL_offset_into(grp_ent.file, heap, obj_ent.cache.slink.lval_offset);
+ /* 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) {
+ /* Set object type */
+ statbuf->type = H5G_LINK;
- statbuf->u.slink.linklen = HDstrlen(s) + 1; /*count the null terminator*/
+ /* Get length of link value */
+ statbuf->u.slink.linklen = HDstrlen(lnk->u.soft.name) + 1; /*count the null terminator*/
+ } /* end if */
+ /* Get info for hard link */
+ else {
+ /* Get object type */
+ statbuf->type = H5O_obj_type(obj_loc->oloc, udata->dxpl_id);
+ if(statbuf->type == H5G_UNKNOWN)
+ H5E_clear_stack(NULL); /* clear any errors resulting from checking type */
- /* Release the local heap */
- if (H5HL_unprotect(grp_ent.file, dxpl_id, heap, stab_mesg.heap_addr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value")
+ /* Get basic info for object */
+ statbuf->u.obj.objno = obj_loc->oloc->addr;
+ statbuf->u.obj.nlink = H5O_link(obj_loc->oloc, 0, udata->dxpl_id);
- /* Set object type */
- statbuf->type = H5G_LINK;
- } else {
- /* Some other type of object */
- statbuf->u.obj.objno = obj_ent.header;
- statbuf->u.obj.nlink = H5O_link (&obj_ent, 0, dxpl_id);
- if (NULL==H5O_read(&obj_ent, H5O_MTIME_ID, 0, &(statbuf->u.obj.mtime), dxpl_id)) {
+ /* Get creation time for object */
+ if(NULL == H5O_read(obj_loc->oloc, H5O_MTIME_ID, 0, &(statbuf->u.obj.mtime), udata->dxpl_id)) {
H5E_clear_stack(NULL);
- if (NULL==H5O_read(&obj_ent, H5O_MTIME_NEW_ID, 0, &(statbuf->u.obj.mtime), dxpl_id)) {
+ if(NULL == H5O_read(obj_loc->oloc, H5O_MTIME_NEW_ID, 0, &(statbuf->u.obj.mtime), udata->dxpl_id)) {
H5E_clear_stack(NULL);
statbuf->u.obj.mtime = 0;
- }
- }
- /* Get object type */
- statbuf->type = H5G_get_type(&obj_ent, dxpl_id);
- H5E_clear_stack(NULL); /*clear errors resulting from checking type*/
+ } /* end if */
+ } /* end if */
/* Get object header information */
- if(H5O_get_info(&obj_ent, &(statbuf->u.obj.ohdr), dxpl_id)<0)
+ if(H5O_get_info(obj_loc->oloc, &(statbuf->u.obj.ohdr), udata->dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object header information")
- }
+ } /* end else */
} /* end if */
done:
- /* Free the ID to name buffers */
- H5G_free_ent_name(&grp_ent);
- H5G_free_ent_name(&obj_ent);
+ /* 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);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_get_objinfo_cb() */
/*-------------------------------------------------------------------------
- * Function: H5G_get_num_objs
+ * Function: H5G_get_objinfo
*
- * Purpose: Private function for H5Gget_num_objs. Returns the number
- * of objects in the group. It iterates all B-tree leaves
- * and sum up total number of group members.
+ * Purpose: Returns information about an object.
*
- * Return: Success: Non-negative
+ * Return: Success: Non-negative with info about the object
+ * returned through STATBUF if it isn't the null
+ * pointer.
*
* Failure: Negative
*
- * Programmer: Raymond Lu
- * Nov 20, 2002
- *
- * Modifications:
+ * Programmer: Robb Matzke
+ * Monday, April 13, 1998
*
*-------------------------------------------------------------------------
*/
-static herr_t
-H5G_get_num_objs(H5G_entry_t *loc, hsize_t *num_objs, hid_t dxpl_id)
+herr_t
+H5G_get_objinfo(H5G_loc_t *loc, const char *name, hbool_t follow_link,
+ H5G_stat_t *statbuf/*out*/, hid_t dxpl_id)
{
- H5O_stab_t stab_mesg; /*info about B-tree */
- herr_t ret_value;
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_get_num_objs);
-
- /* Sanity check */
- assert(loc);
- assert(num_objs);
-
- /* Reset the number of objects in the group */
- *num_objs = 0;
-
- /* Get the B-tree info */
- if (NULL==H5O_read (loc, H5O_STAB_ID, 0, &stab_mesg, dxpl_id))
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address");
-
- /* Iterate over the group members */
- if ((ret_value = H5B_iterate (loc->file, dxpl_id, H5B_SNODE,
- H5G_node_sumup, stab_mesg.btree_addr, num_objs))<0)
- HERROR (H5E_SYM, H5E_CANTINIT, "iteration operator failed");
+ H5G_trav_ud4_t udata; /* User data for callback */
+ herr_t ret_value = SUCCEED; /* Return value */
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_ENTER_NOAPI(H5G_get_objinfo, FAIL)
-
-/*-------------------------------------------------------------------------
- * Function: H5G_get_objname_by_idx
- *
- * Purpose: Private function for H5Gget_objname_by_idx.
- * Returns the name of objects in the group by giving index.
- *
- * Return: Success: Non-negative
- *
- * Failure: Negative
- *
- * Programmer: Raymond Lu
- * Nov 20, 2002
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static ssize_t
-H5G_get_objname_by_idx(H5G_entry_t *loc, hsize_t idx, char* name, size_t size, hid_t dxpl_id)
-{
- H5O_stab_t stab; /*info about local heap & B-tree */
- H5G_bt_it_ud2_t udata; /* Iteration information */
- ssize_t ret_value; /* Return value */
+ HDassert(loc);
+ HDassert(name && *name);
- FUNC_ENTER_NOAPI_NOINIT(H5G_get_objname_by_idx);
+ /* Set up user data for retrieving information */
+ udata.statbuf = statbuf;
+ udata.follow_link = follow_link;
+ udata.dxpl_id = dxpl_id;
- /* Sanity check */
- assert(loc);
-
- /* Get the B-tree & local heap info */
- if (NULL==H5O_read (loc, H5O_STAB_ID, 0, &stab, dxpl_id))
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address");
-
- /* Set iteration information */
- udata.idx = idx;
- udata.num_objs = 0;
- udata.heap_addr = stab.heap_addr;
- udata.name = NULL;
-
- /* Iterate over the group members */
- if ((ret_value = H5B_iterate (loc->file, dxpl_id, H5B_SNODE,
- H5G_node_name, stab.btree_addr, &udata))<0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed");
-
- /* If we don't know the name now, we almost certainly went out of bounds */
- if(udata.name==NULL)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound");
-
- /* Get the length of the name */
- ret_value = (ssize_t)HDstrlen(udata.name);
-
- /* Copy the name into the user's buffer, if given */
- if(name) {
- HDstrncpy(name, udata.name, MIN((size_t)(ret_value+1),size));
- if((size_t)ret_value >= size)
- name[size-1]='\0';
- } /* end if */
+ /* Traverse the group hierarchy to locate the object to get info about */
+ if(H5G_traverse(loc, name, (unsigned)(follow_link ? H5G_TARGET_NORMAL : H5G_TARGET_SLINK),
+ H5G_get_objinfo_cb, &udata, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name doesn't exist")
done:
- /* Free the duplicated name */
- if(udata.name!=NULL)
- H5MM_xfree(udata.name);
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_get_objinfo() */
/*-------------------------------------------------------------------------
- * Function: H5G_get_objtype_by_idx
- *
- * Purpose: Private function for H5Gget_objtype_by_idx.
- * Returns the type of objects in the group by giving index.
- *
- * Return: Success: H5G_GROUP(1), H5G_DATASET(2), H5G_TYPE(3)
+ * Function: H5G_linkval_cb
*
- * Failure: UNKNOWN
+ * Purpose: Callback for retrieving soft link value for an object.
*
- * Programmer: Raymond Lu
- * Nov 20, 2002
+ * Return: Non-negative on success/Negative on failure
*
- * Modifications:
+ * Programmer: Quincey Koziol
+ * Tuesday, September 20, 2005
*
*-------------------------------------------------------------------------
*/
-static H5G_obj_t
-H5G_get_objtype_by_idx(H5G_entry_t *loc, hsize_t idx, hid_t dxpl_id)
+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*/)
{
- H5O_stab_t stab_mesg; /*info about local heap & B-tree */
- H5G_bt_it_ud3_t udata; /* User data for B-tree callback */
- H5G_obj_t ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_get_objtype_by_idx);
+ H5G_trav_ud5_t *udata = (H5G_trav_ud5_t *)_udata; /* User data passed in */
+ herr_t ret_value = SUCCEED; /* Return value */
- /* Sanity check */
- assert(loc);
-
- /* Get the B-tree & local heap info */
- if (NULL==H5O_read (loc, H5O_STAB_ID, 0, &stab_mesg, dxpl_id))
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address");
+ FUNC_ENTER_NOAPI_NOINIT(H5G_linkval_cb)
- /* Set iteration information */
- udata.idx = idx;
- udata.num_objs = 0;
- udata.type = H5G_UNKNOWN;
+ /* 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")
- /* Iterate over the group members */
- if (H5B_iterate (loc->file, dxpl_id, H5B_SNODE,
- H5G_node_type, stab_mesg.btree_addr, &udata)<0)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "iteration operator failed");
+ if(H5G_LINK_SOFT != lnk->type)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object is not a symbolic link")
- /* If we don't know the type now, we almost certainly went out of bounds */
- if(udata.type==H5G_UNKNOWN)
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "index out of bound");
-
- ret_value = udata.type;
+ /* 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:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ /* 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() */
/*-------------------------------------------------------------------------
@@ -3131,65 +2373,27 @@ done:
* Programmer: Robb Matzke
* Monday, April 13, 1998
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002
- * Added `id to name' support.
- *
- * John Mainzer - 6/8/05
- * Modified function to use the new dirtied parmeter of
- * H5AC_unprotect(), which allows management of the is_dirty
- * field of the cache info to be moved into the cache code.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_linkval (H5G_entry_t *loc, const char *name, size_t size, char *buf/*out*/, hid_t dxpl_id)
+H5G_linkval(H5G_loc_t *loc, const char *name, size_t size, char *buf/*out*/, hid_t dxpl_id)
{
- const char *s = NULL;
- H5G_entry_t grp_ent, obj_ent;
- H5O_stab_t stab_mesg;
- const H5HL_t *heap;
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_linkval);
-
- /*
- * Get the symbol table entry for the link head and the symbol table
- * entry for the group in which the link head appears.
- */
- if (H5G_namei(loc, name, NULL, &grp_ent/*out*/, &obj_ent/*out*/,
- H5G_TARGET_SLINK, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)<0)
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "symbolic link was not found");
- if (H5G_CACHED_SLINK!=obj_ent.type)
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "object is not a symbolic link");
-
- /*
- * Get the address of the local heap for the link value and a pointer
- * into that local heap.
- */
- if (NULL==H5O_read (&grp_ent, H5O_STAB_ID, 0, &stab_mesg, dxpl_id))
- HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "unable to determine local heap address");
+ H5G_trav_ud5_t udata; /* User data for callback */
+ herr_t ret_value = SUCCEED; /* Return value */
- if (NULL == (heap = H5HL_protect(grp_ent.file, dxpl_id, stab_mesg.heap_addr)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value")
+ FUNC_ENTER_NOAPI_NOINIT(H5G_linkval)
- s = H5HL_offset_into(grp_ent.file, heap, obj_ent.cache.slink.lval_offset);
+ /* Set up user data for retrieving information */
+ udata.size = size;
+ udata.buf = buf;
- /* Copy to output buffer */
- if (size>0 && buf)
- HDstrncpy (buf, s, size);
-
- if (H5HL_unprotect(grp_ent.file, dxpl_id, heap, stab_mesg.heap_addr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value")
+ /* 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:
- /* Free the ID to name buffers */
- H5G_free_ent_name(&grp_ent);
- H5G_free_ent_name(&obj_ent);
-
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5G_linkval() */
/*-------------------------------------------------------------------------
@@ -3202,44 +2406,36 @@ done:
* Programmer: Robb Matzke
* Monday, July 20, 1998
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_set_comment(H5G_entry_t *loc, const char *name, const char *buf, hid_t dxpl_id)
+H5G_set_comment(H5G_loc_t *loc, const char *name, const char *buf, hid_t dxpl_id)
{
- H5G_entry_t obj_ent;
+ H5O_loc_t obj_oloc; /* Object's location */
H5O_name_t comment;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5G_set_comment);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_set_comment)
/* Get the symbol table entry for the object */
- if (H5G_find(loc, name, &obj_ent/*out*/, dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
+ if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, &obj_oloc/*out*/, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
/* Remove the previous comment message if any */
- if (H5O_remove(&obj_ent, H5O_NAME_ID, 0, TRUE, dxpl_id)<0)
+ if(H5O_remove(&obj_oloc, H5O_NAME_ID, 0, TRUE, dxpl_id) < 0)
H5E_clear_stack(NULL);
/* Add the new message */
- if (buf && *buf) {
- comment.s = H5MM_xstrdup(buf);
- if (H5O_modify(&obj_ent, H5O_NAME_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, &comment, dxpl_id)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to set comment object header message");
- H5O_reset(H5O_NAME_ID, &comment);
- }
+ if(buf && *buf) {
+ /* Casting away const OK -QAK */
+ comment.s = (char *)buf;
+ if(H5O_modify(&obj_oloc, H5O_NAME_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, &comment, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to set comment object header message")
+ } /* end if */
done:
- /* Free the ID to name buffer */
- H5G_free_ent_name(&obj_ent);
-
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_set_comment() */
/*-------------------------------------------------------------------------
@@ -3256,30 +2452,25 @@ done:
* Programmer: Robb Matzke
* Monday, July 20, 1998
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
static int
-H5G_get_comment(H5G_entry_t *loc, const char *name, size_t bufsize, char *buf, hid_t dxpl_id)
+H5G_get_comment(H5G_loc_t *loc, const char *name, size_t bufsize, char *buf, hid_t dxpl_id)
{
H5O_name_t comment;
- H5G_entry_t obj_ent;
- int ret_value;
+ H5O_loc_t obj_oloc; /* Object's location */
+ int ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5G_get_comment);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_get_comment)
/* Get the symbol table entry for the object */
- if (H5G_find(loc, name, &obj_ent/*out*/, dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
+ if(H5G_obj_find(loc, name, H5G_TARGET_NORMAL, &obj_oloc/*out*/, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
/* Get the message */
comment.s = NULL;
- if (NULL==H5O_read(&obj_ent, H5O_NAME_ID, 0, &comment, dxpl_id)) {
- if (buf && bufsize>0)
+ if(NULL == H5O_read(&obj_oloc, H5O_NAME_ID, 0, &comment, dxpl_id)) {
+ if(buf && bufsize > 0)
buf[0] = '\0';
ret_value = 0;
} else {
@@ -3287,14 +2478,57 @@ H5G_get_comment(H5G_entry_t *loc, const char *name, size_t bufsize, char *buf, h
HDstrncpy(buf, comment.s, bufsize);
ret_value = (int)HDstrlen(comment.s);
H5O_reset(H5O_NAME_ID, &comment);
- }
+ } /* end else */
done:
- /* Free the ID to name buffer */
- H5G_free_ent_name(&obj_ent);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_get_comment() */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+
+/*-------------------------------------------------------------------------
+ * 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() */
/*-------------------------------------------------------------------------
@@ -3307,68 +2541,92 @@ done:
* Programmer: Robb Matzke
* Thursday, September 17, 1998
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_unlink(H5G_entry_t *loc, const char *name, hid_t dxpl_id)
+H5G_unlink(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
{
- H5G_entry_t grp_ent, obj_ent;
- const char *base=NULL;
+ H5G_trav_ud6_t udata; /* User data for callback */
char *norm_name = NULL; /* Pointer to normalized name */
- H5G_obj_t obj_type; /* Object type */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5G_unlink);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_unlink)
/* Sanity check */
- assert(loc);
- assert(name && *name);
+ 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");
-
- /* Reset the group entries to known values in a portable way */
- H5G_ent_reset(&grp_ent);
- H5G_ent_reset(&obj_ent);
-
- /* Get the entry for the group that contains the object to be unlinked */
- if (H5G_namei(loc, norm_name, NULL, &grp_ent, &obj_ent,
- H5G_TARGET_SLINK|H5G_TARGET_MOUNT, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
- if (!H5F_addr_defined(grp_ent.header))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "no containing group specified");
- if (NULL==(base=H5G_basename(norm_name, NULL)) || '/'==*base)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "problems obtaining object base name");
-
- /* Get object type before unlink */
- if((obj_type = H5G_get_type(&obj_ent, dxpl_id)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't determine object type");
-
- /* Remove the name from the symbol table */
- if (H5G_stab_remove(&grp_ent, base, dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to unlink name from symbol table");
-
- /* Search the open IDs and replace names for unlinked object */
- if (H5G_replace_name(obj_type, &obj_ent, NULL, NULL, NULL, NULL, OP_UNLINK )<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to replace name");
+ if((norm_name = H5G_normalize(name)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "can't normalize name")
-done:
- /* Free the ID to name buffers */
- H5G_free_ent_name(&grp_ent);
- H5G_free_ent_name(&obj_ent);
+ /* 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);
-}
+ 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 *src_name_r = NULL; /* Ref-counted version of src name */
+ 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 */
+ src_name_r = H5RS_wrap(udata->src_name);
+ HDassert(src_name_r);
+ dst_name_r = H5RS_wrap(udata->dst_name);
+ HDassert(dst_name_r);
+ if(H5G_name_replace(udata->type, obj_loc, src_name_r, udata->src_loc, dst_name_r, udata->dst_loc, OP_MOVE) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name ")
+
+done:
+ /* Cleanup */
+ if(src_name_r)
+ H5RS_decr(src_name_r);
+ 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() */
/*-------------------------------------------------------------------------
@@ -3381,87 +2639,102 @@ done:
* Programmer: Robb Matzke
* Friday, September 25, 1998
*
- * Modifications:
- *
- * Raymond Lu
- * Thursday, April 18, 2002
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_move(H5G_entry_t *src_loc, const char *src_name, H5G_entry_t *dst_loc,
+H5G_move(H5G_loc_t *src_loc, const char *src_name, H5G_loc_t *dst_loc,
const char *dst_name, hid_t dxpl_id)
{
- H5G_stat_t sb;
- char *linkval=NULL;
- size_t lv_size=32;
- H5G_entry_t obj_ent; /* Object entry for object being moved */
- H5RS_str_t *src_name_r; /* Ref-counted version of src name */
- H5RS_str_t *dst_name_r; /* Ref-counted version of dest name */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5G_stat_t sb; /* Object info for link to move */
+ H5G_trav_ud2_t udata; /* User data for traversal */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5G_move);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_move)
/* Sanity check */
- assert(src_loc);
- assert(dst_loc);
- assert(src_name && *src_name);
- assert(dst_name && *dst_name);
-
- if (H5G_get_objinfo(src_loc, src_name, FALSE, &sb, dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found");
- if (H5G_LINK==sb.type) {
+ HDassert(src_loc);
+ HDassert(dst_loc);
+ HDassert(src_name && *src_name);
+ HDassert(dst_name && *dst_name);
+
+ if(H5G_get_objinfo(src_loc, src_name, FALSE, &sb, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
+ if(H5G_LINK == sb.type) {
+ char *linkval = NULL;
+
/*
* When renaming a symbolic link we rename the link but don't change
* the value of the link.
*/
- do {
- if (NULL==(linkval=H5MM_realloc(linkval, 2*lv_size)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate space for symbolic link value");
- linkval[lv_size-1] = '\0';
- if (H5G_linkval(src_loc, src_name, lv_size, linkval, dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read symbolic link value");
- } while (linkval[lv_size-1]);
- if (H5G_link(src_loc, linkval, dst_loc, dst_name, H5G_LINK_SOFT,
- H5G_TARGET_NORMAL, dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to rename symbolic link");
+ if(NULL == (linkval = H5MM_malloc(sb.u.slink.linklen)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate space for symbolic link value")
+ if(H5G_linkval(src_loc, src_name, sb.u.slink.linklen, linkval, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read symbolic link value")
+ if(H5G_link(src_loc, linkval, dst_loc, dst_name, H5G_LINK_SOFT, H5G_TARGET_NORMAL, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to rename symbolic link")
H5MM_xfree(linkval);
-
} else {
/*
* Rename the object.
*/
- if (H5G_link(src_loc, src_name, dst_loc, dst_name, H5G_LINK_HARD,
- H5G_TARGET_MOUNT, dxpl_id)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object");
- }
+ if(H5G_link(src_loc, src_name, dst_loc, dst_name, H5G_LINK_HARD, H5G_TARGET_MOUNT, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to register new name for object")
+ } /* end else */
+
+ /* Set up user data for name replacement */
+ udata.type = sb.type;
+ udata.src_name = src_name;
+ udata.src_loc = src_loc;
+ udata.dst_name = dst_name;
+ udata.dst_loc = dst_loc;
/* Search the open ID list and replace names for the move operation
- * This has to be done here because H5G_link and H5G_unlink have
- * internal object entries, and do not modify the entries list
- */
- if (H5G_namei(src_loc, src_name, NULL, NULL, &obj_ent, H5G_TARGET_NORMAL|H5G_TARGET_SLINK, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id))
- HGOTO_ERROR (H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link");
- src_name_r=H5RS_wrap(src_name);
- assert(src_name_r);
- dst_name_r=H5RS_wrap(dst_name);
- assert(dst_name_r);
- if (H5G_replace_name(sb.type, &obj_ent, src_name_r, src_loc, dst_name_r, dst_loc, OP_MOVE )<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to replace name ");
- H5RS_decr(src_name_r);
- H5RS_decr(dst_name_r);
- H5G_free_ent_name(&obj_ent);
+ */
+ if(H5G_traverse(src_loc, src_name, H5G_TARGET_NORMAL|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 deregister old object name");
+ if(H5G_unlink(src_loc, src_name, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to deregister old object name")
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_move() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_insertion_file_cb
+ *
+ * Purpose: Callback for finding insertion file. This routine sets the
+ * correct information for the file pointer to return.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_insertion_file_cb(H5G_loc_t *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk,
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+{
+ H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_insertion_file_cb)
+
+ /* Check if the name in this group resolves to a valid location */
+ /* (which is not what we want) */
+ if(obj_loc != NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_EXISTS, FAIL, "name already exists")
+
+ /* Get file pointer for location */
+ udata->file = grp_loc->oloc->file;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_insertion_file_cb() */
/*-------------------------------------------------------------------------
@@ -3478,65 +2751,43 @@ done:
* Programmer: Robb Matzke
* Wednesday, October 14, 1998
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 18 Sep 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
H5F_t *
-H5G_insertion_file(H5G_entry_t *loc, const char *name, hid_t dxpl_id)
+H5G_insertion_file(H5G_loc_t *loc, const char *name, hid_t dxpl_id)
{
H5F_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5G_insertion_file, NULL);
+ FUNC_ENTER_NOAPI(H5G_insertion_file, NULL)
- assert(loc);
- assert(name && *name);
+ HDassert(loc);
+ HDassert(name && *name);
/* Check if the location the object will be inserted into is part of a
* file mounting chain (either a parent or a child) and perform a more
* rigorous determination of the location's file (which traverses into
* mounted files, etc.).
*/
- if(H5F_has_mount(loc->file) || H5F_is_mount(loc->file)) {
- const char *rest;
- H5G_entry_t grp_ent;
- size_t size;
+ if(H5F_has_mount(loc->oloc->file) || H5F_is_mount(loc->oloc->file)) {
+ H5G_trav_ud1_t udata; /* User data for traversal */
/*
* Look up the name to get the containing group and to make sure the name
* doesn't already exist.
*/
- if (H5G_namei(loc, name, &rest, &grp_ent, NULL, H5G_TARGET_NORMAL, NULL, H5G_NAMEI_TRAVERSE, NULL, dxpl_id)>=0) {
- H5G_free_ent_name(&grp_ent);
- HGOTO_ERROR(H5E_SYM, H5E_EXISTS, NULL, "name already exists");
- } /* end if */
- H5E_clear_stack(NULL);
-
- /* Make sure only the last component wasn't resolved */
- rest = H5G_component(rest, &size);
- assert(*rest && size>0);
- rest = H5G_component(rest+size, NULL);
- if (*rest) {
- H5G_free_ent_name(&grp_ent);
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, NULL, "insertion point not found");
- } /* end if */
+ if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_insertion_file_cb, &udata, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_EXISTS, NULL, "name already exists")
/* Set return value */
- ret_value=grp_ent.file;
-
- /* Free the ID to name buffer */
- H5G_free_ent_name(&grp_ent);
+ ret_value = udata.file;
} /* end if */
else
/* Use the location's file */
- ret_value=loc->file;
+ ret_value = loc->oloc->file;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_insertion_file() */
/*-------------------------------------------------------------------------
@@ -3552,630 +2803,25 @@ done:
*
* Comments: Used now only on the root group close, in H5F_close()
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5G_free_grp_name(H5G_t *grp)
{
- H5G_entry_t *ent; /* Group object's entry */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5G_free_grp_name, FAIL);
-
- /* Check args */
- assert(grp && grp->shared);
- assert(grp->shared->fo_count > 0);
-
- /* Get the entry for the group */
- if (NULL==( ent = H5G_entof(grp)))
- HGOTO_ERROR (H5E_SYM, H5E_CANTINIT, FAIL, "cannot get entry");
-
- /* Free the entry */
- H5G_free_ent_name(ent);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_free_ent_name
- *
- * Purpose: Free the 'ID to name' buffers.
- *
- * Return: Success
- *
- * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
- *
- * Date: August 22, 2002
- *
- * Comments:
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_free_ent_name(H5G_entry_t *ent)
-{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5G_free_ent_name, FAIL);
+ FUNC_ENTER_NOAPI(H5G_free_grp_name, FAIL)
/* Check args */
- assert(ent);
-
- if(ent->user_path_r) {
- H5RS_decr(ent->user_path_r);
- ent->user_path_r=NULL;
- } /* end if */
- if(ent->canon_path_r) {
- H5RS_decr(ent->canon_path_r);
- ent->canon_path_r=NULL;
- } /* end if */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_replace_name
- *
- * Purpose: Search the list of open IDs and replace names according to a
- * particular operation. The operation occured on the LOC
- * entry, which had SRC_NAME previously. The new name (if there
- * is one) is DST_NAME. Additional entry location information
- * (currently only needed for the 'move' operation) is passed
- * in SRC_LOC and DST_LOC.
- *
- * Return: Success: 0, Failure: -1
- *
- * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
- *
- * Date: June 11, 2002
- *
- * Comments:
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5G_replace_name(H5G_obj_t type, H5G_entry_t *loc,
- H5RS_str_t *src_name, H5G_entry_t *src_loc,
- H5RS_str_t *dst_name, H5G_entry_t *dst_loc, H5G_names_op_t op )
-{
- H5G_names_t names; /* Structure to hold operation information for callback */
- unsigned search_group=0; /* Flag to indicate that groups are to be searched */
- unsigned search_dataset=0; /* Flag to indicate that datasets are to be searched */
- unsigned search_datatype=0; /* Flag to indicate that datatypes are to be searched */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI(H5G_replace_name, FAIL);
-
- /* Set up common information for callback */
- names.src_name=src_name;
- names.dst_name=dst_name;
- names.loc=loc;
- names.src_loc=src_loc;
- names.dst_loc=dst_loc;
- names.op=op;
-
- /* Determine which types of IDs need to be operated on */
- switch(type) {
- /* Object is a group */
- case H5G_GROUP:
- /* Search and replace names through group IDs */
- search_group=1;
- break;
-
- /* Object is a dataset */
- case H5G_DATASET:
- /* Search and replace names through dataset IDs */
- search_dataset=1;
- break;
-
- /* Object is a named datatype */
- case H5G_TYPE:
- /* Search and replace names through datatype IDs */
- search_datatype=1;
- break;
-
- case H5G_UNKNOWN: /* We pass H5G_UNKNOWN as object type when we need to search all IDs */
- case H5G_LINK: /* Symbolic links might resolve to any object, so we need to search all IDs */
- /* Check if we will need to search groups */
- if(H5I_nmembers(H5I_GROUP)>0)
- search_group=1;
-
- /* Check if we will need to search datasets */
- if(H5I_nmembers(H5I_DATASET)>0)
- search_dataset=1;
-
- /* Check if we will need to search datatypes */
- if(H5I_nmembers(H5I_DATATYPE)>0)
- search_datatype=1;
- break;
-
- default:
- HGOTO_ERROR (H5E_DATATYPE, H5E_BADTYPE, FAIL, "not valid object type");
- } /* end switch */
-
- /* Search through group IDs */
- if(search_group)
- H5I_search(H5I_GROUP, H5G_replace_ent, &names);
-
- /* Search through dataset IDs */
- if(search_dataset)
- H5I_search(H5I_DATASET, H5G_replace_ent, &names);
-
- /* Search through datatype IDs */
- if(search_datatype)
- H5I_search(H5I_DATATYPE, H5G_replace_ent, &names);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_common_path
- *
- * Purpose: Determine if one path is a valid prefix of another path
- *
- * Return: TRUE for valid prefix, FALSE for not a valid prefix, FAIL
- * on error
- *
- * Programmer: Quincey Koziol, koziol@ncsa.uiuc.edu
- *
- * Date: September 24, 2002
- *
- * Comments:
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static htri_t
-H5G_common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r)
-{
- const char *fullpath; /* Pointer to actual fullpath string */
- const char *prefix; /* Pointer to actual prefix string */
- size_t nchars1,nchars2; /* Number of characters in components */
- htri_t ret_value=FALSE; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_common_path);
-
- /* Get component of each name */
- fullpath=H5RS_get_str(fullpath_r);
- assert(fullpath);
- fullpath=H5G_component(fullpath,&nchars1);
- assert(fullpath);
- prefix=H5RS_get_str(prefix_r);
- assert(prefix);
- prefix=H5G_component(prefix,&nchars2);
- assert(prefix);
-
- /* Check if we have a real string for each component */
- while(*fullpath && *prefix) {
- /* Check that the components we found are the same length */
- if(nchars1==nchars2) {
- /* Check that the two components are equal */
- if(HDstrncmp(fullpath,prefix,nchars1)==0) {
- /* Advance the pointers in the names */
- fullpath+=nchars1;
- prefix+=nchars2;
-
- /* Get next component of each name */
- fullpath=H5G_component(fullpath,&nchars1);
- assert(fullpath);
- prefix=H5G_component(prefix,&nchars2);
- assert(prefix);
- } /* end if */
- else
- HGOTO_DONE(FALSE);
- } /* end if */
- else
- HGOTO_DONE(FALSE);
- } /* end while */
-
- /* If we reached the end of the prefix path to check, it must be a valid prefix */
- if(*prefix=='\0')
- ret_value=TRUE;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_build_fullpath
- *
- * Purpose: Build a full path from a prefix & base pair of reference counted
- * strings
- *
- * Return: Pointer to reference counted string on success, NULL on error
- *
- * Programmer: Quincey Koziol, koziol@ncsa.uiuc.edu
- *
- * Date: August 19, 2005
- *
- * Comments:
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static H5RS_str_t *
-H5G_build_fullpath(const H5RS_str_t *prefix_r, const H5RS_str_t *name_r)
-{
- const char *prefix; /* Pointer to raw string of prefix */
- const char *name; /* Pointer to raw string of name */
- char *full_path; /* Full user path built */
- size_t path_len; /* Length of the path */
- unsigned need_sep; /* Flag to indicate if separator is needed */
- H5RS_str_t *ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_build_fullpath)
-
- /* Get the pointer to the prefix */
- prefix=H5RS_get_str(prefix_r);
-
- /* Get the length of the prefix */
- path_len=HDstrlen(prefix);
-
- /* Determine if there is a trailing separator in the name */
- if(prefix[path_len-1]=='/')
- need_sep=0;
- else
- need_sep=1;
-
- /* Get the pointer to the raw src user path */
- name=H5RS_get_str(name_r);
-
- /* Add in the length needed for the '/' separator and the relative path */
- path_len+=HDstrlen(name)+need_sep;
-
- /* Allocate space for the path */
- if(NULL==(full_path = H5FL_BLK_MALLOC(str_buf,path_len+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
-
- /* Build full path */
- HDstrcpy(full_path,prefix);
- if(need_sep)
- HDstrcat(full_path,"/");
- HDstrcat(full_path,name);
-
- /* Create reference counted string for path */
- ret_value=H5RS_own(full_path);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_build_fullpath() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5G_replace_ent
- *
- * Purpose: H5I_search callback function to replace group entry names
- *
- * Return: Success: 0, Failure: -1
- *
- * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
- *
- * Date: June 5, 2002
- *
- * Comments:
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static int
-H5G_replace_ent(void *obj_ptr, hid_t obj_id, void *key)
-{
- const H5G_names_t *names = (const H5G_names_t *)key; /* Get operation's information */
- H5G_entry_t *ent = NULL; /* Group entry for object that the ID refers to */
- H5F_t *top_ent_file; /* Top file in entry's mounted file chain */
- H5F_t *top_loc_file; /* Top file in location's mounted file chain */
- herr_t ret_value = SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5G_replace_ent);
-
- assert(obj_ptr);
-
- /* Get the symbol table entry */
- switch(H5I_get_type(obj_id)) {
- case H5I_GROUP:
- ent = H5G_entof((H5G_t*)obj_ptr);
- break;
-
- case H5I_DATASET:
- ent = H5D_entof((H5D_t*)obj_ptr);
- break;
-
- case H5I_DATATYPE:
- /* Avoid non-named datatypes */
- if(!H5T_is_named((H5T_t*)obj_ptr))
- HGOTO_DONE(SUCCEED); /* Do not exit search over IDs */
-
- ent = H5T_entof((H5T_t*)obj_ptr);
- break;
-
- default:
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object");
- } /* end switch */
- assert(ent);
-
- switch(names->op) {
- /*-------------------------------------------------------------------------
- * OP_MOUNT
- *-------------------------------------------------------------------------
- */
- case OP_MOUNT:
- if(ent->user_path_r) {
- if(ent->file->mtab.parent && H5RS_cmp(ent->user_path_r,ent->canon_path_r)) {
- /* Find the "top" file in the chain of mounted files */
- top_ent_file=ent->file->mtab.parent;
- while(top_ent_file->mtab.parent!=NULL)
- top_ent_file=top_ent_file->mtab.parent;
- } /* end if */
- else
- top_ent_file=ent->file;
-
- /* Check for entry being in correct file (or mounted file) */
- if(top_ent_file->shared == names->loc->file->shared) {
- /* Check if the source is along the entry's path */
- /* (But not actually the entry itself) */
- if(H5G_common_path(ent->user_path_r,names->src_name) &&
- H5RS_cmp(ent->user_path_r,names->src_name)!=0) {
- /* Hide the user path */
- ent->user_path_hidden++;
- } /* end if */
- } /* end if */
- } /* end if */
- break;
-
- /*-------------------------------------------------------------------------
- * OP_UNMOUNT
- *-------------------------------------------------------------------------
- */
- case OP_UNMOUNT:
- if(ent->user_path_r) {
- if(ent->file->mtab.parent) {
- /* Find the "top" file in the chain of mounted files for the entry */
- top_ent_file=ent->file->mtab.parent;
- while(top_ent_file->mtab.parent!=NULL)
- top_ent_file=top_ent_file->mtab.parent;
- } /* end if */
- else
- top_ent_file=ent->file;
-
- if(names->loc->file->mtab.parent) {
- /* Find the "top" file in the chain of mounted files for the location */
- top_loc_file=names->loc->file->mtab.parent;
- while(top_loc_file->mtab.parent!=NULL)
- top_loc_file=top_loc_file->mtab.parent;
- } /* end if */
- else
- top_loc_file=names->loc->file;
-
- /* If the ID's entry is not in the file we operated on, skip it */
- if(top_ent_file->shared == top_loc_file->shared) {
- if(ent->user_path_hidden) {
- if(H5G_common_path(ent->user_path_r,names->src_name)) {
- /* Un-hide the user path */
- ent->user_path_hidden--;
- } /* end if */
- } /* end if */
- else {
- if(H5G_common_path(ent->user_path_r,names->src_name)) {
- /* Free user path */
- H5RS_decr(ent->user_path_r);
- ent->user_path_r=NULL;
- } /* end if */
- } /* end else */
- } /* end if */
- } /* end if */
- break;
-
- /*-------------------------------------------------------------------------
- * OP_UNLINK
- *-------------------------------------------------------------------------
- */
- case OP_UNLINK:
- /* If the ID's entry is not in the file we operated on, skip it */
- if(ent->file->shared == names->loc->file->shared &&
- names->loc->canon_path_r && ent->canon_path_r && ent->user_path_r) {
- /* Check if we are referring to the same object */
- if(H5F_addr_eq(ent->header, names->loc->header)) {
- /* Check if the object was opened with the same canonical path as the one being moved */
- if(H5RS_cmp(ent->canon_path_r,names->loc->canon_path_r)==0) {
- /* Free user path */
- H5RS_decr(ent->user_path_r);
- ent->user_path_r=NULL;
- } /* end if */
- } /* end if */
- else {
- /* Check if the location being unlinked is in the canonical path for the current object */
- if(H5G_common_path(ent->canon_path_r,names->loc->canon_path_r)) {
- /* Free user path */
- H5RS_decr(ent->user_path_r);
- ent->user_path_r=NULL;
- } /* end if */
- } /* end else */
- } /* end if */
- break;
-
- /*-------------------------------------------------------------------------
- * OP_MOVE
- *-------------------------------------------------------------------------
- */
- case OP_MOVE: /* H5Gmove case, check for relative names case */
- /* If the ID's entry is not in the file we operated on, skip it */
- if(ent->file->shared == names->loc->file->shared) {
- if(ent->user_path_r && names->loc->user_path_r &&
- names->src_loc->user_path_r && names->dst_loc->user_path_r) {
- H5RS_str_t *src_path_r; /* Full user path of source name */
- H5RS_str_t *dst_path_r; /* Full user path of destination name */
- H5RS_str_t *canon_src_path_r; /* Copy of canonical part of source path */
- H5RS_str_t *canon_dst_path_r; /* Copy of canonical part of destination path */
-
- /* Sanity check */
- HDassert(names->src_name);
- HDassert(names->dst_name);
-
- /* Make certain that the source and destination names are full (not relative) paths */
- if(*(H5RS_get_str(names->src_name))!='/') {
- /* Create reference counted string for full src path */
- if((src_path_r = H5G_build_fullpath(names->src_loc->user_path_r, names->src_name)) == NULL)
- HGOTO_ERROR (H5E_SYM, H5E_PATH, FAIL, "can't build source path name")
- } /* end if */
- else
- src_path_r=H5RS_dup(names->src_name);
- if(*(H5RS_get_str(names->dst_name))!='/') {
- /* Create reference counted string for full dst path */
- if((dst_path_r = H5G_build_fullpath(names->dst_loc->user_path_r, names->dst_name)) == NULL)
- HGOTO_ERROR (H5E_SYM, H5E_PATH, FAIL, "can't build destination path name")
- } /* end if */
- else
- dst_path_r=H5RS_dup(names->dst_name);
-
- /* Get the canonical parts of the source and destination names */
-
- /* Check if the object being moved was accessed through a mounted file */
- if(H5RS_cmp(names->loc->user_path_r,names->loc->canon_path_r)!=0) {
- size_t non_canon_name_len; /* Length of non-canonical part of name */
-
- /* Get current string lengths */
- non_canon_name_len=H5RS_len(names->loc->user_path_r)-H5RS_len(names->loc->canon_path_r);
-
- canon_src_path_r=H5RS_create(H5RS_get_str(src_path_r)+non_canon_name_len);
- canon_dst_path_r=H5RS_create(H5RS_get_str(dst_path_r)+non_canon_name_len);
- } /* end if */
- else {
- canon_src_path_r=H5RS_dup(src_path_r);
- canon_dst_path_r=H5RS_dup(dst_path_r);
- } /* end else */
-
- /* Check if the link being changed in the file is along the canonical path for this object */
- if(H5G_common_path(ent->canon_path_r,canon_src_path_r)) {
- size_t user_dst_len; /* Length of destination user path */
- size_t canon_dst_len; /* Length of destination canonical path */
- const char *old_user_path; /* Pointer to previous user path */
- char *new_user_path; /* Pointer to new user path */
- char *new_canon_path; /* Pointer to new canonical path */
- const char *tail_path; /* Pointer to "tail" of path */
- size_t tail_len; /* Pointer to "tail" of path */
- char *src_canon_prefix; /* Pointer to source canonical path prefix of component which is moving */
- size_t src_canon_prefix_len;/* Length of the source canonical path prefix */
- char *dst_canon_prefix; /* Pointer to destination canonical path prefix of component which is moving */
- size_t dst_canon_prefix_len;/* Length of the destination canonical path prefix */
- char *user_prefix; /* Pointer to user path prefix of component which is moving */
- size_t user_prefix_len; /* Length of the user path prefix */
- char *src_comp; /* The source name of the component which is actually changing */
- char *dst_comp; /* The destination name of the component which is actually changing */
- const char *canon_src_path; /* pointer to canonical part of source path */
- const char *canon_dst_path; /* pointer to canonical part of destination path */
-
- /* Get the pointers to the raw strings */
- canon_src_path=H5RS_get_str(canon_src_path_r);
- canon_dst_path=H5RS_get_str(canon_dst_path_r);
-
- /* Get the source & destination components */
- src_comp=HDstrrchr(canon_src_path,'/');
- assert(src_comp);
- dst_comp=HDstrrchr(canon_dst_path,'/');
- assert(dst_comp);
-
- /* Find the canonical prefixes for the entry */
- src_canon_prefix_len=HDstrlen(canon_src_path)-HDstrlen(src_comp);
- if(NULL==(src_canon_prefix = H5MM_malloc(src_canon_prefix_len+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDstrncpy(src_canon_prefix,canon_src_path,src_canon_prefix_len);
- src_canon_prefix[src_canon_prefix_len]='\0';
-
- dst_canon_prefix_len=HDstrlen(canon_dst_path)-HDstrlen(dst_comp);
- if(NULL==(dst_canon_prefix = H5MM_malloc(dst_canon_prefix_len+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDstrncpy(dst_canon_prefix,canon_dst_path,dst_canon_prefix_len);
- dst_canon_prefix[dst_canon_prefix_len]='\0';
-
- /* Hold this for later use */
- old_user_path=H5RS_get_str(ent->user_path_r);
-
- /* Find the user prefix for the entry */
- user_prefix_len=HDstrlen(old_user_path)-H5RS_len(ent->canon_path_r);
- if(NULL==(user_prefix = H5MM_malloc(user_prefix_len+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- HDstrncpy(user_prefix,old_user_path,user_prefix_len);
- user_prefix[user_prefix_len]='\0';
-
- /* Set the tail path info */
- tail_path=old_user_path+user_prefix_len+src_canon_prefix_len+HDstrlen(src_comp);
- tail_len=HDstrlen(tail_path);
-
- /* Get the length of the destination paths */
- user_dst_len=user_prefix_len+dst_canon_prefix_len+HDstrlen(dst_comp)+tail_len;
- canon_dst_len=dst_canon_prefix_len+HDstrlen(dst_comp)+tail_len;
-
- /* Allocate space for the new user path */
- if(NULL==(new_user_path = H5FL_BLK_MALLOC(str_buf,user_dst_len+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
-
- /* Allocate space for the new canonical path */
- if(NULL==(new_canon_path = H5FL_BLK_MALLOC(str_buf,canon_dst_len+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
-
- /* Create the new names */
- HDstrcpy(new_user_path,user_prefix);
- HDstrcat(new_user_path,dst_canon_prefix);
- HDstrcat(new_user_path,dst_comp);
- HDstrcat(new_user_path,tail_path);
- HDstrcpy(new_canon_path,dst_canon_prefix);
- HDstrcat(new_canon_path,dst_comp);
- HDstrcat(new_canon_path,tail_path);
-
- /* Release the old user & canonical paths */
- H5RS_decr(ent->user_path_r);
- H5RS_decr(ent->canon_path_r);
-
- /* Take ownership of the new user & canonical paths */
- ent->user_path_r=H5RS_own(new_user_path);
- ent->canon_path_r=H5RS_own(new_canon_path);
-
- /* Free the extra paths allocated */
- H5MM_xfree(src_canon_prefix);
- H5MM_xfree(dst_canon_prefix);
- H5MM_xfree(user_prefix);
- } /* end if */
-
-
- /* Free the extra paths allocated */
- H5RS_decr(src_path_r);
- H5RS_decr(dst_path_r);
- H5RS_decr(canon_src_path_r);
- H5RS_decr(canon_dst_path_r);
- } /* end if */
- else {
- /* Release the old user path */
- if(ent->user_path_r) {
- H5RS_decr(ent->user_path_r);
- ent->user_path_r = NULL;
- } /* end if */
- } /* end else */
- } /* end if */
- break;
+ HDassert(grp && grp->shared);
+ HDassert(grp->shared->fo_count > 0);
- default:
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid call");
- } /* end switch */
+ /* Free the path */
+ H5G_name_free(&(grp->path));
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_free_grp_name() */
/*-------------------------------------------------------------------------
@@ -4279,44 +2925,49 @@ H5G_unmount(H5G_t *grp)
*-------------------------------------------------------------------------
*/
static herr_t
-H5G_copy(H5G_entry_t *ent_src, H5G_entry_t *loc_dst,
+H5G_copy(H5G_loc_t *src_loc, H5G_loc_t *dst_loc,
const char *name_dst, hid_t plist_id)
{
H5P_genplist_t *oc_plist; /* Property list created */
hid_t dxpl_id = H5AC_dxpl_id;
- H5G_entry_t ent_new;
+ H5G_name_t new_path; /* Copied object group hier. path */
+ H5O_loc_t new_oloc; /* Copied object object location */
+ H5G_loc_t new_loc; /* Group location of object copied */
hbool_t entry_inserted = FALSE; /* Flag to indicate that the new entry was inserted into a group */
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_copy, FAIL);
- HDassert(ent_src);
- HDassert(ent_src->file);
- HDassert(loc_dst);
- HDassert(loc_dst->file);
+ HDassert(src_loc);
+ HDassert(src_loc->oloc->file);
+ HDassert(dst_loc);
+ HDassert(dst_loc->oloc->file);
HDassert(name_dst);
/* Get the property list */
if(NULL == (oc_plist = H5I_object(plist_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a property list")
- /* Reset group entry for new object */
- H5G_ent_reset(&ent_new);
- ent_new.file = loc_dst->file;
+ /* Set up copied object location to fill in */
+ new_loc.oloc = &new_oloc;
+ new_loc.path = &new_path;
+ H5G_loc_reset(&new_loc);
+ new_oloc.file = dst_loc->oloc->file;
/* copy the object from the source file to the destination file */
- if(H5O_copy_header(ent_src, &ent_new, dxpl_id) < 0)
+ if(H5O_copy_header(src_loc->oloc, &new_oloc, dxpl_id) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
/* Insert the new object in the destination file's group */
- if(H5G_insert(loc_dst, name_dst, &ent_new, dxpl_id, oc_plist) < 0)
+ if(H5G_insert(dst_loc, name_dst, &new_loc, dxpl_id, oc_plist) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to insert the name")
entry_inserted = TRUE;
done:
/* Free the ID to name buffers */
if(entry_inserted)
- H5G_free_ent_name(&ent_new);
+ H5G_loc_free(&new_loc);
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5G_copy() */
+
diff --git a/src/H5Gent.c b/src/H5Gent.c
index 52729c6..08f7e77 100644
--- a/src/H5Gent.c
+++ b/src/H5Gent.c
@@ -27,56 +27,24 @@
#include "H5FLprivate.h" /* Free Lists */
#include "H5Gpkg.h" /* Groups */
#include "H5HLprivate.h" /* Local Heaps */
+#include "H5Iprivate.h" /* IDs */
+
+/* Private macros */
+#define H5G_NO_CHANGE (-1) /*see H5G_ent_modified() */
/* Private prototypes */
#ifdef NOT_YET
static herr_t H5G_ent_modified(H5G_entry_t *ent, H5G_type_t cache_type);
#endif /* NOT_YET */
+static herr_t H5G_ent_encode(H5F_t *f, uint8_t **pp, const H5G_entry_t *ent);
+static herr_t H5G_ent_decode(H5F_t *f, const uint8_t **pp,
+ H5G_entry_t *ent/*out*/);
/* Declare extern the PQ free list for the wrapped strings */
H5FL_BLK_EXTERN(str_buf);
/*-------------------------------------------------------------------------
- * Function: H5G_ent_cache
- *
- * Purpose: Returns a pointer to the cache associated with the symbol
- * table entry. You should modify the cache directly, then call
- * H5G_ent_modified() with the new cache type (even if the type is
- * still the same).
- *
- * Return: Success: Ptr to the cache in the symbol table entry.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * Friday, September 19, 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-const H5G_cache_t *
-H5G_ent_cache(const H5G_entry_t *ent, H5G_type_t *cache_type)
-{
- const H5G_cache_t *ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI(H5G_ent_cache, NULL);
-
- if (!ent)
- HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, NULL, "no entry");
- if (cache_type)
- *cache_type = ent->type;
-
- /* Set return value */
- ret_value=(const H5G_cache_t *)&(ent->cache);
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5G_ent_modified
*
* Purpose: This function should be called after you make any
@@ -94,8 +62,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-#ifdef NOT_YET
-static herr_t
+herr_t
H5G_ent_modified(H5G_entry_t *ent, H5G_type_t cache_type)
{
FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_modified)
@@ -109,7 +76,6 @@ H5G_ent_modified(H5G_entry_t *ent, H5G_type_t cache_type)
FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5G_ent_modified */
-#endif /* NOT_YET */
/*-------------------------------------------------------------------------
@@ -179,18 +145,18 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5G_ent_decode(H5F_t *f, const uint8_t **pp, H5G_entry_t *ent)
{
const uint8_t *p_ret = *pp;
uint32_t tmp;
- FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_decode);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_ent_decode)
/* check arguments */
- assert(f);
- assert(pp);
- assert(ent);
+ HDassert(f);
+ HDassert(pp);
+ HDassert(ent);
ent->file = f;
@@ -222,8 +188,8 @@ H5G_ent_decode(H5F_t *f, const uint8_t **pp, H5G_entry_t *ent)
*pp = p_ret + H5G_SIZEOF_ENTRY(f);
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5G_ent_decode() */
/*-------------------------------------------------------------------------
@@ -296,12 +262,12 @@ done:
*
*-------------------------------------------------------------------------
*/
-herr_t
+static herr_t
H5G_ent_encode(H5F_t *f, uint8_t **pp, const H5G_entry_t *ent)
{
uint8_t *p_ret = *pp + H5G_SIZEOF_ENTRY(f);
- FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_encode);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_ent_encode);
/* check arguments */
assert(f);
@@ -348,31 +314,19 @@ H5G_ent_encode(H5F_t *f, uint8_t **pp, const H5G_entry_t *ent)
/*-------------------------------------------------------------------------
- * Function: H5G_ent_copy
- *
- * Purpose: Do a deep copy of symbol table entries
+ * Function: H5G_ent_copy
*
- * Return: Success: 0, Failure: -1
+ * Purpose: Do a deep copy of symbol table entries
*
- * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ * Return: Success: Non-negative
+ * Failure: Negative
*
- * Date: August 2002
+ * Programmer: Pedro Vicente
+ * pvn@ncsa.uiuc.edu
+ * ???day, August ??, 2002
*
- * Comments:
- *
- * Modifications:
- * Quincey Koziol, Sept. 25, 2002:
- * - Changed source & destination parameters to match the rest
- * of the functions in the library.
- * - Added 'depth' parameter to determine how much of the group
- * entry structure we want to copy. The new depths are:
- * H5G_COPY_NULL - Copy all the fields from the
- * source to the destination, but set the destination's
- * user path and canonical path to NULL.
- * H5G_COPY_LIMITED - Copy all the fields from the
- * source to the destination, except for the user path
- * field, keeping it the same as its
- * previous value in the destination.
+ * Notes: 'depth' parameter determines how much of the group entry
+ * structure we want to copy. The values are:
* H5G_COPY_SHALLOW - Copy all the fields from the source
* to the destination, including the user path and
* canonical path. (Destination "takes ownership" of
@@ -384,68 +338,48 @@ H5G_ent_encode(H5F_t *f, uint8_t **pp, const H5G_entry_t *ent)
*-------------------------------------------------------------------------
*/
herr_t
-H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src, H5G_ent_copy_depth_t depth)
+H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src, H5G_copy_depth_t depth)
{
- H5RS_str_t *tmp_user_path_r=NULL; /* Temporary string pointer for entry's user path */
-
- FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_copy);
+ FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_copy)
/* Check arguments */
- assert(src);
- assert(dst);
-
- /* If the depth is "very shallow", keep the old entry's user path */
- if(depth==H5G_COPY_LIMITED) {
- tmp_user_path_r=dst->user_path_r;
- if(dst->canon_path_r)
- H5RS_decr(dst->canon_path_r);
- } /* end if */
+ HDassert(src);
+ HDassert(dst);
+ HDassert(depth == H5G_COPY_SHALLOW || depth == H5G_COPY_DEEP);
/* Copy the top level information */
- HDmemcpy(dst,src,sizeof(H5G_entry_t));
+ HDmemcpy(dst, src, sizeof(H5G_entry_t));
/* Deep copy the names */
- if(depth==H5G_COPY_DEEP) {
- dst->user_path_r=H5RS_dup(src->user_path_r);
- dst->canon_path_r=H5RS_dup(src->canon_path_r);
- } else if(depth==H5G_COPY_LIMITED) {
- dst->user_path_r=tmp_user_path_r;
- dst->canon_path_r=H5RS_dup(src->canon_path_r);
- } else if(depth==H5G_COPY_NULL) {
- dst->user_path_r=NULL;
- dst->canon_path_r=NULL;
- } else if(depth==H5G_COPY_SHALLOW) {
-#ifndef NDEBUG
+ if(depth == H5G_COPY_DEEP) {
+ /* Nothing currently */
+ ;
+ } else if(depth == H5G_COPY_SHALLOW) {
/* Discarding 'const' qualifier OK - QAK */
H5G_ent_reset((H5G_entry_t *)src);
-#endif /* NDEBUG */
} /* end if */
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5G_ent_copy() */
/*-------------------------------------------------------------------------
- * Function: H5G_ent_reset
- *
- * Purpose: Reset a symbol table entry to an empty state
- *
- * Return: Success: 0, Failure: -1
+ * Function: H5G_ent_reset
*
- * Programmer: Quincey Koziol, koziol@ncsa.uiuc.edu
+ * Purpose: Reset a symbol table entry to an empty state
*
- * Date: August 2005
+ * Return: Success: Non-negative
+ * Failure: Negative
*
- * Comments:
- *
- * Modifications:
+ * Programmer: Quincey Koziol
+ * ?day, August ??, 2005
*
*-------------------------------------------------------------------------
*/
herr_t
H5G_ent_reset(H5G_entry_t *ent)
{
- FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_reset);
+ FUNC_ENTER_NOAPI_NOFUNC(H5G_ent_reset)
/* Check arguments */
HDassert(ent);
@@ -454,126 +388,83 @@ H5G_ent_reset(H5G_entry_t *ent)
HDmemset(ent, 0, sizeof(H5G_entry_t));
ent->header = HADDR_UNDEF;
- FUNC_LEAVE_NOAPI(SUCCEED);
+ FUNC_LEAVE_NOAPI(SUCCEED)
} /* end H5G_ent_reset() */
/*-------------------------------------------------------------------------
- * Function: H5G_ent_set_name
+ * Function: H5G_ent_convert
*
- * Purpose: Set the name of a symbol entry OBJ, located at LOC
+ * Purpose: Convert a link to a symbol table entry
*
- * Return: Success: 0, Failure: -1
+ * Return: Success: Non-negative, with *pp pointing to the first byte
+ * after the last symbol.
*
- * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ * Failure: Negative
*
- * Date: August 22, 2002
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 20 2005
*
*-------------------------------------------------------------------------
*/
herr_t
-H5G_ent_set_name(H5G_entry_t *loc, H5G_entry_t *obj, const char *name)
+H5G_ent_convert(H5F_t *f, haddr_t heap_addr, const char *name, const H5O_link_t *lnk,
+ H5G_entry_t *ent, hid_t dxpl_id)
{
- size_t name_len; /* Length of name to append */
- herr_t ret_value = SUCCEED;
+ size_t name_offset; /* Offset of name in heap */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5G_ent_set_name, FAIL)
+ FUNC_ENTER_NOAPI(H5G_ent_convert, FAIL)
- assert(loc);
- assert(obj);
- assert(name);
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(heap_addr));
+ HDassert(name);
+ HDassert(lnk);
+
+ /* Reset the new entry */
+ H5G_ent_reset(ent);
+
+ /*
+ * Add the new name to the heap.
+ */
+ name_offset = H5HL_insert(f, dxpl_id, heap_addr, HDstrlen(name) + 1, name);
+ if(0 == name_offset || (size_t)(-1) == name_offset)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, "unable to insert symbol name into heap")
+ ent->name_off = name_offset;
+
+ /* Build correct information for symbol table entry based on link type */
+ switch(lnk->type) {
+ case H5G_LINK_HARD:
+ ent->type = H5G_NOTHING_CACHED;
+ ent->header = lnk->u.hard.addr;
+ break;
- /* Reset the object's previous names, if they exist */
- if(obj->user_path_r) {
- H5RS_decr(obj->user_path_r);
- obj->user_path_r=NULL;
- } /* end if */
- if(obj->canon_path_r) {
- H5RS_decr(obj->canon_path_r);
- obj->canon_path_r=NULL;
- } /* end if */
- obj->user_path_hidden=0;
-
- /* Get the length of the new name */
- name_len = HDstrlen(name);
-
- /* Modify the object's user path, if a user path exists in the location */
- if(loc->user_path_r) {
- const char *loc_user_path; /* Pointer to raw string for user path */
- size_t user_path_len; /* Length of location's user path name */
- char *new_user_path; /* Pointer to new user path */
-
- /* Get the length of the strings involved */
- user_path_len = H5RS_len(loc->user_path_r);
-
- /* Modify the object's user path */
-
- /* Get the raw string for the user path */
- loc_user_path=H5RS_get_str(loc->user_path_r);
- assert(loc_user_path);
-
- /* The location's user path already ends in a '/' separator */
- if ('/'==loc_user_path[user_path_len-1]) {
- if (NULL==(new_user_path = H5FL_BLK_MALLOC(str_buf,user_path_len+name_len+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- HDstrcpy(new_user_path, loc_user_path);
- } /* end if */
- /* The location's user path needs a separator */
- else {
- if (NULL==(new_user_path = H5FL_BLK_MALLOC(str_buf,user_path_len+1+name_len+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- HDstrcpy(new_user_path, loc_user_path);
- HDstrcat(new_user_path, "/");
- } /* end else */
-
- /* Append the component's name */
- HDstrcat(new_user_path, name);
-
- /* Give ownership of the user path to the entry */
- obj->user_path_r=H5RS_own(new_user_path);
- assert(obj->user_path_r);
- } /* end if */
+ case H5G_LINK_SOFT:
+ {
+ size_t lnk_offset; /* Offset to sym-link value */
- /* Modify the object's canonical path, if a canonical path exists in the location */
- if(loc->canon_path_r) {
- const char *loc_canon_path; /* Pointer to raw string for canonical path */
- size_t canon_path_len; /* Length of location's canonical path name */
- char *new_canon_path; /* Pointer to new canonical path */
-
- /* Get the length of the strings involved */
- canon_path_len = H5RS_len(loc->canon_path_r);
-
- /* Modify the object's canonical path */
-
- /* Get the raw string for the canonical path */
- loc_canon_path=H5RS_get_str(loc->canon_path_r);
- assert(loc_canon_path);
-
- /* The location's canonical path already ends in a '/' separator */
- if ('/'==loc_canon_path[canon_path_len-1]) {
- if (NULL==(new_canon_path = H5FL_BLK_MALLOC(str_buf,canon_path_len+name_len+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- HDstrcpy(new_canon_path, loc_canon_path);
- } /* end if */
- /* The location's canonical path needs a separator */
- else {
- if (NULL==(new_canon_path = H5FL_BLK_MALLOC(str_buf,canon_path_len+1+name_len+1)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- HDstrcpy(new_canon_path, loc_canon_path);
- HDstrcat(new_canon_path, "/");
- } /* end else */
-
- /* Append the component's name */
- HDstrcat(new_canon_path, name);
-
- /* Give ownership of the canonical path to the entry */
- obj->canon_path_r=H5RS_own(new_canon_path);
- assert(obj->canon_path_r);
- } /* end if */
+ /* Insert link value into local heap */
+ if((size_t)(-1) == (lnk_offset = H5HL_insert(f, dxpl_id, heap_addr,
+ HDstrlen(lnk->u.soft.name) + 1, lnk->u.soft.name)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to write link value to local heap")
+
+ ent->type = H5G_CACHED_SLINK;
+ ent->cache.slink.lval_offset = lnk_offset;
+ } /* end case */
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type")
+ } /* end switch */
+
+ /* Set the file for the entry */
+ ent->file = f;
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_ent_set_name() */
+} /* end H5G_ent_convert() */
/*-------------------------------------------------------------------------
@@ -581,17 +472,12 @@ done:
*
* Purpose: Prints debugging information about a symbol table entry.
*
- * Errors:
- *
* Return: Non-negative on success/Negative on failure
*
* Programmer: Robb Matzke
* matzke@llnl.gov
* Aug 29 1997
*
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The HEAP argument is passed by value.
*-------------------------------------------------------------------------
*/
herr_t
@@ -664,3 +550,4 @@ H5G_ent_debug(H5F_t UNUSED *f, hid_t dxpl_id, const H5G_entry_t *ent, FILE * str
FUNC_LEAVE_NOAPI(SUCCEED);
}
+
diff --git a/src/H5Glink.c b/src/H5Glink.c
new file mode 100644
index 0000000..74361ca
--- /dev/null
+++ b/src/H5Glink.c
@@ -0,0 +1,725 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Glink.c
+ * Sep 5 2005
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Functions for handling link messages.
+ *
+ *-------------------------------------------------------------------------
+ */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+
+/* Packages needed by this file... */
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Gpkg.h" /* Groups */
+#include "H5HLprivate.h" /* Local Heaps */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+
+/* Private typedefs */
+
+/* Data structure to hold table of links for a group */
+typedef struct {
+ size_t nlinks; /* # of links in table */
+ H5O_link_t *lnks; /* Pointer to array of links */
+} H5G_link_table_t;
+
+/* User data for link message iteration when building link table */
+typedef struct {
+ H5G_link_table_t *ltable; /* Pointer to link table to build */
+ size_t curr_lnk; /* Current link to operate on */
+} H5G_link_ud1_t;
+
+/* User data for deleting a link in the link messages */
+typedef struct {
+ /* downward */
+ const char *name; /* Name to search for */
+ H5F_t *file; /* File that object header is located within */
+ hid_t dxpl_id; /* DXPL during insertion */
+
+ /* upward */
+ H5G_obj_t *obj_type; /* Type of object deleted */
+} H5G_link_ud2_t;
+
+/* User data for link message iteration when querying object info */
+typedef struct {
+ /* downward */
+ const char *name; /* Name to search for */
+ H5F_t *file; /* File that object header is located within */
+ hid_t dxpl_id; /* DXPL during insertion */
+
+ /* upward */
+ H5G_stat_t *statbuf; /* Stat buffer for info */
+} H5G_link_ud3_t;
+
+/* User data for link message iteration when querying object location */
+typedef struct {
+ /* downward */
+ const char *name; /* Name to search for */
+
+ /* upward */
+ H5O_link_t *lnk; /* Link struct to fill in */
+ hbool_t found; /* Flag to indicate that the object was found */
+} H5G_link_ud4_t;
+
+/* User data for link message iteration when querying soft link value */
+typedef struct {
+ /* downward */
+ const char *name; /* Name to search for */
+ size_t size; /* Buffer size for link value */
+
+ /* upward */
+ char *buf; /* Buffer to fill with link value */
+} H5G_link_ud5_t;
+
+/* Private macros */
+
+/* PRIVATE PROTOTYPES */
+static int H5G_link_cmp_name(const void *lnk1, const void *lnk2);
+static herr_t H5G_link_build_table_cb(const void *_mesg, unsigned idx, void *_udata);
+static herr_t H5G_link_build_table(H5O_loc_t *oloc, hid_t dxpl_id,
+ H5G_link_table_t *ltable);
+static herr_t H5G_link_release_table(H5G_link_table_t *ltable);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_cmp_name
+ *
+ * Purpose: Callback routine for comparing two link messages.
+ *
+ * Return: An integer less than, equal to, or greater than zero if the
+ * first argument is considered to be respectively less than,
+ * equal to, or greater than the second. If two members compare
+ * as equal, their order in the sorted array is undefined.
+ * (i.e. same as strcmp())
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 5 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5G_link_cmp_name(const void *lnk1, const void *lnk2)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_link_cmp_name)
+
+ FUNC_LEAVE_NOAPI(HDstrcmp(((const H5O_link_t *)lnk1)->name, ((const H5O_link_t *)lnk2)->name))
+} /* end H5G_link_cmp_name() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_build_table_cb
+ *
+ * Purpose: Callback routine for searching 'link' messages for a particular
+ * name.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 5 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_link_build_table_cb(const void *_mesg, unsigned UNUSED idx, void *_udata)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *)_mesg; /* Pointer to link */
+ H5G_link_ud1_t *udata = (H5G_link_ud1_t *)_udata; /* 'User data' passed in */
+ herr_t ret_value=H5O_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_link_build_table_cb)
+
+ /* check arguments */
+ HDassert(lnk);
+ HDassert(udata);
+ HDassert(udata->curr_lnk < udata->ltable->nlinks);
+
+ /* Copy link message into table */
+ if(H5O_copy(H5O_LINK_ID, lnk, &(udata->ltable->lnks[udata->curr_lnk])) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, H5O_ITER_ERROR, "can't copy link message")
+
+ /* Increment current link entry to operate on */
+ udata->curr_lnk++;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link_build_table_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_build_table
+ *
+ * Purpose: Builds a table containing a sorted (alphabetically) list of
+ * links for a group
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Sep 6, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_link_build_table(H5O_loc_t *oloc, hid_t dxpl_id, H5G_link_table_t *ltable)
+{
+ H5O_linfo_t linfo; /* Link info message */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_link_build_table)
+
+ /* Sanity check */
+ HDassert(oloc);
+
+ /* Retrieve the link info */
+ if(NULL == H5O_read(oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info")
+
+ /* Set size of table */
+ ltable->nlinks = linfo.nlinks;
+
+ /* Allocate space for the table entries */
+ if(ltable->nlinks > 0) {
+ H5G_link_ud1_t udata; /* User data for iteration callback */
+
+ if((ltable->lnks = H5MM_malloc(sizeof(H5O_link_t) * ltable->nlinks)) == NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Set up user data for iteration */
+ udata.ltable = ltable;
+ udata.curr_lnk = 0;
+
+ /* Iterate through the link messages, adding them to the table */
+ if(H5O_iterate(oloc, H5O_LINK_ID, H5G_link_build_table_cb, &udata, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over link messages")
+
+ /* Sort link table (XXX: alphabetically, for now) */
+ HDqsort(ltable->lnks, ltable->nlinks, sizeof(H5O_link_t), H5G_link_cmp_name);
+ } /* end if */
+ else
+ ltable->lnks = NULL;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link_build_table() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_release_table
+ *
+ * Purpose: Release table containing a list of links for a group
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Sep 6, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_link_release_table(H5G_link_table_t *ltable)
+{
+ size_t u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_link_release_table)
+
+ /* Sanity check */
+ HDassert(ltable);
+
+ /* Release link info, if any */
+ if(ltable->nlinks > 0) {
+ /* Free link message information */
+ for(u = 0; u < ltable->nlinks; u++)
+ if(H5O_reset(H5O_LINK_ID, &(ltable->lnks[u])) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link message")
+
+ /* Free table of links */
+ H5MM_xfree(ltable->lnks);
+ } /* end if */
+ else
+ HDassert(ltable->lnks == NULL);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link_release_table() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_convert
+ *
+ * Purpose: Converts a group entry into a link object.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 5 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent, const H5HL_t *heap,
+ const char *name)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_link_convert, FAIL)
+
+ /* Check arguments. */
+ HDassert(lnk);
+ HDassert(ent);
+ HDassert(name);
+
+ /* 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->ctime = 0;
+ lnk->name = H5MM_xstrdup(name); /* Casting away const OK -QAK */
+ HDassert(lnk->name);
+ switch(ent->type) {
+ case H5G_NOTHING_CACHED:
+ lnk->type = H5G_LINK_HARD;
+ lnk->u.hard.addr = ent->header;
+ break;
+
+ case H5G_CACHED_SLINK:
+ {
+ const char *s; /* Pointer to link value in heap */
+
+ lnk->type = H5G_LINK_SOFT;
+
+ s = H5HL_offset_into(ent->file, heap, ent->cache.slink.lval_offset);
+ HDassert(s);
+
+ /* Copy to for link */
+ lnk->u.soft.name = H5MM_xstrdup(s);
+ HDassert(lnk->u.soft.name);
+ }
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type")
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link_convert() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_insert
+ *
+ * Purpose: Insert a new symbol into the table described by GRP_ENT in
+ * file F. The name of the new symbol is NAME and its symbol
+ * table entry is OBJ_ENT.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 6 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_link_insert(H5O_loc_t *grp_oloc, H5O_link_t *obj_lnk,
+ hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_link_insert, FAIL)
+
+ /* check arguments */
+ HDassert(grp_oloc && grp_oloc->file);
+ HDassert(obj_lnk);
+
+ /* Insert link message into group */
+ if(H5O_modify(grp_oloc, H5O_LINK_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, obj_lnk, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link_insert() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_get_name_by_idx
+ *
+ * Purpose: Returns the name of objects in the group by giving index.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Sep 6, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5G_link_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name,
+ size_t size, hid_t dxpl_id)
+{
+ H5G_link_table_t ltable = {0, NULL}; /* Link table */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_link_get_name_by_idx, FAIL)
+
+ /* Sanity check */
+ HDassert(oloc);
+
+ /* Build table of all link messages */
+ if(H5G_link_build_table(oloc, dxpl_id, &ltable) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create link message table")
+
+ /* Check for going out of bounds */
+ if(idx >= ltable.nlinks)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound")
+
+ /* Get the length of the name */
+ ret_value = (ssize_t)HDstrlen(ltable.lnks[idx].name);
+
+ /* Copy the name into the user's buffer, if given */
+ if(name) {
+ HDstrncpy(name, ltable.lnks[idx].name, MIN((size_t)(ret_value+1),size));
+ if((size_t)ret_value >= size)
+ name[size-1]='\0';
+ } /* end if */
+
+done:
+ /* Release link table */
+ if(ltable.lnks) {
+ /* Free link table information */
+ if(H5G_link_release_table(&ltable) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTFREE, FAIL, "unable to release link table")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link_get_name_by_idx() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_get_type_by_idx
+ *
+ * Purpose: Returns the type of objects in the group by giving index.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Sep 12, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+H5G_obj_t
+H5G_link_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
+{
+ H5G_link_table_t ltable = {0, NULL}; /* Link table */
+ H5G_obj_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_link_get_type_by_idx, H5G_UNKNOWN)
+
+ /* Sanity check */
+ HDassert(oloc);
+
+ /* Build table of all link messages */
+ if(H5G_link_build_table(oloc, dxpl_id, &ltable) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5G_UNKNOWN, "can't create link message table")
+
+ /* Check for going out of bounds */
+ if(idx >= ltable.nlinks)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "index out of bound")
+
+ /* Determine type of object */
+ if(ltable.lnks[idx].type == H5G_LINK_SOFT)
+ ret_value = H5G_LINK;
+ else {
+ H5O_loc_t tmp_oloc; /* Temporary object location */
+
+ /* Build temporary object location */
+ tmp_oloc.file = oloc->file;
+ tmp_oloc.addr = ltable.lnks[idx].u.hard.addr;
+
+ /* Get the type of the object */
+ if((ret_value = H5O_obj_type(&tmp_oloc, dxpl_id)) == H5G_UNKNOWN)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "can't determine object type")
+ } /* end else */
+
+done:
+ /* Release link table */
+ if(ltable.lnks) {
+ /* Free link table information */
+ if(H5G_link_release_table(&ltable) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTFREE, H5G_UNKNOWN, "unable to release link table")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link_get_type_by_idx() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_remove_cb
+ *
+ * Purpose: Callback routine for deleting 'link' message for a particular
+ * name.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 5 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_link_remove_cb(const void *_mesg, unsigned UNUSED idx, void *_udata)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *)_mesg; /* Pointer to link */
+ H5G_link_ud2_t *udata = (H5G_link_ud2_t *)_udata; /* 'User data' passed in */
+ herr_t ret_value = H5O_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_link_remove_cb)
+
+ /* check arguments */
+ HDassert(lnk);
+ HDassert(udata);
+
+ /* If we've found the right link, get the object type */
+ if(HDstrcmp(lnk->name, udata->name) == 0) {
+ if(lnk->type == H5G_LINK_SOFT)
+ *(udata->obj_type) = H5G_LINK;
+ else {
+ H5O_loc_t tmp_oloc; /* Temporary object location */
+
+ /* Build temporary object location */
+ tmp_oloc.file = udata->file;
+ tmp_oloc.addr = lnk->u.hard.addr;
+
+ /* Get the type of the object */
+ /* Note: no way to check for error :-( */
+ *(udata->obj_type) = H5O_obj_type(&tmp_oloc, udata->dxpl_id);
+ } /* end else */
+
+ /* Stop the iteration, we found the correct link */
+ HGOTO_DONE(H5O_ITER_STOP)
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link_remove_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_remove
+ *
+ * Purpose: Remove NAME from links.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_link_remove(const H5O_loc_t *oloc, const char *name, H5G_obj_t *obj_type,
+ hid_t dxpl_id)
+{
+ H5G_link_ud2_t udata; /* Data to pass through OH iteration */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_link_remove, FAIL)
+
+ HDassert(oloc && oloc->file);
+ HDassert(name && *name);
+
+ /* Initialize data to pass through object header iteration */
+ udata.name = name;
+ udata.file = oloc->file;
+ udata.dxpl_id = dxpl_id;
+ udata.obj_type = obj_type;
+
+ /* Iterate over the link messages to delete the right one */
+ if(H5O_remove_op(oloc, H5O_LINK_ID, H5O_FIRST, H5G_link_remove_cb, &udata, TRUE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete link message")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link_remove() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_iterate
+ *
+ * Purpose: Iterate over the objects in a group
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, October 3, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_link_iterate(H5O_loc_t *oloc, hid_t gid, int skip, int *last_obj,
+ H5G_iterate_t op, void *op_data, hid_t dxpl_id)
+{
+ H5G_link_table_t ltable = {0, NULL}; /* Link table */
+ size_t u; /* Local index variable */
+ herr_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5G_link_iterate, FAIL)
+
+ /* Sanity check */
+ HDassert(oloc);
+ HDassert(H5I_GROUP == H5I_get_type(gid));
+ HDassert(last_obj);
+ HDassert(op);
+
+ /* Build table of all link messages */
+ if(H5G_link_build_table(oloc, dxpl_id, &ltable) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_ITER_ERROR, "can't create link message table")
+
+ /* Check for going out of bounds */
+ if(skip > 0 && (size_t)skip >= ltable.nlinks)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5B_ITER_ERROR, "index out of bound")
+
+ /* Iterate over link messages */
+ for(u = 0, ret_value = H5B_ITER_CONT; u < ltable.nlinks && !ret_value; u++) {
+ if(skip > 0)
+ --skip;
+ else
+ ret_value = (op)(gid, ltable.lnks[u].name, op_data);
+
+ /* Increment the number of entries passed through */
+ /* (whether we skipped them or not) */
+ (*last_obj)++;
+ } /* end for */
+
+ /* Check for callback failure and pass along return value */
+ if(ret_value < 0)
+ HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed");
+
+done:
+ /* Release link table */
+ if(ltable.lnks) {
+ /* Free link table information */
+ if(H5G_link_release_table(&ltable) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_CANTFREE, H5B_ITER_ERROR, "unable to release link table")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link_iterate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_lookup_cb
+ *
+ * Purpose: Callback routine for searching 'link' messages for a particular
+ * name & gettting object location for it
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 20 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_link_lookup_cb(const void *_mesg, unsigned UNUSED idx, void *_udata)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *)_mesg; /* Pointer to link */
+ H5G_link_ud4_t *udata = (H5G_link_ud4_t *)_udata; /* 'User data' passed in */
+ herr_t ret_value = H5O_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_link_lookup_cb)
+
+ /* check arguments */
+ HDassert(lnk);
+ HDassert(udata);
+
+ /* Check for name to get information */
+ if(HDstrcmp(lnk->name, udata->name) == 0) {
+ if(udata->lnk) {
+ /* Copy link information */
+ if(H5O_copy(H5O_LINK_ID, lnk, udata->lnk) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOPY, H5O_ITER_ERROR, "can't copy link message")
+ } /* end if */
+
+ /* Indicate that the correct link was found */
+ udata->found = TRUE;
+
+ /* Stop iteration now */
+ HGOTO_DONE(H5O_ITER_STOP)
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link_lookup_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_link_lookup
+ *
+ * Purpose: Look up an object relative to a group, using link messages.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 20 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_link_lookup(H5O_loc_t *oloc, const char *name, H5O_link_t *lnk,
+ hid_t dxpl_id)
+{
+ H5G_link_ud4_t udata; /* User data for iteration callback */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_link_lookup, FAIL)
+
+ /* check arguments */
+ HDassert(lnk && oloc->file);
+ HDassert(name && *name);
+
+ /* Set up user data for iteration */
+ udata.name = name;
+ udata.lnk = lnk;
+ udata.found = FALSE;
+
+ /* Iterate through the link messages, adding them to the table */
+ if(H5O_iterate(oloc, H5O_LINK_ID, H5G_link_lookup_cb, &udata, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over link messages")
+
+ /* Check if we found the link we were looking for */
+ if(!udata.found)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "object not found")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_link_lookup() */
+
diff --git a/src/H5Gloc.c b/src/H5Gloc.c
new file mode 100644
index 0000000..e2a293f
--- /dev/null
+++ b/src/H5Gloc.c
@@ -0,0 +1,469 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/*-------------------------------------------------------------------------
+ *
+ * Created: H5Gloc.c
+ * Sep 13 2005
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Functions for working with group "locations"
+ *
+ *-------------------------------------------------------------------------
+ */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+
+/* Packages needed by this file... */
+#include "H5private.h" /* Generic Functions */
+#include "H5Aprivate.h" /* Attributes */
+#include "H5Dprivate.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Gpkg.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+
+/* Private typedefs */
+
+/* User data for looking up an object in a group */
+typedef struct {
+ H5G_loc_t *loc; /* Group location to set */
+} H5G_loc_ud1_t;
+
+/* Private macros */
+
+/* Local variables */
+
+/* PRIVATE PROTOTYPES */
+static herr_t H5G_loc_find_cb(H5G_loc_t *grp_loc, const char *name,
+ const H5O_link_t *lnk, H5G_loc_t *obj_loc, void *_udata);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc
+ *
+ * Purpose: Given an object ID return a location for the object.
+ *
+ * Return: Success: Group pointer.
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc(hid_t loc_id, H5G_loc_t *loc)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc, FAIL)
+
+ switch(H5I_get_type(loc_id)) {
+ case H5I_FILE:
+ {
+ H5F_t *f;
+
+ if(NULL == (f = H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file ID")
+ if(NULL == (loc->oloc = H5G_oloc(H5G_rootof(f))))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry for root group")
+ if(NULL == (loc->path = H5G_nameof(H5G_rootof(f))))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path for root group")
+
+ /* Patch up root group's symbol table entry to reflect this file */
+ /* (Since the root group info is only stored once for files which
+ * share an underlying low-level file)
+ */
+ /* (but only for non-mounted files) */
+ if(!H5F_is_mount(f))
+ loc->oloc->file = f;
+ } /* end case */
+ break;
+
+ case H5I_GENPROP_CLS:
+ case H5I_GENPROP_LST:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of property list")
+
+ case H5I_ERROR_CLASS:
+ case H5I_ERROR_MSG:
+ case H5I_ERROR_STACK:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of error class, message or stack")
+
+ case H5I_GROUP:
+ {
+ H5G_t *group;
+
+ if(NULL == (group = H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid group ID")
+ if(NULL == (loc->oloc = H5G_oloc(group)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of group")
+ if(NULL == (loc->path = H5G_nameof(group)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of group")
+ } /* end case */
+ break;
+
+ case H5I_DATATYPE:
+ {
+ H5T_t *dt;
+
+ if(NULL == (dt = H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid type ID")
+ if(NULL == (loc->oloc = H5T_oloc(dt)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of datatype")
+ if(NULL == (loc->path = H5T_nameof(dt)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of datatype")
+ } /* end case */
+ break;
+
+ case H5I_DATASPACE:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of dataspace")
+
+ case H5I_DATASET:
+ {
+ H5D_t *dset;
+
+ if(NULL == (dset = H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid data ID")
+ if(NULL == (loc->oloc = H5D_oloc(dset)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of dataset")
+ if(NULL == (loc->path = H5D_nameof(dset)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of dataset")
+ } /* end case */
+ break;
+
+ case H5I_ATTR:
+ {
+ H5A_t *attr;
+
+ if(NULL == (attr = H5I_object(loc_id)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid attribute ID")
+ if(NULL == (loc->oloc = H5A_oloc(attr)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of attribute")
+ if(NULL == (loc->path = H5A_nameof(attr)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get path of attribute")
+ } /* end case */
+ break;
+
+ case H5I_REFERENCE:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "unable to get symbol table entry of reference")
+
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid object ID")
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_copy
+ *
+ * Purpose: Copy over information for a location
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_copy(H5G_loc_t *dst, H5G_loc_t *src, H5G_copy_depth_t depth)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_copy, FAIL)
+
+ /* Check args. */
+ HDassert(dst);
+ HDassert(src);
+
+ /* Copy components of the location */
+ if(H5O_loc_copy(dst->oloc, src->oloc, (depth == H5G_COPY_SHALLOW ? H5O_COPY_SHALLOW : H5O_COPY_DEEP)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to copy entry")
+ if(H5G_name_copy(dst->path, src->path, depth) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to copy path")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_reset
+ *
+ * Purpose: Reset information for a location
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_reset(H5G_loc_t *loc)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_reset, FAIL)
+
+ /* Check args. */
+ HDassert(loc);
+
+ /* Reset components of the location */
+ if(H5O_loc_reset(loc->oloc) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to reset entry")
+ if(H5G_name_reset(loc->path) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to reset path")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_reset() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_free
+ *
+ * Purpose: Free information for a location
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_free(H5G_loc_t *loc)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_free, FAIL)
+
+ /* Check args. */
+ HDassert(loc);
+
+ /* Reset components of the location */
+#ifdef NOT_YET
+ if(H5G_ent_free(loc->ent) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to free entry")
+#endif /* NOT_YET */
+ if(H5G_name_free(loc->path) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to free path")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_find_cb
+ *
+ * Purpose: Callback for retrieving object location for an object in a group
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, October 17, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_loc_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk,
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+{
+ H5G_loc_ud1_t *udata = (H5G_loc_ud1_t *)_udata; /* User data passed in */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_loc_find_cb)
+
+ /* Check if the name in this group resolved to a valid link */
+ if(obj_loc == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
+
+ /* Take ownership of the object's group location */
+ /* (Group traversal callbacks are responsible for either taking ownership
+ * of the group location for the object, or freeing it. - QAK)
+ */
+ H5G_loc_copy(udata->loc, obj_loc, H5O_COPY_SHALLOW);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_find_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_find
+ *
+ * Purpose: Find a symbol from a location
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_find(H5G_loc_t *loc, const char *name, H5G_loc_t *obj_loc/*out*/,
+ hid_t dxpl_id)
+{
+ H5G_loc_ud1_t udata; /* User data for traversal callback */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_find, FAIL)
+
+ /* Check args. */
+ HDassert(loc);
+ HDassert(name && *name);
+ HDassert(obj_loc);
+
+ /* Set up user data for locating object */
+ udata.loc = obj_loc;
+
+ /* Traverse group hierarchy to locate object */
+ if(H5G_traverse(loc, name, H5G_TARGET_NORMAL, H5G_loc_find_cb, &udata, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_find() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_insert
+ *
+ * Purpose: Insert an object at a location
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_insert(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc,
+ hbool_t inc_link, hid_t dxpl_id)
+{
+ H5O_link_t lnk; /* Link for object to insert */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_insert, FAIL)
+
+ /* Check args. */
+ HDassert(grp_loc);
+ HDassert(name && *name);
+ HDassert(obj_loc);
+
+ /* "Translate" object location into link object */
+ lnk.type = H5G_LINK_HARD;
+#ifdef H5_HAVE_GETTIMEOFDAY
+ {
+ struct timeval now_tv;
+
+ HDgettimeofday(&now_tv, NULL);
+ lnk.ctime = now_tv.tv_sec;
+ }
+#else /* H5_HAVE_GETTIMEOFDAY */
+ lnk.ctime = HDtime(NULL);
+#endif /* H5_HAVE_GETTIMEOFDAY */
+ lnk.cset = H5T_CSET_ASCII; /* XXX: Allow user to set this */
+ /* Casting away const OK -QAK */
+ lnk.name = (char *)name;
+ lnk.u.hard.addr = obj_loc->oloc->addr;
+
+ /* Insert new group into current group's symbol table */
+ if(H5G_obj_insert(grp_loc->oloc, name, &lnk, inc_link, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert object")
+
+ /* Set the name of the object location */
+ if(H5G_name_set(grp_loc->path, obj_loc->path, name) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot set name")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_insert() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_exists
+ *
+ * Purpose: Check if a symbol exists in a location
+ *
+ * Return: Non-negative if object exists/Negative if object doesn't exist
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_exists(const H5G_loc_t *loc, const char *name, hid_t dxpl_id)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_exists, FAIL)
+
+ /* Check args. */
+ HDassert(loc);
+ HDassert(name && *name);
+
+ /* Get information for object in current group */
+ if(H5G_obj_lookup(loc->oloc, name, NULL, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_exists() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_loc_remove
+ *
+ * Purpose: Remove a link from a group
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_loc_remove(H5G_loc_t *grp_loc, const char *name, H5G_loc_t *obj_loc, hid_t dxpl_id)
+{
+ H5G_obj_t obj_type; /* Type of object removed */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_loc_remove, FAIL)
+
+ /* Check args. */
+ HDassert(grp_loc);
+ HDassert(name && *name);
+
+ /* Remove object from group */
+ if(H5G_obj_remove(grp_loc->oloc, name, &obj_type, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found")
+
+ /* Search the open IDs and replace names for unlinked object */
+ if(H5G_name_replace(obj_type, obj_loc, NULL, NULL, NULL, NULL, OP_UNLINK) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to replace name")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_loc_remove() */
+
diff --git a/src/H5Gname.c b/src/H5Gname.c
new file mode 100644
index 0000000..1d1a141
--- /dev/null
+++ b/src/H5Gname.c
@@ -0,0 +1,880 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Gname.c
+ * Sep 12 2005
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Functions for handling group hierarchy paths.
+ *
+ *-------------------------------------------------------------------------
+ */
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+
+/* Packages needed by this file... */
+#include "H5private.h" /* Generic Functions */
+#include "H5Dprivate.h" /* Datasets */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Gpkg.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+
+/* Private typedefs */
+
+/* Struct used by change name callback function */
+typedef struct H5G_names_t {
+ H5G_loc_t *loc;
+ H5RS_str_t *src_name;
+ H5G_loc_t *src_loc;
+ H5RS_str_t *dst_name;
+ H5G_loc_t *dst_loc;
+ H5G_names_op_t op;
+} H5G_names_t;
+
+/* Private macros */
+
+/* Local variables */
+
+/* Declare extern the PQ free list for the wrapped strings */
+H5FL_BLK_EXTERN(str_buf);
+
+/* PRIVATE PROTOTYPES */
+static htri_t H5G_common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r);
+static H5RS_str_t *H5G_build_fullpath(const char *prefix, const char *name);
+static H5RS_str_t *H5G_build_fullpath_refstr_refstr(const H5RS_str_t *prefix_r, const H5RS_str_t *name_r);
+static H5RS_str_t *H5G_build_fullpath_refstr_str(H5RS_str_t *path_r, const char *name);
+static int H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_common_path
+ *
+ * Purpose: Determine if one path is a valid prefix of another path
+ *
+ * Return: TRUE for valid prefix, FALSE for not a valid prefix, FAIL
+ * on error
+ *
+ * Programmer: Quincey Koziol, koziol@ncsa.uiuc.edu
+ *
+ * Date: September 24, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5G_common_path(const H5RS_str_t *fullpath_r, const H5RS_str_t *prefix_r)
+{
+ const char *fullpath; /* Pointer to actual fullpath string */
+ const char *prefix; /* Pointer to actual prefix string */
+ size_t nchars1,nchars2; /* Number of characters in components */
+ htri_t ret_value=FALSE; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_common_path)
+
+ /* Get component of each name */
+ fullpath=H5RS_get_str(fullpath_r);
+ assert(fullpath);
+ fullpath=H5G_component(fullpath,&nchars1);
+ assert(fullpath);
+ prefix=H5RS_get_str(prefix_r);
+ assert(prefix);
+ prefix=H5G_component(prefix,&nchars2);
+ assert(prefix);
+
+ /* Check if we have a real string for each component */
+ while(*fullpath && *prefix) {
+ /* Check that the components we found are the same length */
+ if(nchars1==nchars2) {
+ /* Check that the two components are equal */
+ if(HDstrncmp(fullpath,prefix,nchars1)==0) {
+ /* Advance the pointers in the names */
+ fullpath+=nchars1;
+ prefix+=nchars2;
+
+ /* Get next component of each name */
+ fullpath=H5G_component(fullpath,&nchars1);
+ assert(fullpath);
+ prefix=H5G_component(prefix,&nchars2);
+ assert(prefix);
+ } /* end if */
+ else
+ HGOTO_DONE(FALSE)
+ } /* end if */
+ else
+ HGOTO_DONE(FALSE)
+ } /* end while */
+
+ /* If we reached the end of the prefix path to check, it must be a valid prefix */
+ if(*prefix=='\0')
+ ret_value=TRUE;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_common_path() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_build_fullpath
+ *
+ * Purpose: Build a full path from a prefix & base pair of strings
+ *
+ * Return: Pointer to reference counted string on success, NULL on error
+ *
+ * Programmer: Quincey Koziol, koziol@ncsa.uiuc.edu
+ *
+ * Date: August 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5RS_str_t *
+H5G_build_fullpath(const char *prefix, const char *name)
+{
+ char *full_path; /* Full user path built */
+ size_t path_len; /* Length of the path */
+ unsigned need_sep; /* Flag to indicate if separator is needed */
+ H5RS_str_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_build_fullpath)
+
+ /* Sanity check */
+ HDassert(prefix);
+ HDassert(name);
+
+ /* Get the length of the prefix */
+ path_len = HDstrlen(prefix);
+
+ /* Determine if there is a trailing separator in the name */
+ if(prefix[path_len - 1] == '/')
+ need_sep = 0;
+ else
+ need_sep = 1;
+
+ /* Add in the length needed for the '/' separator and the relative path */
+ path_len += HDstrlen(name) + need_sep;
+
+ /* Allocate space for the path */
+ if(NULL == (full_path = H5FL_BLK_MALLOC(str_buf, path_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Build full path */
+ HDstrcpy(full_path, prefix);
+ if(need_sep)
+ HDstrcat(full_path, "/");
+ HDstrcat(full_path, name);
+
+ /* Create reference counted string for path */
+ if((ret_value = H5RS_own(full_path)) == NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_build_fullpath() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_build_fullpath_refstr_str
+ *
+ * Purpose: Append an object path to an existing ref-counted path
+ *
+ * Return: Success: Non-NULL, combined path
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol, koziol@ncsa.uiuc.edu
+ * Tuesday, October 11, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5RS_str_t *
+H5G_build_fullpath_refstr_str(H5RS_str_t *prefix_r, const char *name)
+{
+ const char *prefix; /* Pointer to raw string for path */
+ H5RS_str_t *ret_value;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_build_fullpath_refstr_str)
+
+ HDassert(prefix_r);
+ HDassert(name);
+
+ /* Get the raw string for the user path */
+ prefix = H5RS_get_str(prefix_r);
+ HDassert(prefix);
+
+ /* Create reference counted string for path */
+ ret_value = H5G_build_fullpath(prefix, name);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_build_fullpath_refstr_str() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_name_concat_refstr_refstr
+ *
+ * Purpose: Build a full path from a prefix & base pair of reference counted
+ * strings
+ *
+ * Return: Pointer to reference counted string on success, NULL on error
+ *
+ * Programmer: Quincey Koziol, koziol@ncsa.uiuc.edu
+ *
+ * Date: August 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5RS_str_t *
+H5G_build_fullpath_refstr_refstr(const H5RS_str_t *prefix_r, const H5RS_str_t *name_r)
+{
+ const char *prefix; /* Pointer to raw string of prefix */
+ const char *name; /* Pointer to raw string of name */
+ H5RS_str_t *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_build_fullpath_refstr_refstr)
+
+ /* Get the pointer to the prefix */
+ prefix = H5RS_get_str(prefix_r);
+
+ /* Get the pointer to the raw src user path */
+ name = H5RS_get_str(name_r);
+
+ /* Create reference counted string for path */
+ ret_value = H5G_build_fullpath(prefix, name);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_build_fullpath_refstr_refstr() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_name_init
+ *
+ * Purpose: Set the initial path for a group hierarchy name
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 12, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_name_init(H5G_name_t *name, const char *path)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5G_name_init)
+
+ /* Check arguments */
+ HDassert(name);
+
+ /* Set the initial paths for a name object */
+ name->user_path_r=H5RS_create(path);
+ HDassert(name->user_path_r);
+ name->canon_path_r=H5RS_create(path);
+ HDassert(name->canon_path_r);
+ name->user_path_hidden=0;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5G_name_init() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_name_set
+ *
+ * Purpose: Set the name of a symbol entry OBJ, located at LOC
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ * Thursday, August 22, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_name_set(H5G_name_t *loc, H5G_name_t *obj, const char *name)
+{
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5G_name_set, FAIL)
+
+ HDassert(loc);
+ HDassert(obj);
+ HDassert(name);
+
+ /* Free & reset the object's previous paths info (if they exist) */
+ H5G_name_free(obj);
+
+ /* Create the object's user path, if a user path exists in the location */
+ if(loc->user_path_r) {
+ /* Go build the new user path */
+ if((obj->user_path_r = H5G_build_fullpath_refstr_str(loc->user_path_r, name)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build user path name")
+ } /* end if */
+
+ /* Create the object's canonical path, if a canonical path exists in the location */
+ if(loc->canon_path_r) {
+ /* Go build the new canonical path */
+ if((obj->canon_path_r = H5G_build_fullpath_refstr_str(loc->canon_path_r, name)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build canonical path name")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_name_set() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_name_copy
+ *
+ * Purpose: Do a copy of group hier. names
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 12, 2005
+ *
+ * Notes: 'depth' parameter determines how much of the group entry
+ * structure we want to copy. The new depths are:
+ * H5G_COPY_SHALLOW - Copy all the fields from the source
+ * to the destination, including the user path and
+ * canonical path. (Destination "takes ownership" of
+ * user and canonical paths)
+ * H5G_COPY_CANON - Deep copy the canonical path and leave
+ * the user path alone
+ * H5G_COPY_DEEP - Copy all the fields from the source to
+ * the destination, deep copying the user and canonical
+ * paths.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5G_copy_depth_t depth)
+{
+ H5RS_str_t *tmp_user_path_r = NULL; /* Temporary string pointer for entry's user path */
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5G_name_copy)
+
+ /* Check arguments */
+ HDassert(src);
+ HDassert(dst);
+ HDassert(depth == H5G_COPY_SHALLOW || depth == H5G_COPY_DEEP || depth == H5G_COPY_CANON);
+
+ /* If only copying the canonical path, keep the old user path */
+ if(depth == H5G_COPY_CANON) {
+ tmp_user_path_r = dst->user_path_r;
+ if(dst->canon_path_r)
+ H5RS_decr(dst->canon_path_r);
+ } /* end if */
+
+ /* Copy the top level information */
+ HDmemcpy(dst, src, sizeof(H5G_name_t));
+
+ /* Deep copy the names */
+ if(depth == H5G_COPY_DEEP) {
+ dst->user_path_r = H5RS_dup(src->user_path_r);
+ dst->canon_path_r = H5RS_dup(src->canon_path_r);
+ } else if(depth == H5G_COPY_CANON) {
+ dst->user_path_r = tmp_user_path_r;
+ dst->canon_path_r = H5RS_dup(src->canon_path_r);
+ } else {
+ /* Discarding 'const' qualifier OK - QAK */
+ H5G_name_reset((H5G_name_t *)src);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5G_name_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_name_reset
+ *
+ * Purpose: Reset a group hierarchy name to an empty state
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 12, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_name_reset(H5G_name_t *name)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5G_name_reset)
+
+ /* Check arguments */
+ HDassert(name);
+
+ /* Clear the group hier. name to an empty state */
+ HDmemset(name, 0, sizeof(H5G_name_t));
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5G_name_reset() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_name_free
+ *
+ * Purpose: Free the 'ID to name' buffers.
+ *
+ * Return: Success
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: August 22, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_name_free(H5G_name_t *name)
+{
+ FUNC_ENTER_NOAPI_NOFUNC(H5G_name_free)
+
+ /* Check args */
+ HDassert(name);
+
+ if(name->user_path_r) {
+ H5RS_decr(name->user_path_r);
+ name->user_path_r=NULL;
+ } /* end if */
+ if(name->canon_path_r) {
+ H5RS_decr(name->canon_path_r);
+ name->canon_path_r=NULL;
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5G_name_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_name_replace_cb
+ *
+ * Purpose: H5I_search callback function to replace group entry names
+ *
+ * Return: Success: 0, Failure: -1
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: June 5, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+H5G_name_replace_cb(void *obj_ptr, hid_t obj_id, void *key)
+{
+ const H5G_names_t *names = (const H5G_names_t *)key; /* Get operation's information */
+ H5O_loc_t *oloc; /* Object location for object that the ID refers to */
+ H5G_name_t *obj_path; /* Pointer to group hier. path for obj */
+ H5F_t *top_ent_file; /* Top file in entry's mounted file chain */
+ H5F_t *top_loc_file; /* Top file in location's mounted file chain */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_name_replace_cb)
+
+ HDassert(obj_ptr);
+
+ /* Get the symbol table entry */
+ switch(H5I_get_type(obj_id)) {
+ case H5I_GROUP:
+ oloc = H5G_oloc((H5G_t *)obj_ptr);
+ obj_path = H5G_nameof((H5G_t *)obj_ptr);
+ break;
+
+ case H5I_DATASET:
+ oloc = H5D_oloc((H5D_t *)obj_ptr);
+ obj_path = H5D_nameof((H5D_t *)obj_ptr);
+ break;
+
+ case H5I_DATATYPE:
+ /* Avoid non-named datatypes */
+ if(!H5T_is_named((H5T_t *)obj_ptr))
+ HGOTO_DONE(SUCCEED) /* Do not exit search over IDs */
+
+ oloc = H5T_oloc((H5T_t *)obj_ptr);
+ obj_path = H5T_nameof((H5T_t *)obj_ptr);
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "unknown data object")
+ } /* end switch */
+ HDassert(oloc);
+ HDassert(obj_path);
+
+ switch(names->op) {
+ /*-------------------------------------------------------------------------
+ * OP_MOUNT
+ *-------------------------------------------------------------------------
+ */
+ case OP_MOUNT:
+ if(obj_path->user_path_r) {
+ if(oloc->file->mtab.parent && H5RS_cmp(obj_path->user_path_r, obj_path->canon_path_r)) {
+ /* Find the "top" file in the chain of mounted files */
+ top_ent_file = oloc->file->mtab.parent;
+ while(top_ent_file->mtab.parent != NULL)
+ top_ent_file = top_ent_file->mtab.parent;
+ } /* end if */
+ else
+ top_ent_file = oloc->file;
+
+ /* Check for entry being in correct file (or mounted file) */
+ if(top_ent_file->shared == names->loc->oloc->file->shared) {
+ /* Check if the source is along the entry's path */
+ /* (But not actually the entry itself) */
+ if(H5G_common_path(obj_path->user_path_r, names->src_name) &&
+ H5RS_cmp(obj_path->user_path_r, names->src_name) != 0) {
+ /* Hide the user path */
+ (obj_path->user_path_hidden)++;
+ } /* end if */
+ } /* end if */
+ } /* end if */
+ break;
+
+ /*-------------------------------------------------------------------------
+ * OP_UNMOUNT
+ *-------------------------------------------------------------------------
+ */
+ case OP_UNMOUNT:
+ if(obj_path->user_path_r) {
+ if(oloc->file->mtab.parent) {
+ /* Find the "top" file in the chain of mounted files for the entry */
+ top_ent_file = oloc->file->mtab.parent;
+ while(top_ent_file->mtab.parent != NULL)
+ top_ent_file=top_ent_file->mtab.parent;
+ } /* end if */
+ else
+ top_ent_file = oloc->file;
+
+ if(names->loc->oloc->file->mtab.parent) {
+ /* Find the "top" file in the chain of mounted files for the location */
+ top_loc_file = names->loc->oloc->file->mtab.parent;
+ while(top_loc_file->mtab.parent != NULL)
+ top_loc_file = top_loc_file->mtab.parent;
+ } /* end if */
+ else
+ top_loc_file = names->loc->oloc->file;
+
+ /* If the ID's entry is not in the file we operated on, skip it */
+ if(top_ent_file->shared == top_loc_file->shared) {
+ if(obj_path->user_path_hidden) {
+ if(H5G_common_path(obj_path->user_path_r, names->src_name)) {
+ /* Un-hide the user path */
+ (obj_path->user_path_hidden)--;
+ } /* end if */
+ } /* end if */
+ else {
+ if(H5G_common_path(obj_path->user_path_r, names->src_name)) {
+ /* Free user path */
+ H5RS_decr(obj_path->user_path_r);
+ obj_path->user_path_r = NULL;
+ } /* end if */
+ } /* end else */
+ } /* end if */
+ } /* end if */
+ break;
+
+ /*-------------------------------------------------------------------------
+ * OP_UNLINK
+ *-------------------------------------------------------------------------
+ */
+ case OP_UNLINK:
+ /* If the ID's entry is not in the file we operated on, skip it */
+ if(oloc->file->shared == names->loc->oloc->file->shared &&
+ names->loc->path->canon_path_r && obj_path->canon_path_r && obj_path->user_path_r) {
+ /* Check if we are referring to the same object */
+ if(H5F_addr_eq(oloc->addr, names->loc->oloc->addr)) {
+ /* Check if the object was opened with the same canonical path as the one being moved */
+ if(H5RS_cmp(obj_path->canon_path_r, names->loc->path->canon_path_r) == 0) {
+ /* Free user path */
+ H5RS_decr(obj_path->user_path_r);
+ obj_path->user_path_r=NULL;
+ } /* end if */
+ } /* end if */
+ else {
+ /* Check if the location being unlinked is in the canonical path for the current object */
+ if(H5G_common_path(obj_path->canon_path_r, names->loc->path->canon_path_r)) {
+ /* Free user path */
+ H5RS_decr(obj_path->user_path_r);
+ obj_path->user_path_r=NULL;
+ } /* end if */
+ } /* end else */
+ } /* end if */
+ break;
+
+ /*-------------------------------------------------------------------------
+ * OP_MOVE
+ *-------------------------------------------------------------------------
+ */
+ case OP_MOVE: /* H5Gmove case, check for relative names case */
+ /* If the ID's entry is not in the file we operated on, skip it */
+ if(oloc->file->shared == names->loc->oloc->file->shared) {
+ if(obj_path->user_path_r && names->loc->path->user_path_r &&
+ names->src_loc->path->user_path_r && names->dst_loc->path->user_path_r) {
+ H5RS_str_t *src_path_r; /* Full user path of source name */
+ H5RS_str_t *dst_path_r; /* Full user path of destination name */
+ H5RS_str_t *canon_src_path_r; /* Copy of canonical part of source path */
+ H5RS_str_t *canon_dst_path_r; /* Copy of canonical part of destination path */
+
+ /* Sanity check */
+ HDassert(names->src_name);
+ HDassert(names->dst_name);
+
+ /* Make certain that the source and destination names are full (not relative) paths */
+ if(*(H5RS_get_str(names->src_name)) != '/') {
+ /* Create reference counted string for full src path */
+ if((src_path_r = H5G_build_fullpath_refstr_refstr(names->src_loc->path->user_path_r, names->src_name)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build source path name")
+ } /* end if */
+ else
+ src_path_r = H5RS_dup(names->src_name);
+ if(*(H5RS_get_str(names->dst_name)) != '/') {
+ /* Create reference counted string for full dst path */
+ if((dst_path_r = H5G_build_fullpath_refstr_refstr(names->dst_loc->path->user_path_r, names->dst_name)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_PATH, FAIL, "can't build destination path name")
+ } /* end if */
+ else
+ dst_path_r = H5RS_dup(names->dst_name);
+
+ /* Get the canonical parts of the source and destination names */
+
+ /* Check if the object being moved was accessed through a mounted file */
+ if(H5RS_cmp(names->loc->path->user_path_r, names->loc->path->canon_path_r) != 0) {
+ size_t non_canon_name_len; /* Length of non-canonical part of name */
+
+ /* Get current string lengths */
+ non_canon_name_len = H5RS_len(names->loc->path->user_path_r) - H5RS_len(names->loc->path->canon_path_r);
+
+ canon_src_path_r = H5RS_create(H5RS_get_str(src_path_r) + non_canon_name_len);
+ canon_dst_path_r = H5RS_create(H5RS_get_str(dst_path_r) + non_canon_name_len);
+ } /* end if */
+ else {
+ canon_src_path_r = H5RS_dup(src_path_r);
+ canon_dst_path_r = H5RS_dup(dst_path_r);
+ } /* end else */
+
+ /* Check if the link being changed in the file is along the canonical path for this object */
+ if(H5G_common_path(obj_path->canon_path_r, canon_src_path_r)) {
+ size_t user_dst_len; /* Length of destination user path */
+ size_t canon_dst_len; /* Length of destination canonical path */
+ const char *old_user_path; /* Pointer to previous user path */
+ char *new_user_path; /* Pointer to new user path */
+ char *new_canon_path; /* Pointer to new canonical path */
+ const char *tail_path; /* Pointer to "tail" of path */
+ size_t tail_len; /* Pointer to "tail" of path */
+ char *src_canon_prefix; /* Pointer to source canonical path prefix of component which is moving */
+ size_t src_canon_prefix_len;/* Length of the source canonical path prefix */
+ char *dst_canon_prefix; /* Pointer to destination canonical path prefix of component which is moving */
+ size_t dst_canon_prefix_len;/* Length of the destination canonical path prefix */
+ char *user_prefix; /* Pointer to user path prefix of component which is moving */
+ size_t user_prefix_len; /* Length of the user path prefix */
+ char *src_comp; /* The source name of the component which is actually changing */
+ char *dst_comp; /* The destination name of the component which is actually changing */
+ const char *canon_src_path; /* pointer to canonical part of source path */
+ const char *canon_dst_path; /* pointer to canonical part of destination path */
+
+ /* Get the pointers to the raw strings */
+ canon_src_path = H5RS_get_str(canon_src_path_r);
+ canon_dst_path = H5RS_get_str(canon_dst_path_r);
+
+ /* Get the source & destination components */
+ src_comp = HDstrrchr(canon_src_path, '/');
+ HDassert(src_comp);
+ dst_comp = HDstrrchr(canon_dst_path, '/');
+ HDassert(dst_comp);
+
+ /* Find the canonical prefixes for the entry */
+ src_canon_prefix_len = HDstrlen(canon_src_path) - HDstrlen(src_comp);
+ if(NULL == (src_canon_prefix = H5MM_malloc(src_canon_prefix_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ HDstrncpy(src_canon_prefix, canon_src_path, src_canon_prefix_len);
+ src_canon_prefix[src_canon_prefix_len] = '\0';
+
+ dst_canon_prefix_len = HDstrlen(canon_dst_path) - HDstrlen(dst_comp);
+ if(NULL == (dst_canon_prefix = H5MM_malloc(dst_canon_prefix_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ HDstrncpy(dst_canon_prefix, canon_dst_path, dst_canon_prefix_len);
+ dst_canon_prefix[dst_canon_prefix_len] = '\0';
+
+ /* Hold this for later use */
+ old_user_path = H5RS_get_str(obj_path->user_path_r);
+
+ /* Find the user prefix for the entry */
+ user_prefix_len = HDstrlen(old_user_path) - H5RS_len(obj_path->canon_path_r);
+ if(NULL == (user_prefix = H5MM_malloc(user_prefix_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ HDstrncpy(user_prefix, old_user_path, user_prefix_len);
+ user_prefix[user_prefix_len] = '\0';
+
+ /* Set the tail path info */
+ tail_path = old_user_path+user_prefix_len + src_canon_prefix_len + HDstrlen(src_comp);
+ tail_len = HDstrlen(tail_path);
+
+ /* Get the length of the destination paths */
+ user_dst_len = user_prefix_len + dst_canon_prefix_len + HDstrlen(dst_comp) + tail_len;
+ canon_dst_len = dst_canon_prefix_len + HDstrlen(dst_comp) + tail_len;
+
+ /* Allocate space for the new user path */
+ if(NULL == (new_user_path = H5FL_BLK_MALLOC(str_buf, user_dst_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Allocate space for the new canonical path */
+ if(NULL == (new_canon_path = H5FL_BLK_MALLOC(str_buf, canon_dst_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Create the new names */
+ HDstrcpy(new_user_path, user_prefix);
+ HDstrcat(new_user_path, dst_canon_prefix);
+ HDstrcat(new_user_path, dst_comp);
+ HDstrcat(new_user_path, tail_path);
+ HDstrcpy(new_canon_path, dst_canon_prefix);
+ HDstrcat(new_canon_path, dst_comp);
+ HDstrcat(new_canon_path, tail_path);
+
+ /* Release the old user & canonical paths */
+ H5RS_decr(obj_path->user_path_r);
+ H5RS_decr(obj_path->canon_path_r);
+
+ /* Take ownership of the new user & canonical paths */
+ obj_path->user_path_r = H5RS_own(new_user_path);
+ obj_path->canon_path_r = H5RS_own(new_canon_path);
+
+ /* Free the extra paths allocated */
+ H5MM_xfree(src_canon_prefix);
+ H5MM_xfree(dst_canon_prefix);
+ H5MM_xfree(user_prefix);
+ } /* end if */
+
+
+ /* Free the extra paths allocated */
+ H5RS_decr(src_path_r);
+ H5RS_decr(dst_path_r);
+ H5RS_decr(canon_src_path_r);
+ H5RS_decr(canon_dst_path_r);
+ } /* end if */
+ else {
+ /* Release the old user path */
+ if(obj_path->user_path_r) {
+ H5RS_decr(obj_path->user_path_r);
+ obj_path->user_path_r = NULL;
+ } /* end if */
+ } /* end else */
+ } /* end if */
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid call")
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5G_name_replace_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_name_replace
+ *
+ * Purpose: Search the list of open IDs and replace names according to a
+ * particular operation. The operation occured on the LOC
+ * entry, which had SRC_NAME previously. The new name (if there
+ * is one) is DST_NAME. Additional entry location information
+ * (currently only needed for the 'move' operation) is passed
+ * in SRC_LOC and DST_LOC.
+ *
+ * Return: Success: 0, Failure: -1
+ *
+ * Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
+ *
+ * Date: June 11, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_name_replace(H5G_obj_t type, H5G_loc_t *loc,
+ H5RS_str_t *src_name, H5G_loc_t *src_loc,
+ H5RS_str_t *dst_name, H5G_loc_t *dst_loc, H5G_names_op_t op)
+{
+ H5G_names_t names; /* Structure to hold operation information for callback */
+ unsigned search_group = 0; /* Flag to indicate that groups are to be searched */
+ unsigned search_dataset = 0; /* Flag to indicate that datasets are to be searched */
+ unsigned search_datatype = 0; /* Flag to indicate that datatypes are to be searched */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5G_name_replace, FAIL)
+
+ /* Set up common information for callback */
+ names.src_name = src_name;
+ names.dst_name = dst_name;
+ names.loc = loc;
+ names.src_loc = src_loc;
+ names.dst_loc = dst_loc;
+ names.op = op;
+
+ /* Determine which types of IDs need to be operated on */
+ switch(type) {
+ /* Object is a group */
+ case H5G_GROUP:
+ /* Search and replace names through group IDs */
+ search_group = 1;
+ break;
+
+ /* Object is a dataset */
+ case H5G_DATASET:
+ /* Search and replace names through dataset IDs */
+ search_dataset = 1;
+ break;
+
+ /* Object is a named datatype */
+ case H5G_TYPE:
+ /* Search and replace names through datatype IDs */
+ search_datatype = 1;
+ break;
+
+ case H5G_UNKNOWN: /* We pass H5G_UNKNOWN as object type when we need to search all IDs */
+ case H5G_LINK: /* Symbolic links might resolve to any object, so we need to search all IDs */
+ /* Check if we will need to search groups */
+ if(H5I_nmembers(H5I_GROUP) > 0)
+ search_group = 1;
+
+ /* Check if we will need to search datasets */
+ if(H5I_nmembers(H5I_DATASET) > 0)
+ search_dataset = 1;
+
+ /* Check if we will need to search datatypes */
+ if(H5I_nmembers(H5I_DATATYPE) > 0)
+ search_datatype = 1;
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not valid object type");
+ } /* end switch */
+
+ /* Search through group IDs */
+ if(search_group)
+ H5I_search(H5I_GROUP, H5G_name_replace_cb, &names);
+
+ /* Search through dataset IDs */
+ if(search_dataset)
+ H5I_search(H5I_DATASET, H5G_name_replace_cb, &names);
+
+ /* Search through datatype IDs */
+ if(search_datatype)
+ H5I_search(H5I_DATATYPE, H5G_name_replace_cb, &names);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_name_replace() */
+
diff --git a/src/H5Gnode.c b/src/H5Gnode.c
index 5e053fd..ca605b8 100644
--- a/src/H5Gnode.c
+++ b/src/H5Gnode.c
@@ -890,48 +890,39 @@ done:
* matzke@llnl.gov
* Jun 23 1997
*
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * John Mainzer, 6/17/05
- * Modified the function to use the new dirtied parameter of
- * of H5AC_unprotect() instead of modifying the is_dirty
- * field of the cache info.
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_lt_key,
void *_udata)
{
- H5G_bt_ud1_t *udata = (H5G_bt_ud1_t *) _udata;
+ H5G_bt_ud3_t *udata = (H5G_bt_ud3_t *) _udata;
H5G_node_t *sn = NULL;
const H5HL_t *heap = NULL;
unsigned lt = 0, idx = 0, rt;
int cmp = 1;
const char *s;
const char *base; /* Base of heap */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5G_node_found);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_node_found)
/*
* Check arguments.
*/
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(udata);
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(udata);
/*
* Load the symbol table node for exclusive access.
*/
- if (NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to protect symbol table node");
+ if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to protect symbol table node")
/* Get base address of heap */
- if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name");
+ if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to protect symbol name")
base = H5HL_offset_into(f, heap, 0);
@@ -939,46 +930,34 @@ H5G_node_found(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED *_lt_key
* Binary search.
*/
rt = sn->nsyms;
- while (lt < rt && cmp) {
+ while(lt < rt && cmp) {
idx = (lt + rt) / 2;
- s=base+sn->entry[idx].name_off;
+ s = base + sn->entry[idx].name_off;
cmp = HDstrcmp(udata->common.name, s);
if (cmp < 0)
rt = idx;
else
lt = idx + 1;
- }
+ } /* end while */
- if (H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name");
- heap=NULL; base=NULL;
-
- if (cmp)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found");
+ if(H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to unprotect symbol name")
+ heap = NULL; base = NULL;
- /*
- * The caller is querying the symbol entry, copy it into the UDATA
- * entry field.
- *
- * (do a NULL copy, since the entry's name will be constructed later)
- */
- if (H5G_ent_copy(udata->ent, &sn->entry[idx], H5G_COPY_NULL)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to copy entry");
+ if(cmp)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
- /* Leave object in same file as lookup occurs in */
- /* If a file is opened through different H5Fopen() calls, the symbol
- * table entry from the B-tree lookup ("&sn->entry[idx]" above) will be
- * in the "first" file, but the lookup might occur in the second file. - QAK
- */
- udata->ent->file = f;
+ /* Call user's callback operator */
+ if((udata->op)(&sn->entry[idx], udata->op_data) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "iterator callback failed")
done:
- if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to release symbol table node");
+ if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, FAIL, "unable to release symbol table node")
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_node_found() */
/*-------------------------------------------------------------------------
@@ -1013,59 +992,50 @@ done:
* matzke@llnl.gov
* Jun 24 1997
*
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * John Mainzer, 6/8/05
- * Modified the function to use the new dirtied parameter of
- * of H5AC_unprotect() instead of modifying the is_dirty
- * field of the cache info.
- *
*-------------------------------------------------------------------------
*/
static H5B_ins_t
-H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key,
- hbool_t UNUSED *lt_key_changed, void *_md_key,
- void *_udata, void *_rt_key, hbool_t *rt_key_changed,
- haddr_t *new_node_p)
+H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr,
+ void UNUSED *_lt_key, hbool_t UNUSED *lt_key_changed,
+ void *_md_key, void *_udata,
+ void *_rt_key, hbool_t *rt_key_changed,
+ haddr_t *new_node_p)
{
H5G_node_key_t *md_key = (H5G_node_key_t *) _md_key;
H5G_node_key_t *rt_key = (H5G_node_key_t *) _rt_key;
H5G_bt_ud1_t *udata = (H5G_bt_ud1_t *) _udata;
-
H5G_node_t *sn = NULL, *snrt = NULL;
unsigned sn_flags = H5AC__NO_FLAGS_SET, snrt_flags = H5AC__NO_FLAGS_SET;
const H5HL_t *heap = NULL;
- size_t offset; /*offset of name in heap */
const char *s;
const char *base; /* Base of heap */
unsigned lt = 0, rt; /* Binary search cntrs */
int cmp = 1, idx = -1;
H5G_node_t *insert_into = NULL; /*node that gets new entry*/
+ H5G_entry_t ent; /* Entry to insert in node */
H5B_ins_t ret_value = H5B_INS_ERROR;
- FUNC_ENTER_NOAPI_NOINIT(H5G_node_insert);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_node_insert)
/*
* Check arguments.
*/
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(md_key);
- assert(rt_key);
- assert(udata);
- assert(new_node_p);
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(md_key);
+ HDassert(rt_key);
+ HDassert(udata);
+ HDassert(new_node_p);
/*
* Load the symbol node.
*/
- if (NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node");
+ if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node")
/* Get base address of heap */
- if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name");
+ if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name")
base = H5HL_offset_into(f, heap, 0);
@@ -1073,40 +1043,37 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key,
* Where does the new symbol get inserted? We use a binary search.
*/
rt = sn->nsyms;
- while (lt < rt) {
+ while(lt < rt) {
idx = (lt + rt) / 2;
- s=base+sn->entry[idx].name_off;
+ s = base + sn->entry[idx].name_off;
- if (0 == (cmp = HDstrcmp(udata->common.name, s))) /*already present */ {
+ if(0 == (cmp = HDstrcmp(udata->common.name, s))) /*already present */ {
HCOMMON_ERROR(H5E_SYM, H5E_CANTINSERT, "symbol is already present in symbol table");
- if (H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name");
- heap=NULL; base=NULL;
+ if(H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name")
+ heap = NULL; base = NULL;
- HGOTO_DONE(H5B_INS_ERROR);
- }
+ HGOTO_DONE(H5B_INS_ERROR)
+ } /* end if */
if (cmp < 0)
rt = idx;
else
lt = idx + 1;
- }
+ } /* end while */
idx += cmp > 0 ? 1 : 0;
- if (H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name");
- heap=NULL; base=NULL;
+ if(H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name")
+ heap = NULL; base = NULL;
- /*
- * Add the new name to the heap.
- */
- offset = H5HL_insert(f, dxpl_id, udata->common.heap_addr, HDstrlen(udata->common.name)+1,
- udata->common.name);
- udata->ent->name_off = offset;
- if (0==offset || (size_t)(-1)==offset)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, H5B_INS_ERROR, "unable to insert symbol name into heap");
- if (sn->nsyms >= 2*H5F_SYM_LEAF_K(f)) {
+ /* Convert link information & name to symbol table entry */
+ if(H5G_ent_convert(f, udata->common.heap_addr, udata->common.name, udata->lnk, &ent, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, H5B_INS_ERROR, "unable to convert link")
+
+ /* Determine where to place entry in node */
+ if(sn->nsyms >= 2 * H5F_SYM_LEAF_K(f)) {
/*
* The node is full. Split it into a left and right
* node and return the address of the new right node (the
@@ -1115,12 +1082,11 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key,
ret_value = H5B_INS_RIGHT;
/* The right node */
- if (H5G_node_create(f, dxpl_id, H5B_INS_FIRST, NULL, NULL, NULL,
- new_node_p/*out*/)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, "unable to split symbol table node");
+ if(H5G_node_create(f, dxpl_id, H5B_INS_FIRST, NULL, NULL, NULL, new_node_p/*out*/) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, "unable to split symbol table node")
- if (NULL == (snrt = H5AC_protect(f, dxpl_id, H5AC_SNODE, *new_node_p, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to split symbol table node");
+ if(NULL == (snrt = H5AC_protect(f, dxpl_id, H5AC_SNODE, *new_node_p, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to split symbol table node")
HDmemcpy(snrt->entry, sn->entry + H5F_SYM_LEAF_K(f),
H5F_SYM_LEAF_K(f) * sizeof(H5G_entry_t));
@@ -1137,37 +1103,35 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key,
md_key->offset = sn->entry[sn->nsyms - 1].name_off;
/* Where to insert the new entry? */
- if (idx <= (int)H5F_SYM_LEAF_K(f)) {
+ if(idx <= (int)H5F_SYM_LEAF_K(f)) {
insert_into = sn;
- if (idx == (int)H5F_SYM_LEAF_K(f))
- md_key->offset = offset;
+ if(idx == (int)H5F_SYM_LEAF_K(f))
+ md_key->offset = ent.name_off;
} else {
idx -= H5F_SYM_LEAF_K(f);
insert_into = snrt;
- if (idx == (int)H5F_SYM_LEAF_K (f)) {
- rt_key->offset = offset;
+ if(idx == (int)H5F_SYM_LEAF_K (f)) {
+ rt_key->offset = ent.name_off;
*rt_key_changed = TRUE;
- }
- }
+ } /* end if */
+ } /* end else */
} else {
/* Where to insert the new entry? */
ret_value = H5B_INS_NOOP;
sn_flags |= H5AC__DIRTIED_FLAG;
insert_into = sn;
- if (idx == (int)sn->nsyms) {
- rt_key->offset = offset;
+ if(idx == (int)sn->nsyms) {
+ rt_key->offset = ent.name_off;
*rt_key_changed = TRUE;
- }
- }
+ } /* end if */
+ } /* end else */
/* Move entries down to make room for new entry */
- HDmemmove(insert_into->entry + idx + 1,
- insert_into->entry + idx,
+ HDmemmove(insert_into->entry + idx + 1, insert_into->entry + idx,
(insert_into->nsyms - idx) * sizeof(H5G_entry_t));
/* Copy new entry into table */
- /* (use H5G_COPY_NULL because we don't track the object names in the table) */
- H5G_ent_copy(&(insert_into->entry[idx]), udata->ent, H5G_COPY_NULL);
+ H5G_ent_copy(&(insert_into->entry[idx]), &ent, H5G_COPY_SHALLOW);
/* Flag entry as dirty */
insert_into->entry[idx].dirty = TRUE;
@@ -1176,13 +1140,13 @@ H5G_node_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, void UNUSED *_lt_key,
insert_into->nsyms += 1;
done:
- if (snrt && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, *new_node_p, snrt, snrt_flags) < 0)
- HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node");
- if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, sn_flags) < 0)
- HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node");
+ if(snrt && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, *new_node_p, snrt, snrt_flags) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node")
+ if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, sn_flags) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node")
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_node_insert() */
/*-------------------------------------------------------------------------
@@ -1240,129 +1204,141 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
H5G_node_t *sn = NULL;
unsigned sn_flags = H5AC__NO_FLAGS_SET;
const H5HL_t *heap = NULL;
- unsigned lt=0, rt, idx=0;
- int cmp=1;
+ unsigned lt = 0, rt, idx = 0;
+ int cmp = 1;
const char *s = NULL;
const char *base; /* Base of heap */
H5B_ins_t ret_value = H5B_INS_ERROR;
- FUNC_ENTER_NOAPI_NOINIT(H5G_node_remove);
+ FUNC_ENTER_NOAPI_NOINIT(H5G_node_remove)
/* Check arguments */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(lt_key);
- assert(rt_key);
- assert(udata);
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(lt_key);
+ HDassert(rt_key);
+ HDassert(udata);
/* Load the symbol table */
- if (NULL==(sn=H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node");
+ if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_INS_ERROR, "unable to protect symbol table node")
/* "Normal" removal of a single entry from the symbol table node */
- if(udata->common.name!=NULL) {
- size_t len=0;
+ if(udata->common.name != NULL) {
+ size_t len = 0;
hbool_t found; /* Indicate that the string was found */
/* Get base address of heap */
- if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name");
+ if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name")
base = H5HL_offset_into(f, heap, 0);
/* Find the name with a binary search */
rt = sn->nsyms;
- while (lt<rt && cmp) {
- idx = (lt+rt)/2;
- s=base+sn->entry[idx].name_off;
+ while(lt < rt && cmp) {
+ idx = (lt + rt) / 2;
+ s = base + sn->entry[idx].name_off;
cmp = HDstrcmp(udata->common.name, s);
- if (cmp<0) {
+ if(cmp < 0)
rt = idx;
- } else {
- lt = idx+1;
- }
- }
+ else
+ lt = idx + 1;
+ } /* end while */
- if (H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name");
- heap=NULL; base=NULL;
+ if(H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name")
+ heap = NULL; base = NULL;
- if (cmp)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "not found");
+ if(cmp)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "not found")
+
+ if(H5G_CACHED_SLINK == sn->entry[idx].type) {
+ /* Set the type of the link removed */
+ *(udata->obj_type) = H5G_LINK;
- if (H5G_CACHED_SLINK==sn->entry[idx].type) {
/* Remove the symbolic link value */
- if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name");
+ if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name")
s = H5HL_offset_into(f, heap, sn->entry[idx].cache.slink.lval_offset);
- if (s) {
- len=HDstrlen(s)+1;
- found=1;
+ if(s) {
+ len = HDstrlen(s) + 1;
+ found = 1;
} /* end if */
else
- found=0;
+ found = 0;
- if (H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name");
- heap=NULL; s=NULL;
+ if(H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name")
+ heap = NULL; s = NULL;
- if (found)
+ if(found)
H5HL_remove(f, dxpl_id, udata->common.heap_addr, sn->entry[idx].cache.slink.lval_offset, len);
H5E_clear_stack(NULL); /* no big deal */
} else {
+ H5O_loc_t tmp_oloc; /* Temporary object location */
+
+ /* Build temporary object location */
+ tmp_oloc.file = f;
+ HDassert(H5F_addr_defined(sn->entry[idx].header));
+ tmp_oloc.addr = sn->entry[idx].header;
+
+ /* Get the type of the object */
+ if((*(udata->obj_type) = H5O_obj_type(&tmp_oloc, dxpl_id)) == H5G_UNKNOWN)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGET, H5B_INS_ERROR, "unable to determine object type")
+
/* Decrement the reference count, if requested */
if(udata->adj_link) {
- HDassert(H5F_addr_defined(sn->entry[idx].header));
- if (H5O_link(sn->entry+idx, -1, dxpl_id)<0)
+ if(H5O_link(&tmp_oloc, -1, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_INS_ERROR, "unable to decrement object link count")
} /* end if */
- }
+ } /* end else */
/* Remove the name from the local heap */
- if (NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name");
+ if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->common.heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_INS_ERROR, "unable to protect symbol name")
s = H5HL_offset_into(f, heap, sn->entry[idx].name_off);
- if (s) {
- len=HDstrlen(s)+1;
- found=1;
+ if(s) {
+ len = HDstrlen(s) + 1;
+ found = 1;
} /* end if */
else
- found=0;
+ found = 0;
- if (H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name");
- heap=NULL; s=NULL;
+ if(H5HL_unprotect(f, dxpl_id, heap, udata->common.heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to unprotect symbol name")
+ heap = NULL; s = NULL;
- if (found)
+ if(found)
H5HL_remove(f, dxpl_id, udata->common.heap_addr, sn->entry[idx].name_off, len);
H5E_clear_stack(NULL); /* no big deal */
/* Remove the entry from the symbol table node */
- if(1==sn->nsyms) {
+ if(1 == sn->nsyms) {
/*
* We are about to remove the only symbol in this node. Copy the left
* key to the right key and mark the right key as dirty. Free this
* node and indicate that the pointer to this node in the B-tree
* should be removed also.
*/
- assert(0==idx);
+ HDassert(0 == idx);
*rt_key = *lt_key;
*rt_key_changed = TRUE;
sn->nsyms = 0;
- if (H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)H5G_node_size(f))<0
- || H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG)<0) {
+ if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)H5G_node_size(f)) < 0
+ || H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG) < 0) {
sn = NULL;
- HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to free symbol table node");
- }
+ HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to free symbol table node")
+ } /* end if */
sn = NULL;
ret_value = H5B_INS_REMOVE;
- } else if (0==idx) {
+ } else if(0 == idx) {
/*
* We are about to remove the left-most entry from the symbol table
* node but there are other entries to the right. No key values
@@ -1370,11 +1346,11 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
*/
sn->nsyms -= 1;
sn_flags |= H5AC__DIRTIED_FLAG;
- HDmemmove(sn->entry+idx, sn->entry+idx+1,
- (sn->nsyms-idx)*sizeof(H5G_entry_t));
+ HDmemmove(sn->entry + idx, sn->entry + idx + 1,
+ (sn->nsyms-idx) * sizeof(H5G_entry_t));
ret_value = H5B_INS_NOOP;
- } else if (idx+1==sn->nsyms) {
+ } else if (idx + 1 == sn->nsyms) {
/*
* We are about to remove the right-most entry from the symbol table
* node but there are other entries to the left. The right key
@@ -1382,7 +1358,7 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
*/
sn->nsyms -= 1;
sn_flags |= H5AC__DIRTIED_FLAG;
- rt_key->offset = sn->entry[sn->nsyms-1].name_off;
+ rt_key->offset = sn->entry[sn->nsyms - 1].name_off;
*rt_key_changed = TRUE;
ret_value = H5B_INS_NOOP;
@@ -1393,20 +1369,27 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
*/
sn->nsyms -= 1;
sn_flags |= H5AC__DIRTIED_FLAG;
- HDmemmove(sn->entry+idx, sn->entry+idx+1,
- (sn->nsyms-idx)*sizeof(H5G_entry_t));
+ HDmemmove(sn->entry + idx, sn->entry + idx + 1,
+ (sn->nsyms - idx) * sizeof(H5G_entry_t));
ret_value = H5B_INS_NOOP;
- }
+ } /* end else */
} /* end if */
/* Remove all entries from node, during B-tree deletion */
else {
+ H5O_loc_t tmp_oloc; /* Temporary object location */
+
+ /* Build temporary object location */
+ tmp_oloc.file = f;
+
/* Reduce the link count for all entries in this node */
- for(idx=0; idx<sn->nsyms; idx++) {
- if (H5G_CACHED_SLINK!=sn->entry[idx].type) {
+ for(idx = 0; idx < sn->nsyms; idx++) {
+ if(H5G_CACHED_SLINK != sn->entry[idx].type) {
/* Decrement the reference count, if requested */
if(udata->adj_link) {
HDassert(H5F_addr_defined(sn->entry[idx].header));
- if (H5O_link(sn->entry+idx, -1, dxpl_id)<0)
+ tmp_oloc.addr = sn->entry[idx].header;
+
+ if(H5O_link(&tmp_oloc, -1, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, H5B_INS_ERROR, "unable to decrement object link count")
} /* end if */
} /* end if */
@@ -1421,21 +1404,21 @@ H5G_node_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_lt_key/*in,out*/,
*rt_key = *lt_key;
*rt_key_changed = TRUE;
sn->nsyms = 0;
- if (H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)H5G_node_size(f))<0
- || H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG)<0) {
+ if(H5MF_xfree(f, H5FD_MEM_BTREE, dxpl_id, addr, (hsize_t)H5G_node_size(f)) < 0
+ || H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG) < 0) {
sn = NULL;
- HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to free symbol table node");
- }
+ HGOTO_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to free symbol table node")
+ } /* end if */
sn = NULL;
ret_value = H5B_INS_REMOVE;
} /* end else */
done:
- if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, sn_flags)<0)
- HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node");
+ if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, sn_flags) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_INS_ERROR, "unable to release symbol table node")
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_node_remove() */
/*-------------------------------------------------------------------------
@@ -1538,7 +1521,7 @@ H5G_node_iterate (H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t a
/* Increment the number of entries passed through */
/* (whether we skipped them or not) */
- udata->final_ent++;
+ (*udata->final_ent)++;
}
if (ret_value<0)
HERROR (H5E_SYM, H5E_CANTNEXT, "iteration operator failed");
@@ -1695,13 +1678,6 @@ done:
* Programmer: Raymond Lu
* Nov 20, 2002
*
- * Modifications:
- *
- * John Mainzer, 6/17/05
- * Modified the function to use the new dirtied parameter of
- * of H5AC_unprotect() instead of modifying the is_dirty
- * field of the cache info.
- *
*-------------------------------------------------------------------------
*/
int
@@ -1709,35 +1685,114 @@ H5G_node_type(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
const void UNUSED *_rt_key, void *_udata)
{
H5G_bt_it_ud3_t *udata = (H5G_bt_it_ud3_t*)_udata;
- hsize_t loc_idx;
H5G_node_t *sn = NULL;
int ret_value = H5B_ITER_CONT;
- FUNC_ENTER_NOAPI(H5G_node_type, H5B_ITER_ERROR);
+ FUNC_ENTER_NOAPI(H5G_node_type, H5B_ITER_ERROR)
/* Check arguments. */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(udata);
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(udata);
/* Find the node, locate the object symbol table entry and retrieve the type */
- if (NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
+ if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node");
if(udata->idx >= udata->num_objs && udata->idx < (udata->num_objs + sn->nsyms)) {
+ H5O_loc_t tmp_oloc; /* Temporary object location */
+ hsize_t loc_idx;
+
+ /* Compute index of entry */
loc_idx = udata->idx - udata->num_objs;
- udata->type = H5G_get_type(&(sn->entry[loc_idx]), dxpl_id);
+
+ /* Build temporary object location */
+ tmp_oloc.file = f;
+ HDassert(H5F_addr_defined(sn->entry[loc_idx].header));
+ tmp_oloc.addr = sn->entry[loc_idx].header;
+
+ udata->type = H5O_obj_type(&tmp_oloc, dxpl_id);
ret_value = H5B_ITER_STOP;
} else {
udata->num_objs += sn->nsyms;
- }
+ } /* end else */
done:
- if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED)
+ if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED)
HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header");
FUNC_LEAVE_NOAPI(ret_value);
-}
+} /* end H5G_node_type() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_node_stab_convert
+ *
+ * Purpose: This function gets called when the entries in a group are
+ * converted from a symbol table to link messages.
+ *
+ * Return: 0 if object isn't found in this node; 1 if found;
+ * Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Sep 5, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5G_node_stab_convert(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
+ const void UNUSED *_rt_key, void *_udata)
+{
+ H5G_bt_it_ud4_t *udata = (H5G_bt_it_ud4_t*)_udata;
+ H5G_node_t *sn = NULL; /* Pointer to symbol table node to operate on */
+ const H5HL_t *heap = NULL; /* Pointer to local heap for group */
+ const char *name; /* Pointer to name of link */
+ const H5G_entry_t *ent; /* Pointer to current entry */
+ unsigned u; /* Local index variable */
+ int ret_value = H5B_ITER_CONT;
+
+ FUNC_ENTER_NOAPI(H5G_node_stab_convert, H5B_ITER_ERROR)
+
+ /* Check arguments. */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(udata);
+
+ /* Lock the symbol table node */
+ if(NULL == (sn = H5AC_protect(f, dxpl_id, H5AC_SNODE, addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node")
+
+ /* Lock the local heap */
+ if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_ITER_ERROR, "unable to protect symbol name")
+
+ /* Convert all the entries from this node into link messages */
+ for(u = 0, ent = sn->entry; u < sn->nsyms; u++, ent++) {
+ /* Get a pointer to the link's name in the local heap */
+ name = H5HL_offset_into(f, heap, ent->name_off);
+ HDassert(name);
+
+ /* Check for too many links for link table */
+ if(udata->nlinks >= udata->max_links)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "too many links for table")
+
+ /* Convert entry into link message object */
+ if(H5G_link_convert(&(udata->lnk_table[udata->nlinks]), ent, heap, name) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCONVERT, FAIL, "can't convert entry to link message")
+
+ /* Increment number of links stored */
+ udata->nlinks++;
+ } /* end for */
+
+done:
+ if(heap && H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to unprotect symbol name")
+
+ if(sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED)
+ HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_node_stab_convert() */
/*-------------------------------------------------------------------------
@@ -1898,62 +1953,74 @@ H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void UNUSED *_lt_key, haddr_t addr,
HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, H5B_ITER_ERROR, "unable to load symbol table node")
/* get the base address of the heap */
- if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->heap_addr)))
+ if(NULL == (heap = H5HL_protect(f, dxpl_id, udata->src_heap_addr)))
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5B_ITER_ERROR, "unable to protect symbol name")
/* copy object in this node one by one */
for(i = 0; i < sn->nsyms; i++) {
- H5G_entry_t ent_new; /* New entry to insert into dest. group */
- H5G_entry_t *ent_src = &(sn->entry[i]); /* Convenience variable to refer to current source group entry */
+ H5G_entry_t *src_ent = &(sn->entry[i]); /* Convenience variable to refer to current source group entry */
+ H5O_loc_t new_oloc; /* Copied object object location */
+ H5O_link_t lnk; /* Link to insert */
const char *name; /* Name of source object */
- /* Set up symbol table entry for destination */
- H5G_ent_reset(&ent_new);
- ent_new.file = udata->loc_dst->file;
-
- /* Determine name of source object */
- name = H5HL_offset_into(f, heap, ent_src->name_off);
- HDassert(name);
+ /* Set up copied object location to fill in */
+ H5O_loc_reset(&new_oloc);
+ new_oloc.file = udata->dst_file;
/* Check if object in source group is a hard link */
- if(H5F_addr_defined(ent_src->header)) {
+ if(H5F_addr_defined(src_ent->header)) {
+ H5O_loc_t src_oloc; /* Temporary object location for source object */
+
+ /* Build temporary object location for source */
+ src_oloc.file = f;
+ HDassert(H5F_addr_defined(src_ent->header));
+ src_oloc.addr = src_ent->header;
+
/* Copy the shared object from source to destination */
/* (Increments link count on destination) */
- if(H5O_copy_header_map(ent_src, &ent_new, dxpl_id, udata->map_list) < 0)
+ if(H5O_copy_header_map(&src_oloc, &new_oloc, dxpl_id, udata->map_list) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, H5B_ITER_ERROR, "unable to copy object")
- } /* ( H5F_addr_defined(ent_src->header)) */
- else if(H5G_CACHED_SLINK == ent_src->type) {
+
+ /* Construct link information for eventual insertion */
+ lnk.type = H5G_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 */
- H5O_stab_t stab_mesg;
- size_t offset_link;
- char *name_link = H5HL_offset_into(f, heap, ent_src->cache.slink.lval_offset);
-
- /* read the symbol table where the soft link to be inserted */
- if(NULL == H5O_read(udata->loc_dst, H5O_STAB_ID, 0, &stab_mesg, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_ITER_ERROR, "unable to determine local heap address")
- if((size_t)(-1) == (offset_link = H5HL_insert(udata->loc_dst->file, dxpl_id,
- stab_mesg.heap_addr, HDstrlen(name_link) + 1, name_link)))
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, H5B_ITER_ERROR, "unable to write link value to local heap")
- H5O_reset (H5O_STAB_ID, &stab_mesg);
-
- /* Set up soft link to insert */
- ent_new.type = H5G_CACHED_SLINK;
- ent_new.cache.slink.lval_offset = offset_link;
+
+ /* Construct link information for eventual insertion */
+ lnk.type = H5G_LINK_SOFT;
+ lnk.u.soft.name = H5HL_offset_into(f, heap, src_ent->cache.slink.lval_offset);
} /* else if */
else
HDassert(0 && "Unknown entry type");
+ /* Set up common link data */
+#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 */
+
+ /* Determine name of source object */
+ name = H5HL_offset_into(f, heap, src_ent->name_off);
+ HDassert(name);
+
/* Insert the new object in the destination file's group */
/* (Don't increment the link count - that's already done above for hard links) */
- if(H5G_stab_insert(udata->loc_dst, name, &ent_new, FALSE, dxpl_id) < 0)
+ if(H5G_stab_insert_real(udata->dst_file, udata->dst_stab, name, &lnk, dxpl_id) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5B_ITER_ERROR, "unable to insert the name")
-
- /* Free the ID to name buffers */
- H5G_free_ent_name(&ent_new);
} /* end of for (i=0; i<sn->nsyms; i++) */
done:
- if (heap && H5HL_unprotect(f, dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ if (heap && H5HL_unprotect(f, dxpl_id, heap, udata->src_heap_addr, H5AC__NO_FLAGS_SET) < 0)
HDONE_ERROR(H5E_SYM, H5E_PROTECT, H5B_ITER_ERROR, "unable to unprotect symbol name")
if (sn && H5AC_unprotect(f, dxpl_id, H5AC_SNODE, addr, sn, H5AC__NO_FLAGS_SET) != SUCCEED)
diff --git a/src/H5Gobj.c b/src/H5Gobj.c
new file mode 100644
index 0000000..a178e93
--- /dev/null
+++ b/src/H5Gobj.c
@@ -0,0 +1,884 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Gobj.c
+ * Sep 5 2005
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Functions for abstract handling of objects in groups.
+ *
+ *-------------------------------------------------------------------------
+ */
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+
+/* Packages needed by this file... */
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5Gpkg.h" /* Groups */
+#include "H5HLprivate.h" /* Local Heaps */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+
+/* Private typedefs */
+
+/* User data for converting link messages to symbol table */
+typedef struct {
+ H5F_t *f; /* Pointer to file for insertion */
+ haddr_t btree_addr; /* Address of symbol table B-tree */
+ haddr_t heap_addr; /* Address of symbol table local heap */
+ hid_t dxpl_id; /* DXPL during insertion */
+} H5G_obj_ud1_t;
+
+/* User data for looking up an object in a group */
+typedef struct {
+ H5O_loc_t *oloc; /* Object location to set */
+} H5G_obj_ud2_t;
+
+/* Private macros */
+
+/* PRIVATE PROTOTYPES */
+static herr_t
+H5G_obj_link_to_stab_cb(const void *_mesg, unsigned idx, void *_udata);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_create
+ *
+ * Purpose: Create an object header for a group and update object location info
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 29 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_obj_create(H5F_t *f, hid_t dxpl_id, H5O_ginfo_t *ginfo, H5O_loc_t *oloc/*out*/)
+{
+ H5O_linfo_t linfo; /* Link information */
+ H5O_link_t lnk; /* Temporary link message info for computing message size */
+ char null_char = '\0'; /* Character for creating null string */
+ size_t ginfo_size; /* Size of the group info message */
+ size_t linfo_size; /* Size of the link info message */
+ size_t link_size; /* Size of a link message */
+ size_t hdr_size; /* Size of object header to request */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_obj_create, FAIL)
+
+ /*
+ * Check arguments.
+ */
+ HDassert(f);
+ HDassert(ginfo);
+ HDassert(oloc);
+
+ /* Initialize message information */
+ linfo.nlinks = 0;
+
+ /* Calculate message size infomation, for creating group's object header */
+ linfo_size = H5O_mesg_size(H5O_LINFO_ID, f, &linfo);
+ HDassert(linfo_size);
+
+ ginfo_size = H5O_mesg_size(H5O_GINFO_ID, f, ginfo);
+ HDassert(ginfo_size);
+
+ lnk.type = H5G_LINK_HARD;
+ lnk.name = &null_char;
+ link_size = H5O_mesg_size(H5O_LINK_ID, f, &lnk);
+ HDassert(link_size);
+
+ /* Compute size of header to use for creation */
+ hdr_size = linfo_size +
+ ginfo_size +
+ (ginfo->est_num_entries * (link_size + ginfo->est_name_len));
+
+ /*
+ * Create symbol table object header. It has a zero link count
+ * since nothing refers to it yet. The link count will be
+ * incremented if the object is added to the group directed graph.
+ */
+ if(H5O_create(f, dxpl_id, hdr_size, oloc/*out*/) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header")
+
+ /* Insert link info message */
+ if(H5O_modify(oloc, H5O_LINFO_ID, H5O_NEW_MESG, 0, 0, &linfo, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
+
+ /* Insert group info message */
+ if(H5O_modify(oloc, H5O_GINFO_ID, H5O_NEW_MESG, H5O_FLAG_CONSTANT, H5O_UPDATE_TIME, ginfo, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_obj_create() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_ent_decode
+ *
+ * Purpose: Decodes a symbol table entry into a object location
+ *
+ * Return: Success: Non-negative with *pp pointing to the first byte
+ * following the symbol table entry.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 26 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_obj_ent_decode(H5F_t *f, const uint8_t **pp, H5O_loc_t *oloc)
+{
+ const uint8_t *p_ret = *pp;
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5G_obj_ent_decode)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(pp);
+ HDassert(oloc);
+
+ /* Set file pointer for root object location */
+ oloc->file = f;
+
+ /* decode header */
+ *pp += H5F_SIZEOF_SIZE(f); /* Skip over local heap address */
+ H5F_addr_decode(f, pp, &(oloc->addr));
+ *pp += 4; /* Skip over "cache type" */
+ *pp += 4; /* Reserved */
+
+ /* Set decode pointer */
+ *pp = p_ret + H5G_SIZEOF_ENTRY(f);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5G_obj_ent_decode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_ent_encode
+ *
+ * Purpose: Encodes the specified object location into a symbol table
+ * entry in the buffer pointed to by *pp.
+ *
+ * Return: Success: Non-negative, with *pp pointing to the first byte
+ * after the symbol table entry.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 26 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_obj_ent_encode(H5F_t *f, uint8_t **pp, const H5O_loc_t *oloc)
+{
+ uint8_t *p_ret = *pp + H5G_SIZEOF_ENTRY(f);
+
+ FUNC_ENTER_NOAPI_NOFUNC(H5G_obj_ent_encode)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(pp);
+
+ /* encode header */
+ H5F_ENCODE_LENGTH(f, *pp, 0); /* No name for root group */
+ if(oloc)
+ H5F_addr_encode(f, pp, oloc->addr);
+ else
+ H5F_addr_encode(f, pp, HADDR_UNDEF);
+ UINT32ENCODE(*pp, H5G_NOTHING_CACHED);
+ UINT32ENCODE(*pp, 0); /*reserved*/
+
+ /* fill with zero */
+ while(*pp < p_ret)
+ *(*pp)++ = 0;
+ *pp = p_ret;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5G_obj_ent_encode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_link_to_stab_cb
+ *
+ * Purpose: Callback routine for converting 'link' messages to symbol table
+ * form.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 30 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_obj_link_to_stab_cb(const void *_mesg, unsigned UNUSED idx, void *_udata)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *)_mesg; /* Pointer to link */
+ H5G_obj_ud1_t *udata = (H5G_obj_ud1_t *)_udata; /* 'User data' passed in */
+ H5G_bt_ud1_t bt_udata; /* Data to pass through B-tree */
+ herr_t ret_value = H5O_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_obj_link_to_stab_cb)
+
+ /* check arguments */
+ HDassert(lnk);
+ HDassert(udata);
+
+ /* Construct user data to pass through B-tree routines */
+ bt_udata.common.name = lnk->name;
+ bt_udata.common.heap_addr = udata->heap_addr;
+ bt_udata.lnk = lnk;
+
+ /* Insert entry into symbol table */
+ if(H5B_insert(udata->f, udata->dxpl_id, H5B_SNODE, udata->btree_addr, &bt_udata) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_obj_link_to_stab_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_insert
+ *
+ * Purpose: Insert a new symbol into the group described by GRP_OLOC.
+ * file F. The name of the new symbol is NAME and its symbol
+ * table entry is OBJ_LNK. Optionally, increment the reference
+ * count for the object the link points to with INC_LINK.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 6 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_obj_insert(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
+ hbool_t inc_link, hid_t dxpl_id)
+{
+ H5O_linfo_t linfo; /* Link info message */
+ htri_t linfo_exists; /* Whether the link info is present */
+ hbool_t use_stab; /* Whether to use symbol table for insertions or not */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_obj_insert, FAIL)
+
+ /* check arguments */
+ HDassert(grp_oloc && grp_oloc->file);
+ HDassert(name && *name);
+ HDassert(obj_lnk);
+
+ /* Check if we have information about the number of objects in this group */
+ if((linfo_exists = H5O_exists(grp_oloc, H5O_LINFO_ID, 0, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for link info")
+ if(linfo_exists) {
+ htri_t stab_exists; /* Whether the symbol table info is present */
+
+ /* Get the number of objects in this group */
+ if(NULL == H5O_read(grp_oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info")
+
+ /* Check if there is already a 'stab' message */
+ if((stab_exists = H5O_exists(grp_oloc, H5O_STAB_ID, 0, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for symbol table")
+ if(stab_exists)
+ use_stab = TRUE;
+ else {
+ H5O_ginfo_t ginfo; /* Group info message */
+ size_t link_msg_size; /* Size of link message in the file */
+
+ /* Get the link message size */
+ if((link_msg_size = H5O_raw_size(H5O_LINK_ID, grp_oloc->file, obj_lnk)) == 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGETSIZE, FAIL, "can't get link size")
+
+ /* Get the group info */
+ if(NULL == H5O_read(grp_oloc, H5O_GINFO_ID, 0, &ginfo, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info")
+
+ /* If there's still a small enough number of links, use the 'link' message */
+ /* (If the encoded form of the link is too large to fit into an object
+ * header message, convert to using symbol table instead of link messages)
+ */
+ if(linfo.nlinks < ginfo.max_compact && link_msg_size < H5O_MAX_SIZE)
+ use_stab = FALSE;
+ else {
+ H5G_obj_ud1_t udata; /* User data for iteration */
+ H5O_stab_t stab; /* Symbol table message */
+
+ /* The group doesn't currently have a 'stab' message, go create one */
+ if(H5G_stab_create(grp_oloc, &stab, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create symbol table")
+
+ /* Set up user data for object header message iteration */
+ udata.f = grp_oloc->file;
+ udata.btree_addr = stab.btree_addr;
+ udata.heap_addr = stab.heap_addr;
+ udata.dxpl_id = dxpl_id;
+
+ /* Iterate over the 'link' messages, inserting them into the symbol table */
+ if(H5O_iterate(grp_oloc, H5O_LINK_ID, H5G_obj_link_to_stab_cb, &udata, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over links")
+
+ /* Remove all the 'link' messages */
+ if(H5O_remove(grp_oloc, H5O_LINK_ID, H5O_ALL, FALSE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete link messages")
+
+ use_stab = TRUE;
+ } /* end else */
+ } /* end else */
+ } /* end if */
+ else
+ use_stab = TRUE;
+
+ /* Insert into symbol table or create link object */
+ if(use_stab) {
+ /* Insert into symbol table */
+ if(H5G_stab_insert(grp_oloc, name, obj_lnk, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry")
+ } /* end if */
+ else {
+ /* Insert with link message */
+ if(H5G_link_insert(grp_oloc, obj_lnk, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry")
+ } /* end else */
+
+ /* Increment the number of objects in this group */
+ if(linfo_exists) {
+ linfo.nlinks++;
+ if(H5O_modify(grp_oloc, H5O_LINFO_ID, 0, 0, H5O_UPDATE_TIME, &linfo, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update link info message")
+ } /* end if */
+
+ /* Increment link count on object, if appropriate */
+ if(inc_link) {
+ H5O_loc_t obj_oloc; /* Object location */
+
+ /* Convert to object location */
+ obj_oloc.file = grp_oloc->file;
+ obj_oloc.addr = obj_lnk->u.hard.addr;
+
+ /* Increment reference count for object */
+ if(H5O_link(&obj_oloc, 1, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to increment hard link count")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_obj_insert() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_iterate
+ *
+ * Purpose: Private function for H5Giterate.
+ * Iterates over objects in a group
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Oct 3, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_obj_iterate(hid_t loc_id, const char *name, int skip, int *last_obj,
+ H5G_iterate_t op, void *op_data, hid_t dxpl_id)
+{
+ htri_t stab_exists; /* Whether the symbol table info is present */
+ hid_t gid = -1; /* ID of group to iterate over */
+ H5G_t *grp; /* Pointer to group data structure to iterate over */
+ herr_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_obj_iterate, FAIL)
+
+ /* Sanity check */
+ HDassert(name);
+ HDassert(last_obj);
+ HDassert(op);
+
+ /*
+ * Open the group on which to operate. We also create a group ID which
+ * we can pass to the application-defined operator.
+ */
+ if((gid = H5Gopen (loc_id, name)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
+ if((grp = H5I_object(gid)) == NULL)
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "bad group ID")
+
+ /* Check if we have information about the number of objects in this group */
+ if((stab_exists = H5O_exists(&(grp->oloc), H5O_STAB_ID, 0, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for symbol table")
+
+ /* If the symbol table doesn't exist, iterate over link messages */
+ if(!stab_exists) {
+ /* Get the object's name from the link messages */
+ if((ret_value = H5G_link_iterate(&(grp->oloc), gid, skip, last_obj, op, op_data, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over links")
+ } /* end if */
+ else {
+ /* Iterate over symbol table */
+ if((ret_value = H5G_stab_iterate(&(grp->oloc), gid, skip, last_obj, op, op_data, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADITER, FAIL, "can't iterate over symbol table")
+ } /* end else */
+
+done:
+ if(gid > 0)
+ H5I_dec_ref(gid); /*also closes 'grp'*/
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_obj_iterate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_count
+ *
+ * Purpose: Check the number of objects in a group
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 6 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_obj_count(H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id)
+{
+ htri_t linfo_exists; /* Whether the link info is present */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_obj_count, FAIL)
+
+ /* Sanity check */
+ HDassert(oloc);
+ HDassert(num_objs);
+
+ /* Check if we have information about the number of objects in this group */
+ if((linfo_exists = H5O_exists(oloc, H5O_LINFO_ID, 0, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for link info")
+
+ /* If the link info exists, then it has the number of objects in the group */
+ if(linfo_exists > 0) {
+ H5O_linfo_t linfo; /* Link info message */
+
+ /* Get the link info for this group */
+ if(NULL == H5O_read(oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info")
+
+ /* Set the number of objects */
+ *num_objs = linfo.nlinks;
+ } /* end if */
+ else {
+ /* Get the number of objects in this group by iterating over symbol table */
+ if(H5G_stab_count(oloc, num_objs, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "can't count objects")
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_obj_count() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_get_name_by_idx
+ *
+ * Purpose: Private function for H5Gget_objname_by_idx.
+ * Returns the name of objects in the group by giving index.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * Nov 20, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5G_obj_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name, size_t size, hid_t dxpl_id)
+{
+ htri_t stab_exists; /* Whether the symbol table info is present */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_obj_get_name_by_idx, FAIL)
+
+ /* Sanity check */
+ HDassert(oloc);
+
+ /* Check if we have information about the number of objects in this group */
+ if((stab_exists = H5O_exists(oloc, H5O_STAB_ID, 0, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for symbol table")
+
+ /* If the symbol table doesn't exist, search link messages */
+ if(!stab_exists) {
+ /* Get the object's name from the link messages */
+ if((ret_value = H5G_link_get_name_by_idx(oloc, idx, name, size, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name")
+ } /* end if */
+ else {
+ /* Get the object's name from the symbol table */
+ if((ret_value = H5G_stab_get_name_by_idx(oloc, idx, name, size, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate name")
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_obj_get_name_by_idx() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_get_type_by_idx
+ *
+ * Purpose: Private function for H5Gget_objtype_by_idx.
+ * Returns the type of objects in the group by giving index.
+ *
+ * Return: Success: H5G_GROUP(1), H5G_DATASET(2), H5G_TYPE(3)
+ *
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * Nov 20, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+H5G_obj_t
+H5G_obj_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
+{
+ htri_t stab_exists; /* Whether the symbol table info is present */
+ H5G_obj_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_obj_get_type_by_idx, H5G_UNKNOWN)
+
+ /* Sanity check */
+ HDassert(oloc);
+
+ /* Check if we have information about the number of objects in this group */
+ if((stab_exists = H5O_exists(oloc, H5O_STAB_ID, 0, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "unable to check for symbol table")
+
+ /* If the symbol table doesn't exist, search link messages */
+ if(!stab_exists) {
+ /* Get the object's type from the link messages */
+ if((ret_value = H5G_link_get_type_by_idx(oloc, idx, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "can't locate type")
+ } /* end if */
+ else {
+ /* Get the object's type from the symbol table */
+ if((ret_value = H5G_stab_get_type_by_idx(oloc, idx, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "can't locate type")
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_obj_get_type_by_idx() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_remove
+ *
+ * Purpose: Remove an object from a group.
+ * (Needs to hand up the type of the object removed)
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Sep 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_obj_remove(H5O_loc_t *oloc, const char *name, H5G_obj_t *obj_type, hid_t dxpl_id)
+{
+ htri_t linfo_exists; /* Whether the link info is present */
+ H5O_linfo_t linfo; /* Link info message */
+ htri_t stab_exists; /* Whether the symbol table info is present */
+ hbool_t use_stab; /* Whether to use symbol table for deletions or not */
+ H5G_obj_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_obj_remove, FAIL)
+
+ /* Sanity check */
+ HDassert(oloc);
+ HDassert(obj_type);
+
+ /* Check if we have information about the number of objects in this group */
+ if((stab_exists = H5O_exists(oloc, H5O_STAB_ID, 0, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for symbol table")
+
+ /* Check if we have information about the number of objects in this group */
+ if((linfo_exists = H5O_exists(oloc, H5O_LINFO_ID, 0, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for link info message")
+ if(linfo_exists) {
+ H5O_ginfo_t ginfo; /* Group info message */
+
+ /* Get the number of objects in this group */
+ if(NULL == H5O_read(oloc, H5O_LINFO_ID, 0, &linfo, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link info")
+
+ /* Check for deleting enough links from group to go back to link messages */
+ if(stab_exists) {
+ /* Get the group info */
+ if(NULL == H5O_read(oloc, H5O_GINFO_ID, 0, &ginfo, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info")
+
+ /* Switch from symbol table back to link messages */
+ if(linfo.nlinks <= ginfo.min_dense) {
+ H5G_bt_it_ud4_t udata;
+ H5O_stab_t stab; /* Info about local heap & B-tree */
+ H5O_link_t *lnk_table; /* Array of links to convert */
+ hbool_t can_convert = TRUE; /* Whether converting to link messages is possible */
+ size_t u; /* Local index */
+
+ /* Get the B-tree & local heap info */
+ if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address")
+
+ /* Allocate space for the link table */
+ H5_CHECK_OVERFLOW(linfo.nlinks, /* From: */ hsize_t, /* To: */size_t);
+ if(NULL == (lnk_table = H5MM_malloc(sizeof(H5O_link_t) * (size_t)linfo.nlinks)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for link table")
+
+ /* Build udata to pass through H5B_iterate() */
+ udata.heap_addr = stab.heap_addr;
+ udata.lnk_table = lnk_table;
+ udata.nlinks = 0;
+ udata.max_links = linfo.nlinks;
+
+ /* Iterate over the group members, building a table of equivalent link messages */
+ if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE,
+ H5G_node_stab_convert, stab.btree_addr, &udata)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "error iterating over entries")
+
+ /* Inspect links in table for ones that can't be converted back
+ * into link message form (currently only links which can't fit
+ * into an object header message)
+ */
+ for(u = 0; u < linfo.nlinks; u++)
+ if(H5O_mesg_size(H5O_LINK_ID, oloc->file, &(lnk_table[u])) >= H5O_MAX_SIZE) {
+ can_convert = FALSE;
+ break;
+ } /* end if */
+
+ /* If ok, insert links as link messages */
+ if(can_convert) {
+ for(u = 0; u < linfo.nlinks; u++) {
+ /* Insert link message into group */
+ if(H5O_modify(oloc, H5O_LINK_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, &(lnk_table[u]), dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
+ } /* end for */
+
+ /* Remove the 'stab' message */
+ if(H5O_remove(oloc, H5O_STAB_ID, H5O_ALL, FALSE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete symbol table message")
+
+ use_stab = FALSE;
+ } /* end if */
+ else
+ use_stab = TRUE;
+
+ /* 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)
+ H5MM_xfree(lnk_table[u].u.soft.name);
+ } /* end for */
+
+ /* Release memory for link table */
+ H5MM_xfree(lnk_table);
+ } /* end if */
+ else
+ use_stab = TRUE;
+ } /* end if */
+ else
+ use_stab = FALSE;
+ } /* end if */
+ else
+ use_stab = TRUE;
+
+ /* If the symbol table doesn't exist, search link messages */
+ if(!use_stab) {
+ /* Remove object from the link messages */
+ if((ret_value = H5G_link_remove(oloc, name, obj_type, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't remove object")
+ } /* end if */
+ else {
+ /* Remove object from the symbol table */
+ if((ret_value = H5G_stab_remove(oloc, name, obj_type, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't remove object")
+ } /* end else */
+
+ /* Decrement the number of objects in this group */
+ if(linfo_exists) {
+ linfo.nlinks--;
+ if(H5O_modify(oloc, H5O_LINFO_ID, 0, 0, H5O_UPDATE_TIME, &linfo, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update link info message")
+
+ /* Remove the symbol table, if we are using one and the number of links drops to zero */
+ if(linfo.nlinks == 0 && use_stab) {
+ if(H5O_remove(oloc, H5O_STAB_ID, H5O_ALL, FALSE, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTDELETE, FAIL, "unable to delete symbol table message")
+ } /* end if */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_obj_remove() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_lookup
+ *
+ * Purpose: Look up a link in a group.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 26 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_obj_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk,
+ hid_t dxpl_id)
+{
+ htri_t stab_exists; /* Whether the symbol table info is present */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_obj_lookup, FAIL)
+
+ /* check arguments */
+ HDassert(grp_oloc && grp_oloc->file);
+ HDassert(name && *name);
+
+ /* Check if we have information about the number of objects in this group */
+ if((stab_exists = H5O_exists(grp_oloc, H5O_STAB_ID, 0, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to check for symbol table")
+
+ /* If the symbol table doesn't exist, search link messages */
+ if(!stab_exists) {
+ /* Get the object's info from the link messages */
+ if(H5G_link_lookup(grp_oloc, name, lnk, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object")
+ } /* end if */
+ else {
+ /* Get the object's info from the symbol table */
+ if(H5G_stab_lookup(grp_oloc, name, lnk, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't locate object")
+ } /* end else */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_obj_lookup() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_find_cb
+ *
+ * Purpose: Callback for retrieving object location for an object in a group
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 20, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_obj_find_cb(H5G_loc_t UNUSED *grp_loc/*in*/, const char UNUSED *name, const H5O_link_t UNUSED *lnk,
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+{
+ H5G_obj_ud2_t *udata = (H5G_obj_ud2_t *)_udata; /* User data passed in */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_obj_find_cb)
+
+ /* Check if the name in this group resolved to a valid link */
+ if(obj_loc == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "name doesn't exist")
+
+ /* Copy object location for object */
+ H5O_loc_copy(udata->oloc, obj_loc->oloc, H5O_COPY_DEEP);
+
+ /* 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)
+ */
+ H5G_loc_free(obj_loc);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_obj_find_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_obj_find
+ *
+ * Purpose: Look up an object relative to a group.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 20 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_obj_find(H5G_loc_t *loc, const char *name, unsigned traverse_flags,
+ H5O_loc_t *obj_oloc, hid_t dxpl_id)
+{
+ H5G_obj_ud2_t udata; /* User data for traversal callback */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_obj_find, FAIL)
+
+ /* check arguments */
+ HDassert(loc && loc->oloc->file);
+ HDassert(name && *name);
+ HDassert(obj_oloc);
+
+ /* Set up user data for locating object */
+ udata.oloc = obj_oloc;
+
+ /* Traverse group hierarchy to locate object */
+ if(H5G_traverse(loc, name, traverse_flags, H5G_obj_find_cb, &udata, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "can't find object")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_obj_find() */
+
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index 4c6ec68..ad65fc1 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -36,6 +36,55 @@
#include "H5SLprivate.h" /* Skip lists */
#define H5G_SIZE_HINT 256 /* default root grp size hint */
+#define H5G_NLINKS 16 /*max symlinks to follow per lookup */
+
+/*
+ * Various types of object header information can be cached in a symbol
+ * table entry (it's normal home is the object header to which the entry
+ * points). This datatype determines what (if anything) is cached in the
+ * symbol table entry.
+ */
+typedef enum H5G_type_t {
+ H5G_CACHED_ERROR = -1, /*force enum to be signed */
+ H5G_NOTHING_CACHED = 0, /*nothing is cached, must be 0 */
+ H5G_CACHED_STAB = 1, /*symbol table, `stab' */
+ H5G_CACHED_SLINK = 2, /*symbolic link */
+
+ H5G_NCACHED = 3 /*THIS MUST BE LAST */
+} H5G_type_t;
+
+/*
+ * A symbol table entry caches these parameters from object header
+ * messages... The values are entered into the symbol table when an object
+ * header is created (by hand) and are extracted from the symbol table with a
+ * callback function registered in H5O_init_interface(). Be sure to update
+ * H5G_ent_decode(), H5G_ent_encode(), and H5G_ent_debug() as well.
+ */
+typedef union H5G_cache_t {
+ struct {
+ haddr_t btree_addr; /*file address of symbol table B-tree*/
+ haddr_t heap_addr; /*file address of stab name heap */
+ } stab;
+
+ struct {
+ size_t lval_offset; /*link value offset */
+ } slink;
+} H5G_cache_t;
+
+/*
+ * A symbol table entry. The two important fields are `name_off' and
+ * `header'. The remaining fields are used for caching information that
+ * also appears in the object header to which this symbol table entry
+ * points.
+ */
+typedef struct H5G_entry_t {
+ hbool_t dirty; /*entry out-of-date? */
+ H5G_type_t type; /*type of information cached */
+ H5G_cache_t cache; /*cached data from object header */
+ size_t name_off; /*offset of name within name heap */
+ haddr_t header; /*file address of object header */
+ H5F_t *file; /*file to which this obj hdr belongs */
+} H5G_entry_t;
/*
* A symbol table node is a collection of symbol table entries. It can
@@ -63,8 +112,9 @@ struct H5G_shared_t {
* above the H5G layer.
*/
struct H5G_t {
- H5G_shared_t* shared; /*shared file object data */
- H5G_entry_t ent; /*info about the group */
+ H5G_shared_t *shared; /* Shared file object data */
+ H5O_loc_t oloc; /* Object location for group */
+ H5G_name_t path; /* Group hierarchy path */
};
/*
@@ -90,15 +140,12 @@ typedef H5G_bt_ud_common_t H5G_bt_ud0_t;
/*
* Data exchange structure for symbol table nodes. This structure is
- * passed through the B-link tree layer to the methods for the objects
- * to which the B-link tree points.
+ * passed through the B-link tree layer to the insert method for entries.
*/
typedef struct H5G_bt_ud1_t {
/* downward */
H5G_bt_ud_common_t common; /* Common info for B-tree user data (must be first) */
-
- /* downward for INSERT, upward for FIND */
- H5G_entry_t *ent; /*entry to insert into table */
+ const H5O_link_t *lnk; /* Link to insert into table */
} H5G_bt_ud1_t;
/*
@@ -112,8 +159,25 @@ typedef struct H5G_bt_ud2_t {
hbool_t adj_link; /* Whether to adjust the link count on objects */
/* upward */
+ H5G_obj_t *obj_type; /*member type to be returned */
} H5G_bt_ud2_t;
+/* Typedef for B-tree 'find' operation */
+typedef herr_t (*H5G_bt_find_op_t)(const H5G_entry_t *ent/*in*/, void *operator_data/*in,out*/);
+
+/*
+ * Data exchange structure for symbol table nodes. This structure is
+ * passed through the B-link tree layer to the 'find' method for entries.
+ */
+typedef struct H5G_bt_ud3_t {
+ /* downward */
+ H5G_bt_ud_common_t common; /* Common info for B-tree user data (must be first) */
+ H5G_bt_find_op_t op; /* Operator to call when correct entry is found */
+ void *op_data; /* Data to pass to operator */
+
+ /* upward */
+} H5G_bt_ud3_t;
+
/*
* Data exchange structure to pass through the B-tree layer for the
* H5B_iterate function.
@@ -127,7 +191,7 @@ typedef struct H5G_bt_it_ud1_t {
int skip; /*initial entries to skip */
/* upward */
- int final_ent; /*final entry looked at */
+ int *final_ent; /*final entry looked at */
} H5G_bt_it_ud1_t;
/*
@@ -164,18 +228,52 @@ typedef struct H5G_bt_it_ud3_t {
typedef struct H5G_bt_it_ud4_t {
/* downward */
haddr_t heap_addr; /*symbol table heap address */
- H5G_entry_t *grp_ent; /*entry of group */
+ size_t max_links; /* Max. # of links array can store */
/* upward */
+ H5O_link_t *lnk_table; /* Pointer to array of links to fill in */
+ size_t nlinks; /* Links inserted into table */
} H5G_bt_it_ud4_t;
/* Data passed to B-tree iteration for copying copy symblol table content */
typedef struct H5G_bt_it_ud5_t {
+ haddr_t src_heap_addr; /* heap address of the source symbol table */
+ H5F_t *dst_file; /* File of destination group */
+ H5O_stab_t *dst_stab; /* symbol table info for destination group */
H5SL_t *map_list; /* skip list to map copied object addresses */
- haddr_t heap_addr; /* heap address of the source symbol table */
- H5G_entry_t *loc_dst; /* group where new object is inserted to */
} H5G_bt_it_ud5_t;
+/* Typedef for path traversal operations */
+typedef herr_t (*H5G_traverse_t)(H5G_loc_t *grp_loc/*in*/, const char *name,
+ const H5O_link_t *lnk/*in*/, H5G_loc_t *obj_loc/*out*/, void *operator_data/*in,out*/);
+
+/* "value" information for a link (as opposed to "name" of link) */
+typedef struct {
+ haddr_t addr; /* Address of object linked to */
+} H5G_linkvalue_hard_t;
+
+typedef struct {
+ char *name; /* Link value */
+} H5G_linkvalue_soft_t;
+
+typedef struct {
+ H5G_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 */
+ } u;
+} H5G_linkvalue_t;
+
+/*
+ * During name lookups (see H5G_traverse()) we sometimes want information about
+ * a symbolic link or a mount point. The normal operation is to follow the
+ * symbolic link or mount point and return information about its target.
+ */
+#define H5G_TARGET_NORMAL 0x0000
+#define H5G_TARGET_SLINK 0x0001
+#define H5G_TARGET_MOUNT 0x0002
+#define H5G_CRT_INTMD_GROUP 0x0004
+
/*
* This is the class identifier to give to the B-tree functions.
*/
@@ -185,32 +283,56 @@ H5_DLLVAR H5B_class_t H5B_SNODE[1];
H5_DLLVAR const H5AC_class_t H5AC_SNODE[1];
/*
+ * Utility functions
+ */
+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);
+H5_DLL herr_t H5G_traverse(const H5G_loc_t *loc, const char *name,
+ unsigned target, H5G_traverse_t op, void *op_data, hid_t dxpl_id);
+
+/*
* Functions that understand symbol tables but not names. The
* functions that understand names are exported to the rest of
* the library and appear in H5Gprivate.h.
*/
-H5_DLL herr_t H5G_stab_create(H5F_t *f, hid_t dxpl_id, size_t size_hint,
- H5G_entry_t *ent/*out*/);
-H5_DLL herr_t H5G_stab_find(H5G_entry_t *grp_ent, const char *name,
- H5G_entry_t *obj_ent/*out*/, hid_t dxpl_id);
-H5_DLL herr_t H5G_stab_insert(H5G_entry_t *grp_ent, const char *name,
- H5G_entry_t *obj_ent, hbool_t inc_link, hid_t dxpl_id);
+H5_DLL herr_t H5G_stab_create(H5O_loc_t *grp_oloc, H5O_stab_t *stab, hid_t dxpl_id);
+H5_DLL herr_t H5G_stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint, hid_t dxpl_id);
+H5_DLL herr_t H5G_stab_insert(H5O_loc_t *grp_oloc, const char *name,
+ H5O_link_t *obj_lnk, hid_t dxpl_id);
+H5_DLL herr_t H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name,
+ H5O_link_t *obj_lnk, hid_t dxpl_id);
H5_DLL herr_t H5G_stab_delete(H5F_t *f, hid_t dxpl_id, const H5O_stab_t *stab, hbool_t adj_link);
-H5_DLL herr_t H5G_stab_remove(H5G_entry_t *grp_ent, const char *name, hid_t dxpl_id);
-H5_DLL herr_t H5G_stab_copy_tmp(H5F_t *f_dst, H5O_stab_t *stab_dst,
+H5_DLL herr_t H5G_stab_iterate(H5O_loc_t *oloc, hid_t gid, int skip,
+ int *last_obj, H5G_iterate_t op, void *op_data, hid_t dxpl_id);
+H5_DLL herr_t H5G_stab_count(struct H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id);
+H5_DLL ssize_t H5G_stab_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name,
+ size_t size, hid_t dxpl_id);
+H5_DLL H5G_obj_t H5G_stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx,
hid_t dxpl_id);
-
+H5_DLL herr_t H5G_stab_remove(H5O_loc_t *oloc, const char *name,
+ H5G_obj_t *obj_type, hid_t dxpl_id);
+H5_DLL herr_t H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name,
+ H5O_link_t *lnk, hid_t dxpl_id);
/*
* Functions that understand symbol table entries.
*/
+H5_DLL herr_t H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src,
+ H5G_copy_depth_t depth);
+H5_DLL herr_t H5G_ent_reset(H5G_entry_t *ent);
H5_DLL herr_t H5G_ent_decode_vec(H5F_t *f, const uint8_t **pp,
H5G_entry_t *ent, unsigned n);
H5_DLL herr_t H5G_ent_encode_vec(H5F_t *f, uint8_t **pp,
const H5G_entry_t *ent, unsigned n);
-H5_DLL herr_t H5G_ent_set_name(H5G_entry_t *loc, H5G_entry_t *obj, const char *name);
+H5_DLL herr_t H5G_ent_modified(H5G_entry_t *ent, H5G_type_t cache_type);
+H5_DLL herr_t H5G_ent_convert(H5F_t *f, haddr_t heap_addr, const char *name,
+ const H5O_link_t *lnk, H5G_entry_t *ent, hid_t dxpl_id);
+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);
/* 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,
const void *_rt_key, void *_udata);
H5_DLL int H5G_node_sumup(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr,
@@ -221,5 +343,68 @@ H5_DLL int H5G_node_type(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t a
const void *_rt_key, void *_udata);
H5_DLL int H5G_node_copy(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr,
const void *_rt_key, void *_udata);
+H5_DLL int H5G_node_stab_convert(H5F_t *f, hid_t dxpl_id, const void *_lt_key, haddr_t addr,
+ const void *_rt_key, void *_udata);
+
+/* Functions that understand link messages */
+/* forward reference for later use */
+struct H5HL_t; /* defined in H5HLprivate.h */
+H5_DLL herr_t H5G_link_convert(H5O_link_t *lnk, const H5G_entry_t *ent,
+ const struct H5HL_t *_heap, const char *name);
+H5_DLL herr_t H5G_link_insert(H5O_loc_t *grp_oloc, H5O_link_t *obj_lnk,
+ hid_t dxpl_id);
+H5_DLL ssize_t H5G_link_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name,
+ size_t size, hid_t dxpl_id);
+H5_DLL H5G_obj_t H5G_link_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx,
+ hid_t dxpl_id);
+H5_DLL herr_t H5G_link_remove(const H5O_loc_t *oloc, const char *name,
+ H5G_obj_t *obj_type, hid_t dxpl_id);
+H5_DLL herr_t H5G_link_iterate(H5O_loc_t *oloc, hid_t gid, int skip,
+ int *last_obj, H5G_iterate_t op, void *op_data, hid_t dxpl_id);
+H5_DLL herr_t H5G_link_lookup(H5O_loc_t *grp_oloc, const char *name,
+ H5O_link_t *lnk, hid_t dxpl_id);
+
+/* Functions that understand objects */
+H5_DLL herr_t H5G_obj_create(H5F_t *f, hid_t dxpl_id, H5O_ginfo_t *ginfo,
+ H5O_loc_t *oloc/*out*/);
+H5_DLL herr_t H5G_obj_insert(H5O_loc_t *grp_oloc, const char *name,
+ H5O_link_t *obj_lnk, hbool_t inc_link, hid_t dxpl_id);
+H5_DLL herr_t H5G_obj_lookup(H5O_loc_t *grp_oloc, const char *name,
+ H5O_link_t *lnk, hid_t dxpl_id);
+H5_DLL herr_t H5G_obj_iterate(hid_t loc_id, const char *name, int skip,
+ int *last_obj, H5G_iterate_t op, void *op_data, hid_t dxpl_id);
+H5_DLL herr_t H5G_obj_count(struct H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id);
+H5_DLL ssize_t H5G_obj_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx,
+ char* name, size_t size, hid_t dxpl_id);
+H5_DLL H5G_obj_t H5G_obj_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx,
+ hid_t dxpl_id);
+H5_DLL herr_t H5G_obj_remove(H5O_loc_t *oloc, const char *name,
+ H5G_obj_t *obj_type, hid_t dxpl_id);
+H5_DLL herr_t H5G_obj_find(H5G_loc_t *loc, const char *name,
+ unsigned traverse_flags, H5O_loc_t *obj_oloc, hid_t dxpl_id);
+
+/*
+ * These functions operate on group hierarchy names.
+ */
+H5_DLL herr_t H5G_name_init(H5G_name_t *name, const char *path);
+H5_DLL herr_t H5G_name_set(H5G_name_t *loc, H5G_name_t *obj, const char *name);
+
+/*
+ * These functions operate on group "locations"
+ */
+H5_DLL herr_t H5G_loc_copy(H5G_loc_t *dst, H5G_loc_t *src, H5G_copy_depth_t depth);
+H5_DLL herr_t H5G_loc_insert(H5G_loc_t *grp_loc, const char *name,
+ H5G_loc_t *obj_loc, hbool_t inc_link, hid_t dxpl_id);
+H5_DLL herr_t H5G_loc_exists(const H5G_loc_t *loc, const char *name, hid_t dxpl_id);
+H5_DLL herr_t H5G_loc_remove(H5G_loc_t *grp_loc, const char *name,
+ H5G_loc_t *obj_loc, hid_t dxpl_id);
+
+/* Testing functions */
+#ifdef H5G_TESTING
+H5_DLL htri_t H5G_is_empty_test(hid_t gid);
+H5_DLL htri_t H5G_has_links_test(hid_t gid, unsigned *nmsgs);
+H5_DLL htri_t H5G_has_stab_test(hid_t gid);
+#endif /* H5G_TESTING */
#endif
+
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 815a76f..b902f98 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -20,11 +20,6 @@
*
* Purpose: Library-visible declarations.
*
- * Modifications: Aug 22, 2002
- * Pedro Vicente <pvn@ncsa.uiuc.edu>
- * Added 'names' field to H5G_entry_t
- * Added H5G_replace_name
- *
*-------------------------------------------------------------------------
*/
@@ -49,8 +44,6 @@
#define H5G_NODE_MAGIC "SNOD" /*symbol table node magic number */
#define H5G_NODE_SIZEOF_MAGIC 4 /*sizeof symbol node magic number */
-#define H5G_NO_CHANGE (-1) /*see H5G_ent_modified() */
-#define H5G_NLINKS 16 /*max symlinks to follow per lookup */
/*
* The disk size for a symbol table entry...
@@ -65,113 +58,84 @@
/* ========= Group Creation properties ============ */
-/* Definitions for local heap size hint */
+/* Defaults for group info values */
+#define H5G_CRT_GINFO_LHEAP_SIZE_HINT 0
+#define H5G_CRT_GINFO_MAX_COMPACT 8
+#define H5G_CRT_GINFO_MIN_DENSE 6
+#define H5G_CRT_GINFO_EST_NUM_ENTRIES 4
+#define H5G_CRT_GINFO_EST_NAME_LEN 8
+
+/* Definitions for group info settings */
#define H5G_CRT_GROUP_INFO_NAME "group info"
#define H5G_CRT_GROUP_INFO_SIZE sizeof(H5O_ginfo_t)
-#define H5G_CRT_GROUP_INFO_DEF {0, 8, 6, 4, 8}
+#define H5G_CRT_GROUP_INFO_DEF {H5G_CRT_GINFO_LHEAP_SIZE_HINT, \
+ H5G_CRT_GINFO_MAX_COMPACT, \
+ H5G_CRT_GINFO_MIN_DENSE, \
+ 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
-/*
- * Various types of object header information can be cached in a symbol
- * table entry (it's normal home is the object header to which the entry
- * points). This datatype determines what (if anything) is cached in the
- * symbol table entry.
- */
-typedef enum H5G_type_t {
- H5G_CACHED_ERROR = -1, /*force enum to be signed */
- H5G_NOTHING_CACHED = 0, /*nothing is cached, must be 0 */
- H5G_CACHED_STAB = 1, /*symbol table, `stab' */
- H5G_CACHED_SLINK = 2, /*symbolic link */
-
- H5G_NCACHED = 3 /*THIS MUST BE LAST */
-} H5G_type_t;
+/* Type of operation being performed for call to H5G_name_replace() */
+typedef enum {
+ OP_MOVE = 0, /* H5*move call */
+ OP_UNLINK, /* H5Gunlink call */
+ OP_MOUNT, /* H5Fmount call */
+ OP_UNMOUNT /* H5Funmount call */
+} H5G_names_op_t;
-/*
- * A symbol table entry caches these parameters from object header
- * messages... The values are entered into the symbol table when an object
- * header is created (by hand) and are extracted from the symbol table with a
- * callback function registered in H5O_init_interface(). Be sure to update
- * H5G_ent_decode(), H5G_ent_encode(), and H5G_ent_debug() as well.
- */
-typedef union H5G_cache_t {
- struct {
- haddr_t btree_addr; /*file address of symbol table B-tree*/
- haddr_t heap_addr; /*file address of stab name heap */
- } stab;
+/* Structure to store information about the name an object was opened with */
+typedef struct {
+ H5RS_str_t *user_path_r; /* Path to object, as opened by user */
+ H5RS_str_t *canon_path_r; /* Path to object, as found in file */
+ unsigned user_path_hidden; /* Whether the user's path is valid */
+} H5G_name_t;
- struct {
- size_t lval_offset; /*link value offset */
- } slink;
-} H5G_cache_t;
+/* Forward declarations */
+struct H5P_genplist_t;
+struct H5O_loc_t;
/*
- * A symbol table entry. The two important fields are `name_off' and
- * `header'. The remaining fields are used for caching information that
- * also appears in the object header to which this symbol table entry
- * points.
+ * The "location" of an object in a group hierarchy. This points to an object
+ * location and a group hierarchy path for the object.
*/
-typedef struct H5G_entry_t {
- hbool_t dirty; /*entry out-of-date? */
- H5G_type_t type; /*type of information cached */
- H5G_cache_t cache; /*cached data from object header */
- size_t name_off; /*offset of name within name heap */
- haddr_t header; /*file address of object header */
- H5F_t *file; /*file to which this obj hdr belongs */
- H5RS_str_t *user_path_r; /* Path to object, as opened by user */
- H5RS_str_t *canon_path_r; /* Path to object, as found in file */
- unsigned user_path_hidden; /* Whether the user's path is valid */
-} H5G_entry_t;
+typedef struct {
+ struct H5O_loc_t *oloc; /* Object header location */
+ H5G_name_t *path; /* Group hierarchy path */
+} H5G_loc_t;
typedef struct H5G_t H5G_t;
typedef struct H5G_shared_t H5G_shared_t;
-/* Type of operation being performed for call to H5G_replace_name() */
-typedef enum {
- OP_MOVE = 0, /* H5*move call */
- OP_UNLINK, /* H5Gunlink call */
- OP_MOUNT, /* H5Fmount call */
- OP_UNMOUNT /* H5Funmount call */
-} H5G_names_op_t;
-
/* Depth of group entry copy */
+/* (Also used for group hier. name copies) */
typedef enum {
- H5G_COPY_NULL, /* Null destination names */
- H5G_COPY_LIMITED, /* Limited copy from source to destination, omitting name & old name fields */
H5G_COPY_SHALLOW, /* Copy from source to destination, including name & old name fields */
+ H5G_COPY_CANON, /* Keep user path the same, but deep copy canonical path */
H5G_COPY_DEEP /* Deep copy from source to destination, including duplicating name & old name fields */
-} H5G_ent_copy_depth_t;
-
-/* Forward declarations for prototype arguments */
-struct H5P_genplist_t;
+} H5G_copy_depth_t;
/*
* Library prototypes... These are the ones that other packages routinely
* call.
*/
-H5_DLL H5G_entry_t *H5G_loc(hid_t loc_id);
-H5_DLL herr_t H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_entry_t *root_entry);
-H5_DLL H5G_entry_t *H5G_entof(H5G_t *grp);
+H5_DLL htri_t H5G_isa(struct H5O_loc_t *loc, hid_t dxpl_id);
+H5_DLL herr_t H5G_mkroot(H5F_t *f, hid_t dxpl_id, H5G_loc_t *root_loc);
+H5_DLL struct H5O_loc_t *H5G_oloc(H5G_t *grp);
+H5_DLL H5G_name_t * H5G_nameof(H5G_t *grp);
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_entry_t *ent, hid_t dxpl_id);
+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 H5G_obj_t H5G_get_type(H5G_entry_t *ent, hid_t dxpl_id);
-H5_DLL herr_t H5G_get_objinfo(H5G_entry_t *loc, const char *name,
- hbool_t follow_link,
- H5G_stat_t *statbuf/*out*/, hid_t dxpl_id);
-H5_DLL herr_t H5G_insert(H5G_entry_t *loc, const char *name,
- H5G_entry_t *ent, hid_t dxpl_id, struct H5P_genplist_t *oc_plist);
-H5_DLL herr_t H5G_find(H5G_entry_t *loc, const char *name,
- H5G_entry_t *ent/*out*/, hid_t dxpl_id);
-H5_DLL H5F_t *H5G_insertion_file(H5G_entry_t *loc, const char *name, hid_t dxpl_id);
-H5_DLL herr_t H5G_replace_name(H5G_obj_t type, H5G_entry_t *loc,
- H5RS_str_t *src_name, H5G_entry_t *src_loc,
- H5RS_str_t *dst_name, H5G_entry_t *dst_loc, H5G_names_op_t op);
-H5_DLL herr_t H5G_free_grp_name(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(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);
+H5_DLL herr_t H5G_free_grp_name(H5G_t *grp);
H5_DLL herr_t H5G_get_shared_count(H5G_t *grp);
H5_DLL herr_t H5G_mount(H5G_t *grp);
H5_DLL herr_t H5G_unmount(H5G_t *grp);
@@ -179,24 +143,36 @@ H5_DLL herr_t H5G_unmount(H5G_t *grp);
/*
* These functions operate on symbol table nodes.
*/
+H5_DLL herr_t H5G_node_close(const H5F_t *f);
H5_DLL herr_t H5G_node_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream,
int indent, int fwidth, haddr_t heap);
-H5_DLL herr_t H5G_node_init(H5F_t *f);
-H5_DLL herr_t H5G_node_close(const H5F_t *f);
/*
- * These functions operate on symbol table entries. They're used primarily
- * in the H5O package where header messages are cached in symbol table
- * entries. The subclasses of H5O probably don't need them though.
+ * These functions operate on group object locations.
+ */
+/* forward reference for later use */
+H5_DLL herr_t H5G_obj_ent_decode(H5F_t *f, const uint8_t **pp,
+ struct H5O_loc_t *oloc);
+H5_DLL herr_t H5G_obj_ent_encode(H5F_t *f, uint8_t **pp,
+ const struct H5O_loc_t *oloc);
+
+/*
+ * These functions operate on group hierarchy names.
*/
-H5_DLL herr_t H5G_ent_encode(H5F_t *f, uint8_t **pp, const H5G_entry_t *ent);
-H5_DLL herr_t H5G_ent_decode(H5F_t *f, const uint8_t **pp,
- H5G_entry_t *ent/*out*/);
-H5_DLL const H5G_cache_t *H5G_ent_cache(const H5G_entry_t *ent, H5G_type_t *cache_type);
-H5_DLL herr_t H5G_ent_copy(H5G_entry_t *dst, const H5G_entry_t *src,
- H5G_ent_copy_depth_t depth);
-H5_DLL herr_t H5G_ent_reset(H5G_entry_t *ent);
-H5_DLL herr_t H5G_free_ent_name(H5G_entry_t *ent);
-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);
+H5_DLL herr_t H5G_name_replace(H5G_obj_t type, H5G_loc_t *loc,
+ H5RS_str_t *src_name, H5G_loc_t *src_loc,
+ H5RS_str_t *dst_name, H5G_loc_t *dst_loc, H5G_names_op_t op);
+H5_DLL herr_t H5G_name_reset(H5G_name_t *name);
+H5_DLL herr_t H5G_name_copy(H5G_name_t *dst, const H5G_name_t *src, H5G_copy_depth_t depth);
+H5_DLL herr_t H5G_name_free(H5G_name_t *name);
+
+/*
+ * These functions operate on group "locations"
+ */
+H5_DLL herr_t H5G_loc(hid_t loc_id, H5G_loc_t *loc);
+H5_DLL herr_t H5G_loc_find(H5G_loc_t *loc, const char *name,
+ H5G_loc_t *obj_loc/*out*/, hid_t dxpl_id);
+H5_DLL herr_t H5G_loc_reset(H5G_loc_t *loc);
+H5_DLL herr_t H5G_loc_free(H5G_loc_t *loc);
+
#endif
diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h
index 1a7807a..f906a84 100644
--- a/src/H5Gpublic.h
+++ b/src/H5Gpublic.h
@@ -32,6 +32,7 @@
#include "H5public.h"
#include "H5Ipublic.h"
#include "H5Opublic.h"
+#include "H5Tpublic.h"
#ifdef __cplusplus
extern "C" {
@@ -82,6 +83,8 @@ typedef struct H5G_slink_stat_t {
typedef struct H5G_stat_t {
unsigned long fileno; /* File number */
+ H5T_cset_t cset; /* Character set of link name */
+ time_t ctime; /* Creation time */
H5G_obj_t type; /* Object type */
union {
H5G_obj_stat_t obj; /* Information about objects */
@@ -121,10 +124,12 @@ H5_DLL int H5Gget_comment(hid_t loc_id, const char *name, size_t bufsize,
char *buf);
H5_DLL hid_t H5Gcreate_expand(hid_t loc_id, const char *name, hid_t gcpl_id,
hid_t gapl_id);
-H5_DLL herr_t H5Gcopy(hid_t id_src, hid_t loc_dst, const char *name_dst,
+H5_DLL hid_t H5Gget_create_plist(hid_t group_id);
+H5_DLL herr_t H5Gcopy(hid_t src_id, hid_t dst_loc_id, const char *name_dst,
hid_t plist_id);
#ifdef __cplusplus
}
#endif
#endif
+
diff --git a/src/H5Gstab.c b/src/H5Gstab.c
index b63e1cd..926ff7f 100644
--- a/src/H5Gstab.c
+++ b/src/H5Gstab.c
@@ -26,87 +26,170 @@
#include "H5Fpkg.h" /* File access */
#include "H5Gpkg.h" /* Groups */
#include "H5HLprivate.h" /* Local Heaps */
+#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
+/* Private typedefs */
+/* User data for finding a name in the link messages */
+typedef struct {
+ /* downward */
+ H5F_t *f; /* Pointer to file for insertion */
+ const char *name; /* Name to search for */
+
+ /* upward */
+ H5G_entry_t *ent; /* Entry to update when match found */
+} H5G_stab_ud1_t;
+
+/* User data for finding object info from B-tree */
+typedef struct {
+ /* downward */
+ H5O_loc_t *grp_oloc; /* Object location of group */
+ hid_t dxpl_id; /* DXPL during operation */
+ haddr_t heap_addr; /* Local heap address for group */
+
+ /* upward */
+ H5G_stat_t *statbuf; /* Caller's statbuf */
+} H5G_stab_fnd_ud1_t;
+
+/* User data for finding link information from B-tree */
+typedef struct {
+ /* downward */
+ H5F_t *file; /* Pointer to file for query */
+ hid_t dxpl_id; /* DXPL during operation */
+ const char *name; /* Name to search for */
+ haddr_t heap_addr; /* Local heap address for group */
+
+ /* upward */
+ H5O_link_t *lnk; /* Caller's link location */
+} H5G_stab_fnd_ud2_t;
+
+/* User data for finding object location from B-tree */
+typedef struct {
+ /* downward */
+ H5F_t *file; /* Pointer to file for query */
+ size_t size; /* Buffer size for link value */
+ haddr_t heap_addr; /* Local heap address for group */
+ hid_t dxpl_id; /* DXPL during operation */
+
+ /* upward */
+ char *buf; /* Buffer to fill with link value */
+} H5G_stab_fnd_ud3_t;
+
/* Private prototypes */
/*-------------------------------------------------------------------------
- * Function: H5G_stab_create
+ * Function: H5G_stab_create_components
*
- * Purpose: Creates a new empty symbol table (object header, name heap,
+ * Purpose: Creates the components for a new, empty, symbol table (name heap
* and B-tree). The caller can specify an initial size for the
- * name heap. The object header of the group is opened for
- * write access.
+ * name heap.
*
* In order for the B-tree to operate correctly, the first
* item in the heap is the empty string, and must appear at
* heap offset zero.
*
- * Errors:
- *
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 1 1997
- *
- * Modifications:
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Nov 7 2005
*
*-------------------------------------------------------------------------
*/
herr_t
-H5G_stab_create(H5F_t *f, hid_t dxpl_id, size_t init, H5G_entry_t *self/*out*/)
+H5G_stab_create_components(H5F_t *f, H5O_stab_t *stab, size_t size_hint, hid_t dxpl_id)
{
- size_t name; /*offset of "" name */
- H5O_stab_t stab; /*symbol table message */
- herr_t ret_value=SUCCEED; /* Return value */
+ size_t name_offset; /* Offset of "" name */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5G_stab_create, FAIL)
+ FUNC_ENTER_NOAPI(H5G_stab_create_components, FAIL)
/*
* Check arguments.
*/
HDassert(f);
- HDassert(self);
- init = MAX(init, H5HL_SIZEOF_FREE(f) + 2);
+ HDassert(stab);
+ HDassert(size_hint > 0);
+
+ /* Create the B-tree */
+ if(H5B_create(f, dxpl_id, H5B_SNODE, NULL, &(stab->btree_addr)/*out*/) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree")
/* Create symbol table private heap */
- if (H5HL_create(f, dxpl_id, init, &(stab.heap_addr)/*out*/)<0)
+ if(H5HL_create(f, dxpl_id, size_hint, &(stab->heap_addr)/*out*/) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap")
- name = H5HL_insert(f, dxpl_id, stab.heap_addr, 1, "");
- if ((size_t)(-1)==name)
+ name_offset = H5HL_insert(f, dxpl_id, stab->heap_addr, 1, "");
+ if((size_t)(-1) == name_offset)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap")
/*
* B-tree's won't work if the first name isn't at the beginning
* of the heap.
*/
- assert(0 == name);
+ HDassert(0 == name_offset);
- /* Create the B-tree */
- if (H5B_create(f, dxpl_id, H5B_SNODE, NULL, &(stab.btree_addr)/*out*/) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree")
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_create_components() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_create
+ *
+ * Purpose: Creates a new empty symbol table (object header, name heap,
+ * and B-tree). The caller can specify an initial size for the
+ * name heap. The object header of the group is opened for
+ * write access.
+ *
+ * In order for the B-tree to operate correctly, the first
+ * item in the heap is the empty string, and must appear at
+ * heap offset zero.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 1 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_stab_create(H5O_loc_t *grp_oloc, H5O_stab_t *stab, hid_t dxpl_id)
+{
+ H5O_ginfo_t ginfo; /* Group info message */
+ size_t heap_hint; /* Local heap size hint */
+ size_t size_hint; /* Local heap size hint */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_stab_create, FAIL)
/*
- * Create symbol table object header. It has a zero link count
- * since nothing refers to it yet. The link count will be
- * incremented if the object is added to the group directed graph.
+ * Check arguments.
*/
- if (H5O_create(f, dxpl_id, 4 + 2 * H5F_SIZEOF_ADDR(f), self/*out*/) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create header")
+ HDassert(grp_oloc);
+ HDassert(stab);
+
+ /* Get the group info */
+ if(NULL == H5O_read(grp_oloc, H5O_GINFO_ID, 0, &ginfo, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info")
+
+ /* Adjust the size hint, if necessary */
+ if(ginfo.lheap_size_hint == 0)
+ heap_hint = ginfo.est_num_entries * (ginfo.est_name_len + 1);
+ else
+ heap_hint = ginfo.lheap_size_hint;
+ size_hint = MAX(heap_hint, H5HL_SIZEOF_FREE(grp_oloc->file) + 2);
+
+ if(H5G_stab_create_components(grp_oloc->file, stab, size_hint, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create symbol table components")
/*
* Insert the symbol table message into the object header and the symbol
* table entry.
*/
- if (H5O_modify(self, H5O_STAB_ID, H5O_NEW_MESG, H5O_FLAG_CONSTANT, H5O_UPDATE_TIME, &stab, dxpl_id)<0) {
- H5O_close(self);
+ if(H5O_modify(grp_oloc, H5O_STAB_ID, H5O_NEW_MESG, 0, H5O_UPDATE_TIME, stab, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create message")
- }
- self->cache.stab.btree_addr = stab.btree_addr;
- self->cache.stab.heap_addr = stab.heap_addr;
- self->type = H5G_CACHED_STAB;
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -114,62 +197,47 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5G_stab_find
- *
- * Purpose: Finds a symbol named NAME in the symbol table whose
- * description is stored in GRP_ENT in file F and returns its
- * symbol table entry through OBJ_ENT (which is optional).
+ * Function: H5G_stab_insert_real
*
- * Errors:
+ * Purpose: Insert a new symbol into a table.
+ * The name of the new symbol is NAME and its symbol
+ * table entry is OBJ_LNK.
*
* Return: Non-negative on success/Negative on failure
*
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 1 1997
- *
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added `id to name' support.
- * Added a deep copy of the symbol table entry
+ * Programmer: Quincey Koziol
+ * koziol@uiuc.edu
+ * Nov 7 2005
*
*-------------------------------------------------------------------------
*/
herr_t
-H5G_stab_find(H5G_entry_t *grp_ent, const char *name,
- H5G_entry_t *obj_ent/*out*/, hid_t dxpl_id)
+H5G_stab_insert_real(H5F_t *f, H5O_stab_t *stab, const char *name,
+ H5O_link_t *obj_lnk, hid_t dxpl_id)
{
- H5G_bt_ud1_t udata; /*data to pass through B-tree */
- H5O_stab_t stab; /*symbol table message */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5G_bt_ud1_t udata; /* Data to pass through B-tree */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5G_stab_find, FAIL)
+ FUNC_ENTER_NOAPI(H5G_stab_insert_real, FAIL)
- /* Check arguments */
- assert(grp_ent);
- assert(grp_ent->file);
- assert(obj_ent);
- assert(name && *name);
+ /* check arguments */
+ HDassert(f);
+ HDassert(stab);
+ HDassert(name && *name);
+ HDassert(obj_lnk);
- /* set up the udata */
- if (NULL == H5O_read(grp_ent, H5O_STAB_ID, 0, &stab, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message")
+ /* Initialize data to pass through B-tree */
udata.common.name = name;
- udata.common.heap_addr = stab.heap_addr;
- udata.ent = obj_ent;
-
- /* search the B-tree */
- if (H5B_find(grp_ent->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
+ udata.common.heap_addr = stab->heap_addr;
+ udata.lnk = obj_lnk;
- /* Set the name for the symbol entry OBJ_ENT */
- if (H5G_ent_set_name( grp_ent, obj_ent, name ) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot insert name")
+ /* Insert into symbol table */
+ if(H5B_insert(f, dxpl_id, H5B_SNODE, stab->btree_addr, &udata) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_stab_find() */
+} /* end H5G_stab_insert_real() */
/*-------------------------------------------------------------------------
@@ -188,46 +256,29 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5G_stab_insert(H5G_entry_t *grp_ent, const char *name, H5G_entry_t *obj_ent,
- hbool_t inc_link, hid_t dxpl_id)
+H5G_stab_insert(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *obj_lnk,
+ hid_t dxpl_id)
{
- H5O_stab_t stab; /*symbol table message */
- H5G_bt_ud1_t udata; /*data to pass through B-tree */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5O_stab_t stab; /* Symbol table message */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_stab_insert, FAIL)
/* check arguments */
- assert(grp_ent && grp_ent->file);
- assert(name && *name);
- assert(obj_ent && obj_ent->file);
- if (grp_ent->file->shared != obj_ent->file->shared)
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "interfile hard links are not allowed")
-
- /* Set the name for the symbol entry OBJ_ENT */
- if (H5G_ent_set_name( grp_ent, obj_ent, name ) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot insert name")
+ HDassert(grp_oloc && grp_oloc->file);
+ HDassert(name && *name);
+ HDassert(obj_lnk);
- /* initialize data to pass through B-tree */
- if (NULL == H5O_read(grp_ent, H5O_STAB_ID, 0, &stab, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
+ /* Retrieve symbol table message */
+ if(NULL == H5O_read(grp_oloc, H5O_STAB_ID, 0, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
- udata.common.name = name;
- udata.common.heap_addr = stab.heap_addr;
- udata.ent = obj_ent;
-
- /* insert */
- if (H5B_insert(grp_ent->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINSERT, FAIL, "unable to insert entry")
-
- /* Increment link count on object, if appropriate */
- if(inc_link)
- if (H5O_link(obj_ent, 1, dxpl_id) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_LINK, FAIL, "unable to increment hard link count")
+ if(H5G_stab_insert_real(grp_oloc->file, &stab, name, obj_lnk, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, H5B_ITER_ERROR, "unable to insert the name")
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_insert() */
/*-------------------------------------------------------------------------
@@ -240,36 +291,37 @@ done:
* Programmer: Robb Matzke
* Thursday, September 17, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5G_stab_remove(H5G_entry_t *grp_ent, const char *name, hid_t dxpl_id)
+H5G_stab_remove(H5O_loc_t *loc, const char *name, H5G_obj_t *obj_type, hid_t dxpl_id)
{
H5O_stab_t stab; /*symbol table message */
H5G_bt_ud2_t udata; /*data to pass through B-tree */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI(H5G_stab_remove, FAIL)
- assert(grp_ent && grp_ent->file);
- assert(name && *name);
+ HDassert(loc && loc->file);
+ HDassert(name && *name);
- /* initialize data to pass through B-tree */
- if (NULL==H5O_read(grp_ent, H5O_STAB_ID, 0, &stab, dxpl_id))
- HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
+ /* Read in symbol table message */
+ if(NULL == H5O_read(loc, H5O_STAB_ID, 0, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "not a symbol table")
+
+ /* Initialize data to pass through B-tree */
udata.common.name = name;
udata.common.heap_addr = stab.heap_addr;
udata.adj_link = TRUE;
+ udata.obj_type = obj_type;
- /* remove */
- if (H5B_remove(grp_ent->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry")
+ /* Remove from symbol table */
+ if(H5B_remove(loc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &udata) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to remove entry")
done:
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* end H5G_stab_remove() */
/*-------------------------------------------------------------------------
@@ -318,47 +370,324 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5G_stab_copy_tmp
+ * Function: H5G_stab_iterate
+ *
+ * Purpose: Iterate over the objects in a group
*
- * Purpose: copy a group symbol table and memeber objects from SRC file to DST file.
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, October 3, 2005
*
- * Return: Non-negative on success
- * Negative on failure.
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_stab_iterate(H5O_loc_t *oloc, hid_t gid, int skip, int *last_obj,
+ H5G_iterate_t op, void *op_data, hid_t dxpl_id)
+{
+ H5G_bt_it_ud1_t udata; /* User data to pass to B-tree callback */
+ H5O_stab_t stab; /* Info about symbol table */
+ herr_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5G_stab_iterate, FAIL)
+
+ /* Sanity check */
+ HDassert(oloc);
+ HDassert(H5I_GROUP == H5I_get_type(gid));
+ HDassert(last_obj);
+ HDassert(op);
+
+ /* Get the B-tree info */
+ if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address")
+
+ /* Build udata to pass through H5B_iterate() to H5G_node_iterate() */
+ udata.group_id = gid;
+ udata.skip = skip;
+ udata.heap_addr = stab.heap_addr;
+ udata.op = op;
+ udata.op_data = op_data;
+ udata.final_ent = last_obj;
+
+ /* Iterate over the group members */
+ if((ret_value = H5B_iterate(oloc->file, H5AC_dxpl_id, H5B_SNODE,
+ H5G_node_iterate, stab.btree_addr, &udata))<0)
+ HERROR(H5E_SYM, H5E_CANTNEXT, "iteration operator failed");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_iterate() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_count
*
- * Programmer: Peter Cao
- * September 10, 2005
+ * Purpose: Count the # of objects in a group
*
- * Note: This routine should be replaced with proper call to "real"
- * stab creation routine after the "big group revision" checkin
- * occurs. -QAK
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 6, 2005
*
*-------------------------------------------------------------------------
*/
herr_t
-H5G_stab_copy_tmp(H5F_t *f_dst, H5O_stab_t *stab_dst, hid_t dxpl_id)
+H5G_stab_count(H5O_loc_t *oloc, hsize_t *num_objs, hid_t dxpl_id)
+{
+ H5O_stab_t stab; /* Info about symbol table */
+ herr_t ret_value;
+
+ FUNC_ENTER_NOAPI(H5G_stab_count, FAIL)
+
+ /* Sanity check */
+ HDassert(oloc);
+ HDassert(num_objs);
+
+ /* Reset the number of objects in the group */
+ *num_objs = 0;
+
+ /* Get the B-tree info */
+ if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address")
+
+ /* Iterate over the group members */
+ if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_sumup, stab.btree_addr, num_objs)) < 0)
+ HERROR(H5E_SYM, H5E_CANTINIT, "iteration operator failed");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_count() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_get_name_by_idx
+ *
+ * Purpose: Returns the name of objects in the group by giving index.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Raymond Lu
+ * Nov 20, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+ssize_t
+H5G_stab_get_name_by_idx(H5O_loc_t *oloc, hsize_t idx, char* name,
+ size_t size, hid_t dxpl_id)
+{
+ H5O_stab_t stab; /* Info about local heap & B-tree */
+ H5G_bt_it_ud2_t udata; /* Iteration information */
+ ssize_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_stab_get_name_by_idx, FAIL)
+
+ /* Sanity check */
+ HDassert(oloc);
+
+ /* Get the B-tree & local heap info */
+ if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to determine local heap address")
+
+ /* Set iteration information */
+ udata.idx = idx;
+ udata.num_objs = 0;
+ udata.heap_addr = stab.heap_addr;
+ udata.name = NULL;
+
+ /* Iterate over the group members */
+ if((ret_value = H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_name, stab.btree_addr, &udata))<0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "iteration operator failed")
+
+ /* If we don't know the name now, we almost certainly went out of bounds */
+ if(udata.name==NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "index out of bound")
+
+ /* Get the length of the name */
+ ret_value = (ssize_t)HDstrlen(udata.name);
+
+ /* Copy the name into the user's buffer, if given */
+ if(name) {
+ HDstrncpy(name, udata.name, MIN((size_t)(ret_value+1),size));
+ if((size_t)ret_value >= size)
+ name[size-1]='\0';
+ } /* end if */
+
+done:
+ /* Free the duplicated name */
+ if(udata.name!=NULL)
+ H5MM_xfree(udata.name);
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_get_name_by_idx() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_get_objtype_by_idx
+ *
+ * Purpose: Private function for H5Gget_objtype_by_idx.
+ * Returns the type of objects in the group by giving index.
+ *
+ * Return: Success: H5G_GROUP(1), H5G_DATASET(2), H5G_TYPE(3)
+ *
+ * Failure: UNKNOWN
+ *
+ * Programmer: Raymond Lu
+ * Nov 20, 2002
+ *
+ *-------------------------------------------------------------------------
+ */
+H5G_obj_t
+H5G_stab_get_type_by_idx(H5O_loc_t *oloc, hsize_t idx, hid_t dxpl_id)
+{
+ H5O_stab_t stab; /* Info about local heap & B-tree */
+ H5G_bt_it_ud3_t udata; /* User data for B-tree callback */
+ H5G_obj_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_stab_get_type_by_idx, H5G_UNKNOWN)
+
+ /* Sanity check */
+ HDassert(oloc);
+
+ /* Get the B-tree & local heap info */
+ if(NULL == H5O_read(oloc, H5O_STAB_ID, 0, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, H5G_UNKNOWN, "unable to determine local heap address")
+
+ /* Set iteration information */
+ udata.idx = idx;
+ udata.num_objs = 0;
+ udata.type = H5G_UNKNOWN;
+
+ /* Iterate over the group members */
+ if(H5B_iterate(oloc->file, dxpl_id, H5B_SNODE, H5G_node_type, stab.btree_addr, &udata) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "iteration operator failed")
+
+ /* If we don't know the type now, we almost certainly went out of bounds */
+ if(udata.type == H5G_UNKNOWN)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "index out of bound")
+
+ /* Set the return value */
+ ret_value = udata.type;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_get_type_by_idx() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_lookup_cb
+ *
+ * Purpose: B-tree 'find' callback to retrieve location for an object
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Sep 20, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_stab_lookup_cb(const H5G_entry_t *ent, void *_udata)
{
- size_t size_init, name_offset;
- herr_t ret_value = SUCCEED; /* Return value */
+ H5G_stab_fnd_ud2_t *udata = (H5G_stab_fnd_ud2_t *)_udata; /* 'User data' passed in */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_stab_lookup_cb)
+
+ /* Set link info */
+ if(udata->lnk) {
+ /* Set (default) common info for link */
+ udata->lnk->cset = H5T_CSET_ASCII;
+ udata->lnk->ctime = 0;
+ udata->lnk->name = H5MM_xstrdup(udata->name);
+
+ /* Object is a symbolic link */
+ if(H5G_CACHED_SLINK == ent->type) {
+ const char *s; /* Pointer to link value */
+ const H5HL_t *heap; /* Pointer to local heap for group */
+
+ /* Lock the local heap */
+ if(NULL == (heap = H5HL_protect(udata->file, udata->dxpl_id, udata->heap_addr)))
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read protect link value")
- FUNC_ENTER_NOAPI(H5G_stab_copy_tmp, FAIL)
+ s = H5HL_offset_into(udata->file, heap, ent->cache.slink.lval_offset);
- HDassert(f_dst);
- HDassert(stab_dst);
+ /* Copy the link value */
+ udata->lnk->u.soft.name = H5MM_xstrdup(s);
- /* create B-tree private heap */
- size_init = MAX(H5G_SIZE_HINT, H5HL_SIZEOF_FREE(f_dst) + 2);
- if (H5HL_create(f_dst, dxpl_id, size_init, &(stab_dst->heap_addr))<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create heap")
+ /* Release the local heap */
+ if(H5HL_unprotect(udata->file, udata->dxpl_id, heap, udata->heap_addr, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to read unprotect link value")
- name_offset = H5HL_insert(f_dst, dxpl_id, stab_dst->heap_addr, 1, "");
- if ((size_t)(-1)==name_offset)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't initialize heap")
- assert(0 == name_offset);
-
- /* create the B-tree */
- if (H5B_create(f_dst, dxpl_id, H5B_SNODE, NULL, &(stab_dst->btree_addr)) < 0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "can't create B-tree")
+ /* Set link type */
+ udata->lnk->type = H5G_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;
+ } /* end else */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_stab_lookup_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_stab_lookup
+ *
+ * Purpose: Look up an object relative to a group, using symbol table
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 20 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_stab_lookup(H5O_loc_t *grp_oloc, const char *name, H5O_link_t *lnk,
+ hid_t dxpl_id)
+{
+ H5G_bt_ud3_t bt_udata; /* Data to pass through B-tree */
+ H5G_stab_fnd_ud2_t udata; /* 'User data' to give to callback */
+ H5O_stab_t stab; /* Symbol table message */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_stab_lookup, FAIL)
+
+ /* check arguments */
+ HDassert(grp_oloc && grp_oloc->file);
+ HDassert(name && *name);
+ HDassert(lnk);
+
+ /* Set up user data to pass to 'find' operation callback */
+ udata.file = grp_oloc->file;
+ udata.dxpl_id = dxpl_id;
+ udata.name = name;
+ udata.lnk = lnk;
+
+ /* Set up the user data for actual B-tree find operation */
+ if(NULL == H5O_read(grp_oloc, H5O_STAB_ID, 0, &stab, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't read message")
+ bt_udata.common.name = name;
+ bt_udata.common.heap_addr = stab.heap_addr;
+ bt_udata.op = H5G_stab_lookup_cb;
+ bt_udata.op_data = &udata;
+
+ /* Finish up user data to pass to 'find' operation callback */
+ udata.heap_addr = stab.heap_addr;
+
+ /* Search the B-tree */
+ if(H5B_find(grp_oloc->file, dxpl_id, H5B_SNODE, stab.btree_addr, &bt_udata) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
done:
FUNC_LEAVE_NOAPI(ret_value)
-} /* end H5G_stab_copy_tmp() */
+} /* end H5G_stab_lookup() */
+
diff --git a/src/H5Gtest.c b/src/H5Gtest.c
new file mode 100644
index 0000000..6c7d3ee
--- /dev/null
+++ b/src/H5Gtest.c
@@ -0,0 +1,185 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: Quincey Koziol <koziol@ncsa.uiuc.edu>
+ * Monday, October 17, 2005
+ *
+ * Purpose: Group testing functions.
+ */
+
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+#define H5G_TESTING /*suppress warning about H5G testing funcs*/
+
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Gpkg.h" /* Groups */
+#include "H5Iprivate.h" /* IDs */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5G_is_empty_test
+ PURPOSE
+ Determine whether a group contains no objects
+ USAGE
+ htri_t H5G_is_empty_test(gid)
+ hid_t gid; IN: group to check
+ RETURNS
+ Non-negative TRUE/FALSE on success, negative on failure
+ DESCRIPTION
+ Checks to see if the group has no link messages and no symbol table message
+ dimensionality and shape.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5G_is_empty_test(hid_t gid)
+{
+ H5G_t *grp = NULL; /* Pointer to group */
+ htri_t msg_exists = 0; /* Indicate that a header message is present */
+ htri_t ret_value = TRUE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_is_empty_test, FAIL)
+
+ /* Get group structure */
+ if(NULL == (grp = H5I_object_verify(gid, H5I_GROUP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
+
+ /* Check if the group has any link messages */
+ if((msg_exists = H5O_exists(&(grp->oloc), H5O_LINK_ID, 0, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
+ if(msg_exists > 0)
+ HGOTO_DONE(FALSE)
+
+ /* Check if the group has a symbol table message */
+ if((msg_exists = H5O_exists(&(grp->oloc), H5O_STAB_ID, 0, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
+ if(msg_exists > 0)
+ HGOTO_DONE(FALSE)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5G_is_empty_test() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5G_has_links_test
+ PURPOSE
+ Determine whether a group contains link messages
+ USAGE
+ htri_t H5G_has_links_test(gid)
+ hid_t gid; IN: group to check
+ unsigned *nmsgs; OUT: # of link messages in header
+ RETURNS
+ Non-negative TRUE/FALSE on success, negative on failure
+ DESCRIPTION
+ Checks to see if the group has link messages and how many.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5G_has_links_test(hid_t gid, unsigned *nmsgs)
+{
+ H5G_t *grp = NULL; /* Pointer to group */
+ htri_t msg_exists = 0; /* Indicate that a header message is present */
+ htri_t ret_value = TRUE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_has_links_test, FAIL)
+
+ /* Get group structure */
+ if(NULL == (grp = H5I_object_verify(gid, H5I_GROUP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
+
+ /* Check if the group has any link messages */
+ if((msg_exists = H5O_exists(&(grp->oloc), H5O_LINK_ID, 0, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
+ if(msg_exists == 0)
+ HGOTO_DONE(FALSE)
+
+ /* Check if the group has a symbol table message */
+ if((msg_exists = H5O_exists(&(grp->oloc), H5O_STAB_ID, 0, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
+ if(msg_exists > 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "both symbol table and link messages found")
+
+ /* Check if we should retrieve the number of link messages */
+ if(nmsgs) {
+ int msg_count; /* Number of messages of a type */
+
+ /* Check how many link messages there are */
+ if((msg_count = H5O_count(&(grp->oloc), H5O_LINK_ID, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTCOUNT, FAIL, "unable to count link messages")
+ *nmsgs = (unsigned)msg_count;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5G_has_links_test() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5G_has_stab_test
+ PURPOSE
+ Determine whether a group contains a symbol table message
+ USAGE
+ htri_t H5G_has_stab_test(gid)
+ hid_t gid; IN: group to check
+ RETURNS
+ Non-negative TRUE/FALSE on success, negative on failure
+ DESCRIPTION
+ Checks to see if the group has a symbol table message.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ DO NOT USE THIS FUNCTION FOR ANYTHING EXCEPT TESTING
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5G_has_stab_test(hid_t gid)
+{
+ H5G_t *grp = NULL; /* Pointer to group */
+ htri_t msg_exists = 0; /* Indicate that a header message is present */
+ htri_t ret_value = TRUE; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_has_stab_test, FAIL)
+
+ /* Get group structure */
+ if(NULL == (grp = H5I_object_verify(gid, H5I_GROUP)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
+
+ /* Check if the group has a symbol table message */
+ if((msg_exists = H5O_exists(&(grp->oloc), H5O_STAB_ID, 0, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
+ if(msg_exists == 0)
+ HGOTO_DONE(FALSE)
+
+ /* Check if the group has any link messages */
+ if((msg_exists = H5O_exists(&(grp->oloc), H5O_LINK_ID, 0, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
+ if(msg_exists > 0)
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "both symbol table and link messages found")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5G_has_stab_test() */
+
diff --git a/src/H5Gtraverse.c b/src/H5Gtraverse.c
new file mode 100644
index 0000000..c43ffbb
--- /dev/null
+++ b/src/H5Gtraverse.c
@@ -0,0 +1,589 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Gtraverse.c
+ * Sep 13 2005
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Functions for traversing group hierarchy
+ *
+ *-------------------------------------------------------------------------
+ */
+#define H5F_PACKAGE /*suppress error about including H5Fpkg */
+#define H5G_PACKAGE /*suppress error about including H5Gpkg */
+
+
+/* Packages needed by this file... */
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fpkg.h" /* File access */
+#include "H5Gpkg.h" /* Groups */
+#include "H5HLprivate.h" /* Local Heaps */
+#include "H5MMprivate.h" /* Memory management */
+
+/* Private typedefs */
+
+/* User data for path traversal routine */
+typedef struct {
+ H5G_loc_t *obj_loc; /* Object location */
+} H5G_trav_ud1_t;
+
+/* Private macros */
+
+/* Local variables */
+static char *H5G_comp_g = NULL; /*component buffer */
+static size_t H5G_comp_alloc_g = 0; /*sizeof component buffer */
+
+/* PRIVATE PROTOTYPES */
+static herr_t H5G_traverse_slink_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_traverse_slink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk,
+ H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t dxpl_id);
+static herr_t H5G_traverse_mount(H5G_loc_t *loc/*in,out*/);
+static herr_t H5G_traverse_real(const H5G_loc_t *loc, const char *name,
+ unsigned target, int *nlinks, H5G_traverse_t op, void *op_data,
+ hid_t dxpl_id);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_traverse_term_interface
+ *
+ * Purpose: Terminates part of the H5G interface - free the global
+ * component buffer.
+ *
+ * Return: Success: Non-negative.
+ *
+ * Failure: Negative.
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 26, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_traverse_term_interface(void)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5G_traverse_term_interface)
+
+ /* Free the global component buffer */
+ H5G_comp_g = H5MM_xfree(H5G_comp_g);
+ H5G_comp_alloc_g = 0;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5G_traverse_term_interface() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_traverse_slink_cb
+ *
+ * Purpose: Callback for symbolic link traversal. This routine sets the
+ * correct information for the object location.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, September 13, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_traverse_slink_cb(H5G_loc_t UNUSED *grp_loc, const char UNUSED *name, const H5O_link_t UNUSED *lnk,
+ H5G_loc_t *obj_loc, void *_udata/*in,out*/)
+{
+ H5G_trav_ud1_t *udata = (H5G_trav_ud1_t *)_udata; /* User data passed in */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_slink_cb)
+
+ /* Check for dangling soft link */
+ if(obj_loc == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found")
+
+ /* Copy new location information for resolved object */
+ H5O_loc_copy(udata->obj_loc->oloc, obj_loc->oloc, H5O_COPY_DEEP);
+
+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_traverse_slink_cb() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_traverse_slink
+ *
+ * Purpose: Traverses symbolic link. The link head appears in the group
+ * whose entry is GRP_LOC and the link tail entry is OBJ_LOC.
+ *
+ * Return: Success: Non-negative, OBJ_LOC will contain information
+ * about the object to which the link points and
+ * GRP_LOC will contain the information about
+ * the group in which the link tail appears.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Friday, April 10, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_traverse_slink(H5G_loc_t *grp_loc/*in,out*/, H5O_link_t *lnk,
+ H5G_loc_t *obj_loc/*in,out*/, int *nlinks/*in,out*/, hid_t dxpl_id)
+{
+ H5G_trav_ud1_t udata; /* User data to pass to link traversal callback */
+ H5G_name_t tmp_obj_path; /* Temporary copy of object's path */
+ hbool_t tmp_obj_path_set = FALSE; /* Flag to indicate that tmp object path is initialized */
+ H5O_loc_t tmp_grp_oloc; /* Temporary copy of group entry */
+ H5G_name_t tmp_grp_path; /* Temporary copy of group's path */
+ H5G_loc_t tmp_grp_loc; /* Temporary copy of group's location */
+ hbool_t tmp_grp_path_set = FALSE; /* Flag to indicate that tmp group path is initialized */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_slink)
+
+ /* Sanity check */
+ HDassert(grp_loc);
+ HDassert(lnk);
+ HDassert(lnk->type == H5G_LINK_SOFT);
+ HDassert(nlinks);
+
+ /* Set up temporary location */
+ tmp_grp_loc.oloc = &tmp_grp_oloc;
+ tmp_grp_loc.path = &tmp_grp_path;
+
+ /* Portably initialize the temporary objects */
+ H5G_loc_reset(&tmp_grp_loc);
+
+ /* Clone the group location, so we can track the names properly */
+ /* ("tracking the names properly" means to ignore the effects of the
+ * soft link traversal on the object's & group's paths - QAK)
+ */
+ H5G_loc_copy(&tmp_grp_loc, grp_loc, H5G_COPY_DEEP);
+ tmp_grp_path_set = TRUE;
+
+ /* Hold the object's group hier. path to restore later */
+ /* (Part of "tracking the names properly") */
+ H5G_name_reset(&tmp_obj_path);
+ H5G_name_copy(&tmp_obj_path, obj_loc->path, H5G_COPY_SHALLOW);
+ tmp_obj_path_set = TRUE;
+
+ /* Set up user data for traversal callback */
+ udata.obj_loc = obj_loc;
+
+ /* Traverse to the link's last component */
+ if(H5G_traverse_real(&tmp_grp_loc, lnk->u.soft.name, H5G_TARGET_NORMAL, nlinks, H5G_traverse_slink_cb, &udata, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "unable to follow symbolic link")
+
+done:
+ /* Restore object's group hier. path */
+ if(tmp_obj_path_set) {
+ H5G_name_free(obj_loc->path);
+ H5G_name_copy(obj_loc->path, &tmp_obj_path, H5G_COPY_SHALLOW);
+ } /* end if */
+
+ /* Release cloned copy of group path */
+ if(tmp_grp_path_set)
+ H5G_name_free(&tmp_grp_path);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_traverse_slink() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_traverse_mount
+ *
+ * Purpose: If LNK is a mount point then copy the entry for the root
+ * group of the mounted file into LNK.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, October 6, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_traverse_mount(H5G_loc_t *obj_loc/*in,out*/)
+{
+ H5F_t *parent = obj_loc->oloc->file; /* File of object */
+ unsigned lt, rt, md = 0; /* Binary search indices */
+ int cmp;
+ H5O_loc_t *oloc = NULL; /* Object location for mount points */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_traverse_mount, FAIL)
+
+ /* Sanity check */
+ HDassert(obj_loc);
+
+ /*
+ * The loop is necessary because we might have file1 mounted at the root
+ * of file2, which is mounted somewhere in file3.
+ */
+ do {
+ /*
+ * Use a binary search to find the potential mount point in the mount
+ * table for the parent
+ */
+ lt = 0;
+ rt = parent->mtab.nmounts;
+ cmp = -1;
+ while(lt < rt && cmp) {
+ md = (lt + rt) / 2;
+ oloc = H5G_oloc(parent->mtab.child[md].group);
+ cmp = H5F_addr_cmp(obj_loc->oloc->addr, oloc->addr);
+ if(cmp < 0)
+ rt = md;
+ else
+ lt = md + 1;
+ } /* end while */
+
+ /* Copy root info over to ENT */
+ if(0 == cmp) {
+ H5G_name_t *root_path; /* Path of root group */
+
+ /* Get the location for the root group in the child's file */
+ oloc = H5G_oloc(parent->mtab.child[md].file->shared->root_grp);
+ root_path = H5G_nameof(parent->mtab.child[md].file->shared->root_grp);
+
+ /* Copy the entry for the root group */
+ if(H5O_loc_copy(obj_loc->oloc, oloc, H5O_COPY_DEEP) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object location")
+
+ /* Don't lose the user path of the group when we copy the root group's path */
+ if(H5G_name_copy(obj_loc->path, root_path, H5G_COPY_CANON) < 0)
+ HGOTO_ERROR(H5E_FILE, H5E_CANTCOPY, FAIL, "unable to copy object path")
+
+ /* Switch to child's file */
+ parent = oloc->file;
+ } /* end if */
+ } while(!cmp);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_traverse_mount() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_traverse_real
+ *
+ * Purpose: Internal version of path traversal routine
+ *
+ * Return: Success: Non-negative if name can be fully resolved.
+ *
+ * Failure: Negative if the name could not be fully
+ * resolved.
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 11 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5G_traverse_real(const H5G_loc_t *_loc, const char *name, unsigned target,
+ int *nlinks, H5G_traverse_t op, void *op_data, hid_t dxpl_id)
+{
+ H5G_loc_t loc; /* Location of start object */
+ H5O_loc_t grp_oloc; /* Object loc. for current group */
+ H5G_name_t grp_path; /* Path for current group */
+ H5G_loc_t grp_loc; /* Location of group */
+ H5O_loc_t obj_oloc; /* Object found */
+ H5G_name_t obj_path; /* Path for object found */
+ H5G_loc_t obj_loc; /* Location of object */
+ size_t nchars; /* component name length */
+ H5O_link_t lnk; /* Link information for object */
+ hbool_t link_valid = FALSE; /* Flag to indicate that the link information is valid */
+ hbool_t obj_loc_valid = FALSE; /* Flag to indicate that the object location is valid */
+ hbool_t group_copy = FALSE; /* Flag to indicate that the group entry is copied */
+ hbool_t last_comp = FALSE; /* Flag to indicate that a component is the last component in the name */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5G_traverse_real)
+
+ /* Check parameters */
+ HDassert(_loc);
+ HDassert(name);
+ HDassert(nlinks);
+ HDassert(op);
+
+ /*
+ * Where does the searching start? For absolute names it starts at the
+ * root of the file; for relative names it starts at CWG.
+ */
+ /* Check if we need to get the root group's entry */
+ if('/' == *name) {
+ H5G_t *root_grp; /* Temporary pointer to root group of file */
+
+ /* Look up root group for starting location */
+ root_grp = H5G_rootof(_loc->oloc->file);
+ HDassert(root_grp);
+
+ /* Set the location entry to the root group's info */
+ loc.oloc=&(root_grp->oloc);
+ loc.path=&(root_grp->path);
+ } /* end if */
+ else {
+ loc.oloc = _loc->oloc;
+ loc.path = _loc->path;
+ } /* end else */
+
+ /* Set up group & object locations */
+ grp_loc.oloc = &grp_oloc;
+ grp_loc.path = &grp_path;
+ obj_loc.oloc = &obj_oloc;
+ obj_loc.path = &obj_path;
+
+ /* Deep copy of the starting location to group location */
+ if(H5G_loc_copy(&grp_loc, &loc, H5G_COPY_DEEP) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to copy location")
+ group_copy = TRUE;
+
+ /* Clear object location */
+ if(H5G_loc_reset(&obj_loc) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to reset location")
+
+ /* Check for needing a larger buffer for the individual path name components */
+ if(HDstrlen(name) + 1 > H5G_comp_alloc_g) {
+ H5G_comp_alloc_g = MAX3(1024, 2 * H5G_comp_alloc_g, HDstrlen(name) + 1);
+ H5G_comp_g = H5MM_realloc(H5G_comp_g, H5G_comp_alloc_g);
+ if(!H5G_comp_g) {
+ H5G_comp_alloc_g = 0;
+ HGOTO_ERROR(H5E_SYM, H5E_NOSPACE, FAIL, "unable to allocate component buffer")
+ } /* end if */
+ } /* end if */
+
+ /* Traverse the path */
+ while((name = H5G_component(name, &nchars)) && *name) {
+ const char *s; /* Temporary string pointer */
+ herr_t lookup_status; /* Status from object lookup */
+
+ /*
+ * Copy the component name into a null-terminated buffer so
+ * we can pass it down to the other symbol table functions.
+ */
+ HDmemcpy(H5G_comp_g, name, nchars);
+ H5G_comp_g[nchars] = '\0';
+
+ /*
+ * The special name `.' is a no-op.
+ */
+ if('.' == H5G_comp_g[0] && !H5G_comp_g[1]) {
+ name += nchars;
+ continue;
+ } /* end if */
+
+ /* Check if this is the last component of the name */
+ if(!((s = H5G_component(name + nchars, NULL)) && *s))
+ last_comp = TRUE;
+
+ /* If there's valid information in the link, reset it */
+ if(link_valid) {
+ H5O_reset(H5O_LINK_ID, &lnk);
+ link_valid = FALSE;
+ } /* end if */
+
+ /* Get information for object in current group */
+ /* (Defer issuing error for back lookup until later) */
+ lookup_status = H5G_obj_lookup(grp_loc.oloc, H5G_comp_g, &lnk/*out*/, dxpl_id);
+
+ /* If the lookup was OK, try traversing soft links and mount points, if allowed */
+ if(lookup_status >= 0) {
+ /* Indicate that the link info is valid */
+ link_valid = TRUE;
+
+ /* Build object's group hier. location */
+ if(H5G_name_set(grp_loc.path, obj_loc.path, H5G_comp_g) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "cannot set name")
+
+ /* 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) {
+ obj_loc.oloc->addr = lnk.u.hard.addr;
+ } /* end if */
+ obj_loc_valid = TRUE;
+
+ /*
+ * If we found a symbolic link then we should follow it. But if this
+ * 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 &&
+ (0 == (target & H5G_TARGET_SLINK) || !last_comp)) {
+ if((*nlinks)-- <= 0)
+ HGOTO_ERROR(H5E_SYM, H5E_SLINK, FAIL, "too many links")
+ if(H5G_traverse_slink(&grp_loc/*in,out*/, &lnk/*in*/, &obj_loc, nlinks, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "symbolic link traversal failed")
+ } /* end if */
+
+ /*
+ * Resolve mount points to the mounted group. Do not do this step if
+ * the H5G_TARGET_MOUNT bit of TARGET is set and this is the last
+ * component of the name.
+ *
+ * (If this link is a hard link, try to perform mount point traversal)
+ *
+ * (Note that the soft link traversal above can change the status of
+ * the object (into a hard link), so don't use an 'else' statement
+ * here. -QAK)
+ */
+ if(H5F_addr_defined(obj_loc.oloc->addr) &&
+ (0 == (target & H5G_TARGET_MOUNT) || !last_comp)) {
+ if(H5G_traverse_mount(&obj_loc/*in,out*/) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "mount point traversal failed")
+ } /* end if */
+ } /* end if */
+
+ /* Check for last component in name provided */
+ if(last_comp) {
+ H5O_link_t *tmp_lnk; /* Pointer to link info for callback */
+ H5G_loc_t *tmp_loc; /* Pointer to object location for callback */
+
+ /* Set callback parameters appropriately, based on link being found */
+ if(lookup_status < 0) {
+ tmp_lnk = NULL;
+ tmp_loc = NULL;
+ } /* end if */
+ else {
+ tmp_lnk = &lnk;
+ tmp_loc = &obj_loc;
+ } /* end else */
+
+ /* Operator routine will take care of object location, succeed or fail */
+ obj_loc_valid = FALSE;
+
+ /* Call 'operator' routine */
+ if((op)(&grp_loc, H5G_comp_g, tmp_lnk, tmp_loc, op_data) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CALLBACK, FAIL, "traversal operator failed")
+ HGOTO_DONE(SUCCEED)
+ } /* end if */
+
+ /* Handle lookup failures now */
+ if(lookup_status < 0) {
+ /* If an intermediate group doesn't exist & flag is set, create the group */
+ if(target & H5G_CRT_INTMD_GROUP) {
+ H5O_ginfo_t ginfo; /* Group info message for parent group */
+
+ /* Get the group info for parent group */
+ if(NULL == H5O_read(grp_loc.oloc, H5O_GINFO_ID, 0, &ginfo, dxpl_id))
+ HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info")
+
+ /* Create the intermediate group */
+/* XXX: Should we allow user to control the group creation params here? -QAK */
+ if(H5G_obj_create(grp_oloc.file, dxpl_id, &ginfo, obj_loc.oloc/*out*/) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group entry")
+
+ /* 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")
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "component not found")
+ } /* end if */
+
+ /*
+ * Advance to the next component of the path.
+ */
+
+ /* Transfer "ownership" of the object's information to the group object */
+ H5G_loc_free(&grp_loc);
+ H5G_loc_copy(&grp_loc, &obj_loc, H5G_COPY_SHALLOW);
+ H5G_loc_reset(&obj_loc);
+ obj_loc_valid = FALSE;
+
+ /* Advance to next component in string */
+ name += nchars;
+ } /* end while */
+
+ /* If we've fallen through to here, the name must be something like just '.'
+ * and we should issue the callback on that. -QAK
+ */
+ /* Reset "group copied" flag */
+ /* (callback will take ownership of group location, succeed or fail) */
+ HDassert(group_copy);
+ group_copy = FALSE;
+
+ /* Call 'operator' routine */
+ if((op)(&grp_loc, ".", NULL, &grp_loc, op_data) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTNEXT, FAIL, "traversal operator failed")
+ HGOTO_DONE(SUCCEED)
+
+done:
+ /* If the object location is still valid (usually in an error situation), reset it */
+ if(obj_loc_valid)
+ H5G_loc_free(&obj_loc);
+ /* If there's valid information in the link, reset it */
+ if(link_valid)
+ H5O_reset(H5O_LINK_ID, &lnk);
+ /* If we copied something into the group location, free it */
+ if(group_copy)
+ H5G_loc_free(&grp_loc);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_traverse_real() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_traverse
+ *
+ * Purpose: Traverse a path from a location & perform an operation when
+ * the last component of the name is reached.
+ *
+ * Return: Success: Non-negative if path can be fully traversed.
+ * Failure: Negative if the path could not be fully
+ * traversed.
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Sep 13 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_traverse(const H5G_loc_t *loc, const char *name, unsigned target, H5G_traverse_t op,
+ void *op_data, hid_t dxpl_id)
+{
+ int nlinks = H5G_NLINKS; /* Link countdown value */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5G_traverse, FAIL)
+
+ /* Check args */
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "no name given")
+ if(!loc)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "no starting location")
+ if(!op)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "no operation provided")
+
+ /* Go perform "real" traversal */
+ if(H5G_traverse_real(loc, name, target, &nlinks, op, op_data, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "path traversal failed")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5G_traverse() */
+
diff --git a/src/H5HL.c b/src/H5HL.c
index 9de9f5b..e86be3d 100644
--- a/src/H5HL.c
+++ b/src/H5HL.c
@@ -153,8 +153,7 @@ H5HL_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, haddr_t *addr_p/*out*/)
if (NULL==(heap = H5FL_CALLOC(H5HL_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
heap->addr = *addr_p + (hsize_t)sizeof_hdr;
- heap->disk_alloc = size_hint;
- heap->mem_alloc = size_hint;
+ heap->heap_alloc = size_hint;
if (NULL==(heap->chunk = H5FL_BLK_CALLOC(heap_chunk,(sizeof_hdr + size_hint))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
@@ -254,25 +253,24 @@ H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
/* heap data size */
- H5F_DECODE_LENGTH(f, p, heap->disk_alloc);
- heap->mem_alloc = heap->disk_alloc;
+ H5F_DECODE_LENGTH(f, p, heap->heap_alloc);
/* free list head */
H5F_DECODE_LENGTH(f, p, free_block);
- if (free_block != H5HL_FREE_NULL && free_block >= heap->disk_alloc)
+ if (free_block != H5HL_FREE_NULL && free_block >= heap->heap_alloc)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list");
/* data */
H5F_addr_decode(f, &p, &(heap->addr));
- if (NULL==(heap->chunk = H5FL_BLK_CALLOC(heap_chunk,(sizeof_hdr + heap->mem_alloc))))
+ if (NULL==(heap->chunk = H5FL_BLK_CALLOC(heap_chunk,(sizeof_hdr + heap->heap_alloc))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if (heap->disk_alloc &&
- H5F_block_read(f, H5FD_MEM_LHEAP, heap->addr, heap->disk_alloc, dxpl_id, heap->chunk + sizeof_hdr) < 0)
+ if (heap->heap_alloc &&
+ H5F_block_read(f, H5FD_MEM_LHEAP, heap->addr, heap->heap_alloc, dxpl_id, heap->chunk + sizeof_hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to read heap data");
/* Build free list */
while (H5HL_FREE_NULL != free_block) {
- if (free_block >= heap->disk_alloc)
+ if (free_block >= heap->heap_alloc)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list");
if (NULL==(fl = H5FL_MALLOC(H5HL_free_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
@@ -287,7 +285,7 @@ H5HL_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * udata1,
H5F_DECODE_LENGTH(f, p, free_block);
H5F_DECODE_LENGTH(f, p, fl->size);
- if (fl->offset + fl->size > heap->disk_alloc)
+ if (fl->offset + fl->size > heap->heap_alloc)
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "bad heap free list");
}
@@ -324,7 +322,7 @@ done:
*
* It used to be called during cache eviction, where it
* attempted to size the disk space allocation for the
- * actuall size of the heap. However, this causes problems
+ * actual size of the heap. However, this causes problems
* in the parallel case, as the reuslting disk allocations
* may not be synchronized.
*
@@ -338,15 +336,15 @@ done:
static herr_t
H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap)
{
- herr_t ret_value = SUCCEED;
- size_t sizeof_hdr;
+ size_t new_heap_size = heap->heap_alloc; /* New size of heap */
+ size_t sizeof_hdr;
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5HL_minimize_heap_space, FAIL)
/* check args */
HDassert( f );
HDassert( heap );
- HDassert( heap->disk_alloc == heap->mem_alloc );
sizeof_hdr = H5HL_SIZEOF_HDR(f); /* cache H5HL header size for file */
@@ -355,14 +353,14 @@ H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap)
* eliminating free blocks at the tail of the buffer before flushing the
* buffer out.
*/
- if (heap->freelist) {
+ if(heap->freelist) {
H5HL_free_t *tmp_fl;
H5HL_free_t *last_fl = NULL;
/* Search for a free block at the end of the buffer */
for (tmp_fl = heap->freelist; tmp_fl; tmp_fl = tmp_fl->next)
/* Check if the end of this free block is at the end of the buffer */
- if (tmp_fl->offset + tmp_fl->size == heap->mem_alloc) {
+ if (tmp_fl->offset + tmp_fl->size == heap->heap_alloc) {
last_fl = tmp_fl;
break;
}
@@ -371,98 +369,90 @@ H5HL_minimize_heap_space(H5F_t *f, hid_t dxpl_id, H5HL_t *heap)
* Found free block at the end of the buffer, decide what to do
* about it
*/
- if (last_fl) {
- size_t new_mem_size = heap->mem_alloc; /* New size of memory buffer */
-
+ if(last_fl) {
/*
* If the last free block's size is more than half the memory
* buffer size (and the memory buffer is larger than the
* minimum size), reduce or eliminate it.
*/
- if (last_fl->size >= (heap->mem_alloc / 2) && heap->mem_alloc > H5HL_MIN_HEAP) {
+ if(last_fl->size >= (heap->heap_alloc / 2) && heap->heap_alloc > H5HL_MIN_HEAP) {
/*
* Reduce size of buffer until it's too small or would
* eliminate the free block
*/
- while (new_mem_size > H5HL_MIN_HEAP &&
- new_mem_size >= (last_fl->offset + H5HL_SIZEOF_FREE(f)))
- new_mem_size /= 2;
+ while(new_heap_size > H5HL_MIN_HEAP &&
+ new_heap_size >= (last_fl->offset + H5HL_SIZEOF_FREE(f)))
+ new_heap_size /= 2;
/*
* Check if reducing the memory buffer size would
- * eliminate the free list
+ * eliminate the free block
*/
- if (new_mem_size < (last_fl->offset + H5HL_SIZEOF_FREE(f))) {
+ if(new_heap_size < (last_fl->offset + H5HL_SIZEOF_FREE(f))) {
/* Check if this is the only block on the free list */
- if (last_fl->prev == NULL && last_fl->next == NULL) {
+ if(last_fl->prev == NULL && last_fl->next == NULL) {
/* Double the new memory size */
- new_mem_size *= 2;
+ new_heap_size *= 2;
/* Truncate the free block */
- last_fl->size = H5HL_ALIGN(new_mem_size - last_fl->offset);
- new_mem_size = last_fl->offset + last_fl->size;
+ last_fl->size = H5HL_ALIGN(new_heap_size - last_fl->offset);
+ new_heap_size = last_fl->offset + last_fl->size;
assert(last_fl->size >= H5HL_SIZEOF_FREE(f));
} else {
/*
* Set the size of the memory buffer to the start
* of the free list
*/
- new_mem_size = last_fl->offset;
+ new_heap_size = last_fl->offset;
/* Eliminate the free block from the list */
last_fl = H5HL_remove_free(heap, last_fl);
- }
+ } /* end else */
} else {
/* Truncate the free block */
- last_fl->size = H5HL_ALIGN(new_mem_size - last_fl->offset);
- new_mem_size = last_fl->offset + last_fl->size;
+ last_fl->size = H5HL_ALIGN(new_heap_size - last_fl->offset);
+ new_heap_size = last_fl->offset + last_fl->size;
assert(last_fl->size >= H5HL_SIZEOF_FREE(f));
assert(last_fl->size == H5HL_ALIGN(last_fl->size));
- }
-
- /* Resize the memory buffer and reserved space in file */
- if (new_mem_size != heap->mem_alloc) {
-
- heap->mem_alloc = new_mem_size;
- heap->chunk = H5FL_BLK_REALLOC(heap_chunk, heap->chunk, (sizeof_hdr + new_mem_size));
-
- if (!heap->chunk)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- }
- }
- }
- }
+ } /* end else */
+ } /* end if */
+ } /* end if */
+ } /* end if */
/*
* If the heap grew smaller than disk storage then move the
* data segment of the heap to another contiguous block of disk
* storage.
*/
- if (heap->mem_alloc != heap->disk_alloc) {
- haddr_t old_addr = heap->addr, new_addr;
+ if(new_heap_size != heap->heap_alloc) {
+ haddr_t old_addr = heap->addr,
+ new_addr;
+
+ HDassert(new_heap_size < heap->heap_alloc);
- HDassert( heap->mem_alloc < heap->disk_alloc );
+ /* Resize the memory buffer */
+ heap->chunk = H5FL_BLK_REALLOC(heap_chunk, heap->chunk, (sizeof_hdr + new_heap_size));
+ if(!heap->chunk)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Release old space on disk */
- H5_CHECK_OVERFLOW(heap->disk_alloc, size_t, hsize_t);
- H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr, (hsize_t)heap->disk_alloc);
+ /* (Should be safe to free old heap space first, since it's shrinking -QAK) */
+ H5_CHECK_OVERFLOW(heap->heap_alloc, size_t, hsize_t);
+ H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr, (hsize_t)heap->heap_alloc);
H5E_clear_stack(NULL); /* don't really care if the free failed */
/* Allocate new space on disk */
- H5_CHECK_OVERFLOW(heap->mem_alloc, size_t, hsize_t);
-
- if (HADDR_UNDEF == (new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, (hsize_t)heap->mem_alloc)))
+ H5_CHECK_OVERFLOW(new_heap_size, size_t, hsize_t);
+ if(HADDR_UNDEF == (new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, (hsize_t)new_heap_size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "unable to allocate file space for heap")
+ /* Update heap info*/
heap->addr = new_addr;
-
- /* Set new size of block on disk */
- heap->disk_alloc = heap->mem_alloc;
- }
+ heap->heap_alloc = new_heap_size;
+ } /* end if */
done:
FUNC_LEAVE_NOAPI(ret_value)
-
} /* H5HL_minimize_heap_space() */
@@ -506,7 +496,7 @@ H5HL_serialize(H5F_t *f, H5HL_t *heap, uint8_t *buf)
*p++ = 0; /*reserved*/
*p++ = 0; /*reserved*/
*p++ = 0; /*reserved*/
- H5F_ENCODE_LENGTH(f, p, heap->mem_alloc);
+ H5F_ENCODE_LENGTH(f, p, heap->heap_alloc);
H5F_ENCODE_LENGTH(f, p, fl ? fl->offset : H5HL_FREE_NULL);
H5F_addr_encode(f, &p, heap->addr);
@@ -573,7 +563,6 @@ H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HL_t *heap)
HDassert( f );
HDassert( H5F_addr_defined(addr) );
HDassert( heap );
- HDassert( heap->disk_alloc == heap->mem_alloc );
if (heap->cache_info.is_dirty) {
haddr_t hdr_end_addr;
@@ -588,14 +577,14 @@ H5HL_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5HL_t *heap)
if (H5F_addr_eq(heap->addr, hdr_end_addr)) {
/* The header and data are contiguous */
- if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, (sizeof_hdr + heap->disk_alloc),
+ if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, (sizeof_hdr + heap->heap_alloc),
dxpl_id, heap->chunk) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header and data to file")
} else {
if (H5F_block_write(f, H5FD_MEM_LHEAP, addr, sizeof_hdr, dxpl_id, heap->chunk) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap header to file")
- if (H5F_block_write(f, H5FD_MEM_LHEAP, heap->addr, heap->disk_alloc,
+ if (H5F_block_write(f, H5FD_MEM_LHEAP, heap->addr, heap->heap_alloc,
dxpl_id, heap->chunk + sizeof_hdr) < 0)
HGOTO_ERROR(H5E_HEAP, H5E_WRITEERROR, FAIL, "unable to write heap data to file")
}
@@ -717,7 +706,7 @@ H5HL_compute_size(const H5F_t *f, const H5HL_t *heap, size_t *size_ptr)
HDassert(heap);
HDassert(size_ptr);
- *size_ptr = H5HL_SIZEOF_HDR(f) + heap->disk_alloc;
+ *size_ptr = H5HL_SIZEOF_HDR(f) + heap->heap_alloc;
FUNC_LEAVE_NOAPI(SUCCEED)
} /* H5HL_compute_size() */
@@ -766,8 +755,8 @@ H5HL_read(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size, voi
if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, NULL, "unable to load heap");
- assert(offset < heap->mem_alloc);
- assert(offset + size <= heap->mem_alloc);
+ assert(offset < heap->heap_alloc);
+ assert(offset + size <= heap->heap_alloc);
if (!buf && NULL==(buf = H5MM_malloc(size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
@@ -864,7 +853,7 @@ H5HL_offset_into(H5F_t *f, const H5HL_t *heap, size_t offset)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5HL_offset_into)
assert(f);
assert(heap);
- assert(offset < heap->mem_alloc);
+ assert(offset < heap->heap_alloc);
FUNC_LEAVE_NOAPI(heap->chunk + H5HL_SIZEOF_HDR(f) + offset)
}
@@ -976,12 +965,9 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *
{
H5HL_t *heap = NULL;
unsigned heap_flags = H5AC__NO_FLAGS_SET;
- H5HL_free_t *fl = NULL, *max_fl = NULL;
- htri_t tri_result;
- herr_t result;
+ H5HL_free_t *fl = NULL, *last_fl = NULL;
size_t offset = 0;
- size_t need_size, old_size, need_more;
- size_t new_disk_alloc;
+ size_t need_size;
hbool_t found;
size_t sizeof_hdr; /* Cache H5HL header size for file */
size_t ret_value; /* Return value */
@@ -989,10 +975,10 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *
FUNC_ENTER_NOAPI(H5HL_insert, (size_t)(-1));
/* check arguments */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(buf_size > 0);
- assert(buf);
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(buf_size > 0);
+ HDassert(buf);
if (0==(f->intent & H5F_ACC_RDWR))
HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, (size_t)(-1), "no write intent on file");
@@ -1016,28 +1002,28 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *
* Look for a free slot large enough for this object and which would
* leave zero or at least H5G_SIZEOF_FREE bytes left over.
*/
- for (fl=heap->freelist, found=FALSE; fl; fl=fl->next) {
- if (fl->size > need_size &&
- fl->size - need_size >= H5HL_SIZEOF_FREE(f)) {
- /* a bigger free block was found */
+ for(fl = heap->freelist, found = FALSE; fl; fl = fl->next) {
+ if(fl->size > need_size &&
+ fl->size - need_size >= H5HL_SIZEOF_FREE(f)) {
+ /* a big enough free block was found */
offset = fl->offset;
fl->offset += need_size;
fl->size -= need_size;
- assert (fl->offset==H5HL_ALIGN (fl->offset));
- assert (fl->size==H5HL_ALIGN (fl->size));
+ HDassert(fl->offset == H5HL_ALIGN(fl->offset));
+ HDassert(fl->size == H5HL_ALIGN(fl->size));
found = TRUE;
break;
- } else if (fl->size == need_size) {
+ } else if(fl->size == need_size) {
/* free block of exact size found */
offset = fl->offset;
fl = H5HL_remove_free(heap, fl);
found = TRUE;
break;
- } else if (!max_fl || max_fl->offset < fl->offset) {
- /* use worst fit */
- max_fl = fl;
+ } else if(!last_fl || last_fl->offset < fl->offset) {
+ /* track free space that's closest to end of heap */
+ last_fl = fl;
}
- }
+ } /* end for */
/*
* If no free chunk was large enough, then allocate more space and
@@ -1045,34 +1031,41 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *
* can extend that free chunk. Otherwise we'll have to make another
* free chunk. If the heap must expand, we double its size.
*/
- if (found==FALSE) {
- need_more = MAX3(need_size, heap->mem_alloc, H5HL_SIZEOF_FREE(f));
-
- new_disk_alloc = heap->disk_alloc + need_more;
- HDassert( heap->disk_alloc < new_disk_alloc );
- H5_CHECK_OVERFLOW(heap->disk_alloc, size_t, hsize_t);
- H5_CHECK_OVERFLOW(new_disk_alloc, size_t, hsize_t);
-
- /* extend the current heap if we can... */
- tri_result = H5MF_can_extend(f, H5FD_MEM_LHEAP, heap->addr,
- (hsize_t)(heap->disk_alloc),
- (hsize_t)need_more);
- if ( tri_result == TRUE ) {
-
- result = H5MF_extend(f, H5FD_MEM_LHEAP, heap->addr,
- (hsize_t)(heap->disk_alloc),
- (hsize_t)need_more);
- if ( result < 0 ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), \
- "can't extend heap on disk");
- }
+ if(found == FALSE) {
+ size_t need_more; /* How much more space we need */
+ size_t new_heap_alloc; /* Final size of space allocated for heap */
+ htri_t can_extend; /* Whether the local heap's data segment on disk can be extended */
+
+ /* At least double the heap's size, making certain there's enough room
+ * for the new object */
+ need_more = MAX(need_size, heap->heap_alloc);
+
+ /* If there is no last free block or it's not at the end of the heap,
+ * and the amount of space to allocate is not big enough to include at
+ * least the new object and a free-list info, trim down the amount of
+ * space requested to just the amount of space needed. (Generally
+ * speaking, this only occurs when the heap is small -QAK)
+ */
+ if(!(last_fl && last_fl->offset + last_fl->size == heap->heap_alloc)
+ && (need_more < (need_size + H5HL_SIZEOF_FREE(f))))
+ need_more = need_size;
- heap->disk_alloc = new_disk_alloc;
+ new_heap_alloc = heap->heap_alloc + need_more;
+ HDassert(heap->heap_alloc < new_heap_alloc);
+ H5_CHECK_OVERFLOW(heap->heap_alloc, size_t, hsize_t);
+ H5_CHECK_OVERFLOW(new_heap_alloc, size_t, hsize_t);
- } else { /* ...if we can't, allocate a new chunk & release the old */
+ /* Check if current heap is extendible */
+ can_extend = H5MF_can_extend(f, H5FD_MEM_LHEAP, heap->addr, (hsize_t)(heap->heap_alloc), (hsize_t)need_more);
+ if(can_extend < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "unable to check whether heap can be extended")
- haddr_t old_addr = heap->addr;
+ /* extend the current heap if we can... */
+ if(can_extend == TRUE) {
+ if(H5MF_extend(f, H5FD_MEM_LHEAP, heap->addr, (hsize_t)(heap->heap_alloc), (hsize_t)need_more) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "can't extend heap on disk")
+ } /* end if */
+ else { /* ...if we can't, allocate a new chunk & release the old */
haddr_t new_addr;
/* The new allocation may fail -- to avoid the possiblity of
@@ -1081,54 +1074,50 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *
*/
/* allocate new disk space for the heap */
- if ( (new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id,
- (hsize_t)new_disk_alloc)) == HADDR_UNDEF ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), \
- "unable to allocate file space for heap")
- }
+ if((new_addr = H5MF_alloc(f, H5FD_MEM_LHEAP, dxpl_id, (hsize_t)new_heap_alloc)) == HADDR_UNDEF)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "unable to allocate file space for heap")
/* Release old space on disk */
- H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, old_addr,
- (hsize_t)heap->disk_alloc);
+ H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, heap->addr, (hsize_t)heap->heap_alloc);
H5E_clear_stack(NULL); /* don't really care if the free failed */
heap->addr = new_addr;
- heap->disk_alloc = new_disk_alloc;
- }
+ } /* end else */
- if (max_fl && max_fl->offset + max_fl->size == heap->mem_alloc) {
+ /* If the last free list in the heap is at the end of the heap, extend it */
+ if(last_fl && last_fl->offset + last_fl->size == heap->heap_alloc) {
/*
- * Increase the size of the maximum free block.
+ * Increase the size of the last free block.
*/
- offset = max_fl->offset;
- max_fl->offset += need_size;
- max_fl->size += need_more - need_size;
- assert (max_fl->offset==H5HL_ALIGN (max_fl->offset));
- assert (max_fl->size==H5HL_ALIGN (max_fl->size));
+ offset = last_fl->offset;
+ last_fl->offset += need_size;
+ last_fl->size += need_more - need_size;
+ HDassert(last_fl->offset == H5HL_ALIGN(last_fl->offset));
+ HDassert(last_fl->size == H5HL_ALIGN(last_fl->size));
- if (max_fl->size < H5HL_SIZEOF_FREE(f)) {
+ if (last_fl->size < H5HL_SIZEOF_FREE(f)) {
#ifdef H5HL_DEBUG
- if (H5DEBUG(HL) && max_fl->size) {
+ if (H5DEBUG(HL) && last_fl->size) {
fprintf(H5DEBUG(HL), "H5HL: lost %lu bytes at line %d\n",
- (unsigned long)(max_fl->size), __LINE__);
+ (unsigned long)(last_fl->size), __LINE__);
}
#endif
- max_fl = H5HL_remove_free(heap, max_fl);
+ last_fl = H5HL_remove_free(heap, last_fl);
}
- } else {
+ } /* end if */
+ else {
/*
* Create a new free list element large enough that we can
* take some space out of it right away.
*/
- offset = heap->mem_alloc;
- if (need_more - need_size >= H5HL_SIZEOF_FREE(f)) {
- if (NULL==(fl = H5FL_MALLOC(H5HL_free_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "memory allocation failed");
- fl->offset = heap->mem_alloc + need_size;
+ offset = heap->heap_alloc;
+ if(need_more - need_size >= H5HL_SIZEOF_FREE(f)) {
+ if(NULL == (fl = H5FL_MALLOC(H5HL_free_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "memory allocation failed")
+ fl->offset = heap->heap_alloc + need_size;
fl->size = need_more - need_size;
- assert (fl->offset==H5HL_ALIGN (fl->offset));
- assert (fl->size==H5HL_ALIGN (fl->size));
+ HDassert(fl->offset == H5HL_ALIGN(fl->offset));
+ HDassert(fl->size == H5HL_ALIGN(fl->size));
fl->prev = NULL;
fl->next = heap->freelist;
if (heap->freelist) heap->freelist->prev = fl;
@@ -1140,40 +1129,39 @@ H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t buf_size, const void *
(unsigned long)(need_more - need_size), __LINE__);
#endif
}
- }
+ } /* end else */
#ifdef H5HL_DEBUG
if (H5DEBUG(HL)) {
fprintf(H5DEBUG(HL),
"H5HL: resize mem buf from %lu to %lu bytes\n",
- (unsigned long)(heap->mem_alloc),
- (unsigned long)(heap->mem_alloc + need_more));
+ (unsigned long)(heap->heap_alloc),
+ (unsigned long)(heap->heap_alloc + need_more));
}
#endif
- old_size = heap->mem_alloc;
- heap->mem_alloc += need_more;
- heap->chunk = H5FL_BLK_REALLOC(heap_chunk,heap->chunk,
- (sizeof_hdr + heap->mem_alloc));
- if (NULL==heap->chunk)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "memory allocation failed");
-
- /* clear new section so junk doesn't appear in the file */
- HDmemset(heap->chunk + sizeof_hdr + old_size, 0, need_more);
- }
+ heap->heap_alloc = new_heap_alloc;
+ heap->chunk = H5FL_BLK_REALLOC(heap_chunk, heap->chunk, (sizeof_hdr + heap->heap_alloc));
+ if(NULL == heap->chunk)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, (size_t)(-1), "memory allocation failed")
+
+ /* Clear new section so junk doesn't appear in the file */
+ /* (Avoid clearing section which will be overwritten with newly inserted data) */
+ HDmemset(heap->chunk + sizeof_hdr + offset + buf_size, 0, (new_heap_alloc - (offset + buf_size)));
+ } /* end if */
+
/*
* Copy the data into the heap
*/
HDmemcpy(heap->chunk + sizeof_hdr + offset, buf, buf_size);
/* Set return value */
- ret_value=offset;
+ ret_value = offset;
done:
- if (heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, heap_flags) != SUCCEED)
- HDONE_ERROR(H5E_HEAP, H5E_PROTECT, (size_t)(-1), "unable to release object header");
-
- FUNC_LEAVE_NOAPI(ret_value);
+ if(heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, heap_flags) != SUCCEED)
+ HDONE_ERROR(H5E_HEAP, H5E_PROTECT, (size_t)(-1), "unable to release object header")
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5HL_insert() */
#ifdef NOT_YET
@@ -1227,8 +1215,8 @@ H5HL_write(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size, co
if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to load heap");
- assert(offset < heap->mem_alloc);
- assert(offset + size <= heap->mem_alloc);
+ assert(offset < heap->heap_alloc);
+ assert(offset + size <= heap->heap_alloc);
heap_flags |= H5AC__DIRTIED_FLAG;
HDmemcpy(heap->chunk + H5HL_SIZEOF_HDR(f) + offset, buf, size);
@@ -1305,9 +1293,8 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size)
if (NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_WRITE)))
HGOTO_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to load heap");
- HDassert( offset < heap->mem_alloc );
- HDassert( offset + size <= heap->mem_alloc );
- HDassert( heap->disk_alloc == heap->mem_alloc );
+ HDassert( offset < heap->heap_alloc );
+ HDassert( offset + size <= heap->heap_alloc );
fl = heap->freelist;
heap_flags |= H5AC__DIRTIED_FLAG;
@@ -1331,28 +1318,19 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size)
assert (fl->offset==H5HL_ALIGN (fl->offset));
assert (fl->size==H5HL_ALIGN (fl->size));
fl2 = H5HL_remove_free(heap, fl2);
- if ( ( (fl->offset + fl->size) == heap->mem_alloc ) &&
- ( (2 * fl->size) > heap->mem_alloc ) ) {
-
- if ( H5HL_minimize_heap_space(f, dxpl_id, heap) !=
- SUCCEED ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "heap size minimization failed");
- }
+ if ( ( (fl->offset + fl->size) == heap->heap_alloc ) &&
+ ( (2 * fl->size) > heap->heap_alloc ) ) {
+ if ( H5HL_minimize_heap_space(f, dxpl_id, heap) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "heap size minimization failed")
}
HGOTO_DONE(SUCCEED);
}
fl2 = fl2->next;
}
- if ( ( (fl->offset + fl->size) == heap->mem_alloc ) &&
- ( (2 * fl->size) > heap->mem_alloc ) ) {
-
- if ( H5HL_minimize_heap_space(f, dxpl_id, heap) != SUCCEED ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "heap size minimization failed");
- }
+ if ( ( (fl->offset + fl->size) == heap->heap_alloc ) &&
+ ( (2 * fl->size) > heap->heap_alloc ) ) {
+ if ( H5HL_minimize_heap_space(f, dxpl_id, heap) < 0 )
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "heap size minimization failed")
}
HGOTO_DONE(SUCCEED);
@@ -1365,28 +1343,19 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size)
fl->size += fl2->size;
assert (fl->size==H5HL_ALIGN (fl->size));
fl2 = H5HL_remove_free(heap, fl2);
- if ( ( (fl->offset + fl->size) == heap->mem_alloc ) &&
- ( (2 * fl->size) > heap->mem_alloc ) ) {
-
- if ( H5HL_minimize_heap_space(f, dxpl_id, heap) !=
- SUCCEED ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "heap size minimization failed");
- }
+ if ( ( (fl->offset + fl->size) == heap->heap_alloc ) &&
+ ( (2 * fl->size) > heap->heap_alloc ) ) {
+ if ( H5HL_minimize_heap_space(f, dxpl_id, heap) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "heap size minimization failed")
}
HGOTO_DONE(SUCCEED);
}
fl2 = fl2->next;
}
- if ( ( (fl->offset + fl->size) == heap->mem_alloc ) &&
- ( (2 * fl->size) > heap->mem_alloc ) ) {
-
- if ( H5HL_minimize_heap_space(f, dxpl_id, heap) != SUCCEED ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "heap size minimization failed");
- }
+ if ( ( (fl->offset + fl->size) == heap->heap_alloc ) &&
+ ( (2 * fl->size) > heap->heap_alloc ) ) {
+ if ( H5HL_minimize_heap_space(f, dxpl_id, heap) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "heap size minimization failed")
}
HGOTO_DONE(SUCCEED);
}
@@ -1407,6 +1376,7 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size)
#endif
HGOTO_DONE(SUCCEED);
}
+
/*
* Add an entry to the free list.
*/
@@ -1422,14 +1392,10 @@ H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size)
heap->freelist->prev = fl;
heap->freelist = fl;
- if ( ( (fl->offset + fl->size) == heap->mem_alloc ) &&
- ( (2 * fl->size) > heap->mem_alloc ) ) {
-
- if ( H5HL_minimize_heap_space(f, dxpl_id, heap) != SUCCEED ) {
-
- HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, \
- "heap size minimization failed");
- }
+ if ( ( (fl->offset + fl->size) == heap->heap_alloc ) &&
+ ( (2 * fl->size) > heap->heap_alloc ) ) {
+ if ( H5HL_minimize_heap_space(f, dxpl_id, heap) < 0)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_CANTFREE, FAIL, "heap size minimization failed")
}
done:
@@ -1488,8 +1454,8 @@ H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
assert(!H5F_addr_overflow(addr,sizeof_hdr));
if(H5F_addr_eq(heap->addr,addr+sizeof_hdr)) {
/* Free the contiguous local heap in one call */
- H5_CHECK_OVERFLOW(sizeof_hdr+heap->disk_alloc,size_t,hsize_t);
- if (H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, addr, (hsize_t)(sizeof_hdr+heap->disk_alloc))<0)
+ H5_CHECK_OVERFLOW(sizeof_hdr+heap->heap_alloc,size_t,hsize_t);
+ if (H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, addr, (hsize_t)(sizeof_hdr+heap->heap_alloc))<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free contiguous local heap");
} /* end if */
else {
@@ -1499,8 +1465,8 @@ H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free local heap header");
/* Free the local heap's data */
- H5_CHECK_OVERFLOW(heap->disk_alloc,size_t,hsize_t);
- if (H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, heap->addr, (hsize_t)heap->disk_alloc)<0)
+ H5_CHECK_OVERFLOW(heap->heap_alloc,size_t,hsize_t);
+ if (H5MF_xfree(f, H5FD_MEM_LHEAP, dxpl_id, heap->addr, (hsize_t)heap->heap_alloc)<0)
HGOTO_ERROR(H5E_HEAP, H5E_CANTFREE, FAIL, "unable to free local heap data");
} /* end else */
@@ -1518,3 +1484,44 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5HL_delete() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5HL_get_size
+ *
+ * Purpose: Retrieves the current size of a heap
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Nov 7 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5HL_get_size(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t *size)
+{
+ H5HL_t *heap = NULL; /* Heap to query */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5HL_get_size, FAIL)
+
+ /* check arguments */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(size);
+
+ /* Get heap pointer */
+ if(NULL == (heap = H5AC_protect(f, dxpl_id, H5AC_LHEAP, addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_HEAP, H5E_CANTLOAD, FAIL, "unable to load heap")
+
+ /* Set the size to return */
+ *size = heap->heap_alloc;
+
+done:
+ if(heap && H5AC_unprotect(f, dxpl_id, H5AC_LHEAP, addr, heap, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_HEAP, H5E_PROTECT, FAIL, "unable to release local heap")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5HL_get_size() */
+
diff --git a/src/H5HLdbg.c b/src/H5HLdbg.c
index bf1251c..0401f92 100644
--- a/src/H5HLdbg.c
+++ b/src/H5HLdbg.c
@@ -84,17 +84,14 @@ H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int
"Address of heap data:",
h->addr);
HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
- "Data bytes allocated on disk:",
- h->disk_alloc);
- HDfprintf(stream, "%*s%-*s %Zu\n", indent, "", fwidth,
- "Data bytes allocated in core:",
- h->mem_alloc);
+ "Data bytes allocated for heap:",
+ h->heap_alloc);
/*
* Traverse the free list and check that all free blocks fall within
* the heap and that no two free blocks point to the same region of
* the heap. */
- if (NULL==(marker = H5MM_calloc(h->mem_alloc)))
+ if (NULL==(marker = H5MM_calloc(h->heap_alloc)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
fprintf(stream, "%*sFree Blocks (offset, size):\n", indent, "");
@@ -106,7 +103,7 @@ H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int
HDfprintf(stream, "%*s%-*s %8Zu, %8Zu\n", indent+3, "", MAX(0,fwidth-9),
temp_str,
freelist->offset, freelist->size);
- if (freelist->offset + freelist->size > h->mem_alloc) {
+ if (freelist->offset + freelist->size > h->heap_alloc) {
fprintf(stream, "***THAT FREE BLOCK IS OUT OF BOUNDS!\n");
} else {
for (i=overlap=0; i<(int)(freelist->size); i++) {
@@ -123,20 +120,20 @@ H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int
}
}
- if (h->mem_alloc) {
+ if (h->heap_alloc) {
fprintf(stream, "%*s%-*s %.2f%%\n", indent, "", fwidth,
"Percent of heap used:",
- (100.0 * (double)(h->mem_alloc - amount_free) / (double)h->mem_alloc));
+ (100.0 * (double)(h->heap_alloc - amount_free) / (double)h->heap_alloc));
}
/*
* Print the data in a VMS-style octal dump.
*/
fprintf(stream, "%*sData follows (`__' indicates free region)...\n",
indent, "");
- for (i=0; i<(int)(h->disk_alloc); i+=16) {
+ for (i=0; i<(int)(h->heap_alloc); i+=16) {
fprintf(stream, "%*s %8d: ", indent, "", i);
for (j = 0; j < 16; j++) {
- if (i+j<(int)(h->disk_alloc)) {
+ if (i+j<(int)(h->heap_alloc)) {
if (marker[i + j]) {
fprintf(stream, "__ ");
} else {
@@ -151,7 +148,7 @@ H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent, int
}
for (j = 0; j < 16; j++) {
- if (i+j < (int)(h->disk_alloc)) {
+ if (i+j < (int)(h->heap_alloc)) {
if (marker[i + j]) {
HDfputc(' ', stream);
} else {
diff --git a/src/H5HLpkg.h b/src/H5HLpkg.h
index 8b099cc..3598403 100644
--- a/src/H5HLpkg.h
+++ b/src/H5HLpkg.h
@@ -65,8 +65,7 @@ struct H5HL_t {
H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */
/* first field in structure */
haddr_t addr; /*address of data */
- size_t disk_alloc; /*data bytes allocated on disk */
- size_t mem_alloc; /*data bytes allocated in mem */
+ size_t heap_alloc; /*size of heap on disk and in mem */
uint8_t *chunk; /*the chunk, including header */
H5HL_free_t *freelist; /*the free list */
};
diff --git a/src/H5HLprivate.h b/src/H5HLprivate.h
index 001c3a1..445c1a7 100644
--- a/src/H5HLprivate.h
+++ b/src/H5HLprivate.h
@@ -70,6 +70,7 @@ H5_DLL size_t H5HL_insert(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t size,
const void *buf);
H5_DLL herr_t H5HL_remove(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t offset, size_t size);
H5_DLL herr_t H5HL_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr);
+H5_DLL herr_t H5HL_get_size(H5F_t *f, hid_t dxpl_id, haddr_t addr, size_t *size);
/* Debugging functions */
H5_DLL herr_t H5HL_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent,
diff --git a/src/H5I.c b/src/H5I.c
index a0e2096..bfcef6b 100644
--- a/src/H5I.c
+++ b/src/H5I.c
@@ -45,6 +45,7 @@
#include "H5FLprivate.h" /* Free Lists */
#include "H5Ipkg.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
+#include "H5Oprivate.h" /* Object headers */
/* Define this to compile in support for dumping ID information */
/* #define H5I_DEBUG_OUTPUT */
@@ -2003,28 +2004,61 @@ H5I_find_id(hid_t id)
ssize_t
H5Iget_name(hid_t id, char *name/*out*/, size_t size)
{
- H5G_entry_t *ent; /*symbol table entry */
- size_t len=0;
+ H5G_loc_t loc; /* Object location */
+ size_t len = 0;
ssize_t ret_value;
- FUNC_ENTER_API (H5Iget_name, FAIL);
+ FUNC_ENTER_API(H5Iget_name, FAIL)
H5TRACE3("Zs","ixz",id,name,size);
- /* get symbol table entry */
- if(NULL!=(ent = H5G_loc(id))) {
- if (ent->user_path_r != NULL && ent->user_path_hidden==0) {
- len = H5RS_len(ent->user_path_r);
+ /* get object location */
+ if(H5G_loc(id, &loc) >= 0) {
+ if(loc.path->user_path_r != NULL && loc.path->user_path_hidden == 0) {
+ len = H5RS_len(loc.path->user_path_r);
if(name) {
- HDstrncpy(name, H5RS_get_str(ent->user_path_r), MIN(len+1,size));
+ HDstrncpy(name, H5RS_get_str(loc.path->user_path_r), MIN(len + 1, size));
if(len >= size)
- name[size-1]='\0';
+ name[size-1] = '\0';
} /* end if */
} /* end if */
} /* end if */
/* Set return value */
- ret_value=(ssize_t)len;
+ ret_value = (ssize_t)len;
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Iget_name() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Iget_file_id
+ *
+ * Purpose: The public version of H5I_get_file_id(), obtains the file
+ * ID given an object ID. User has to close this ID.
+ *
+ * Return: Success: file ID
+ *
+ * Failure: a negative value
+ *
+ * Programmer: Raymond Lu
+ * Oct 27, 2003
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Iget_file_id(hid_t obj_id)
+{
+ hid_t ret_value;
+
+ FUNC_ENTER_API(H5Iget_file_id, FAIL);
+ H5TRACE1("i","i",obj_id);
+
+ if((ret_value = H5I_get_file_id(obj_id))<0)
+ HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve file ID");
done:
FUNC_LEAVE_API(ret_value);
@@ -2032,6 +2066,57 @@ done:
/*-------------------------------------------------------------------------
+ * Function: H5I_get_file_id
+ *
+ * Purpose: The private version of H5Iget_file_id(), obtains the file
+ * ID given an object ID.
+ *
+ * Return: Success: file ID
+ *
+ * Failure: a negative value
+ *
+ * Programmer: Raymond Lu
+ * Oct 27, 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+static hid_t
+H5I_get_file_id(hid_t obj_id)
+{
+ H5G_loc_t loc; /* Location of object */
+ H5I_type_t type; /* ID type */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5I_get_file_id)
+
+ /* Get object type */
+ type = H5I_TYPE(obj_id);
+ if(type == H5I_FILE) {
+ ret_value = obj_id;
+
+ /* Increment reference count on atom. */
+ if(H5I_inc_ref(ret_value) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed")
+ }
+ else if(type == H5I_DATATYPE) {
+ if(H5G_loc(obj_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "not a named datatype")
+ ret_value = H5F_get_id(loc.oloc->file);
+ }
+ else if(type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR) {
+ if(H5G_loc(obj_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTGET, FAIL, "can't get symbol table info")
+ ret_value = H5F_get_id(loc.oloc->file);
+ }
+ else
+ HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid object ID")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5I_get_file_id() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5I_debug
*
* Purpose: Dump the contents of a type to stderr for debugging.
@@ -2056,7 +2141,7 @@ H5I_debug(H5I_type_t type)
{
H5I_id_type_t *type_ptr;
H5I_id_info_t *cur;
- H5G_entry_t *ent = NULL;
+ H5G_name_t *path;
int is, js;
unsigned int iu;
herr_t ret_value; /* Return value */
@@ -2092,26 +2177,26 @@ H5I_debug(H5I_type_t type)
fprintf(stderr, " count = %u\n", cur->count);
fprintf(stderr, " obj = 0x%08lx\n", (unsigned long)(cur->obj_ptr));
- /* Get the symbol table entry, so we get get the name */
+ /* Get the group location, so we get get the name */
switch(type) {
case H5I_GROUP:
- ent = H5G_entof((H5G_t*)cur->obj_ptr);
+ path = H5G_nameof((H5G_t*)cur->obj_ptr);
break;
case H5I_DATASET:
- ent = H5D_entof((H5D_t*)cur->obj_ptr);
+ path = H5D_nameof((H5D_t*)cur->obj_ptr);
break;
case H5I_DATATYPE:
- ent = H5T_entof((H5T_t*)cur->obj_ptr);
+ path = H5T_nameof((H5T_t*)cur->obj_ptr);
break;
default:
continue; /* Other types of IDs are not stored in files */
} /* end switch*/
- if(ent) {
- if(ent->name)
- fprintf(stderr, " name = %s\n",ent->name);
- if(ent->old_name)
- fprintf(stderr, " old_name = %s\n",ent->old_name);
+ if(path) {
+ if(path->user_path_r)
+ fprintf(stderr, " user_path = %s\n", H5RS_get_str(path->user_path_r));
+ if(ent->canon_path_r)
+ fprintf(stderr, " canon_path = %s\n", H5RS_get_str(path->canon_path_r));
} /* end if */
} /* end for */
} /* end for */
@@ -2121,89 +2206,3 @@ done:
}
#endif /* H5I_DEBUG_OUTPUT */
-
-/*-------------------------------------------------------------------------
- * Function: H5Iget_file_id
- *
- * Purpose: The public version of H5I_get_file_id(), obtains the file
- * ID given an object ID. User has to close this ID.
- *
- * Return: Success: file ID
- *
- * Failure: a negative value
- *
- * Programmer: Raymond Lu
- * Oct 27, 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-hid_t
-H5Iget_file_id(hid_t obj_id)
-{
- hid_t ret_value;
-
- FUNC_ENTER_API(H5Iget_file_id, FAIL);
- H5TRACE1("i","i",obj_id);
-
- if((ret_value = H5I_get_file_id(obj_id))<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't retrieve file ID");
-
-done:
- FUNC_LEAVE_API(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5I_get_file_id
- *
- * Purpose: The private version of H5Iget_file_id(), obtains the file
- * ID given an object ID.
- *
- * Return: Success: file ID
- *
- * Failure: a negative value
- *
- * Programmer: Raymond Lu
- * Oct 27, 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static hid_t
-H5I_get_file_id(hid_t obj_id)
-{
- H5G_entry_t *ent;
- H5I_type_t type;
- hid_t ret_value;
-
- FUNC_ENTER_NOAPI_NOINIT(H5I_get_file_id);
-
- /* Get object type */
- type = H5I_TYPE(obj_id);
- if(type == H5I_FILE) {
- ret_value = obj_id;
-
- /* Increment reference count on atom. */
- if (H5I_inc_ref(ret_value)<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTSET, FAIL, "incrementing file ID failed");
- }
- else if(type == H5I_DATATYPE) {
- if((ent = H5G_loc(obj_id))==NULL)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "not a named datatype");
- ret_value = H5F_get_id(ent->file);
- }
- else if(type == H5I_GROUP || type == H5I_DATASET || type == H5I_ATTR) {
- if((ent = H5G_loc(obj_id))==NULL)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTGET, FAIL, "can't get symbol table info");
- ret_value = H5F_get_id(ent->file);
- }
- else
- HGOTO_ERROR(H5E_ARGS, H5E_BADRANGE, FAIL, "invalid object ID");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
diff --git a/src/H5O.c b/src/H5O.c
index 7522b4a..0f2ae87 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -20,8 +20,6 @@
*
* Purpose: Object header virtual functions.
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
@@ -33,20 +31,38 @@
#include "H5private.h" /* Generic Functions */
-#include "H5ACprivate.h" /* Metadata cache */
+#include "H5Dprivate.h" /* Datasets */
#include "H5Eprivate.h" /* Error handling */
#include "H5Fpkg.h" /* File access */
#include "H5FLprivate.h" /* Free lists */
-#include "H5Iprivate.h" /* IDs */
#include "H5MFprivate.h" /* File memory management */
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
-#include "H5Pprivate.h" /* Property lists */
#ifdef H5_HAVE_GETTIMEOFDAY
#include <sys/time.h>
#endif /* H5_HAVE_GETTIMEOFDAY */
+/* Local macros */
+
+/* Load native information for a message, if it's not already present */
+/* (Only works for messages with decode callback) */
+#define LOAD_NATIVE(F, DXPL, MSG) \
+ if(NULL == (MSG)->native) { \
+ const H5O_class_t *decode_type; \
+ \
+ /* Check for shared message */ \
+ if ((MSG)->flags & H5O_FLAG_SHARED) \
+ decode_type = H5O_SHARED; \
+ else \
+ decode_type = (MSG)->type; \
+ \
+ /* Decode the message */ \
+ HDassert(decode_type->decode); \
+ if(NULL == ((MSG)->native = (decode_type->decode)((F), (DXPL), (MSG)->raw))) \
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message") \
+ } /* end if */
+
/* Private typedefs */
/* User data for iteration while removing a message */
@@ -64,39 +80,114 @@ typedef struct {
typedef herr_t (*H5O_operator_int_t)(H5O_mesg_t *mesg/*in,out*/, unsigned idx,
unsigned * oh_flags_ptr, void *operator_data/*in,out*/);
+/*
+ * This table contains a list of object types, descriptions, and the
+ * functions that determine if some object is a particular type. The table
+ * is allocated dynamically.
+ */
+typedef struct H5O_typeinfo_t {
+ H5G_obj_t type; /*one of the public H5G_* types */
+ htri_t (*isa)(H5O_loc_t*, hid_t); /*function to determine type */
+ char *desc; /*description of object type */
+} H5O_typeinfo_t;
+
/* Node in skip list to map addresses from one file to another during object header copy */
typedef struct H5O_addr_map_t {
haddr_t src_addr; /* Address of object in source file */
haddr_t dst_addr; /* Address of object in destination file */
+ hbool_t is_locked; /* Indicate that the destination object is locked currently */
+ hsize_t inc_ref_count; /* Number of deferred increments to reference count */
} H5O_addr_map_t;
+/* Package variables */
+
+/* ID to type mapping */
+const H5O_class_t *const message_type_g[] = {
+ H5O_NULL, /*0x0000 Null */
+ H5O_SDSPACE, /*0x0001 Simple Dimensionality */
+ H5O_LINFO, /*0x0002 Link information */
+ H5O_DTYPE, /*0x0003 Data Type */
+ H5O_FILL, /*0x0004 Old data storage -- fill value */
+ H5O_FILL_NEW, /*0x0005 New Data storage -- fill value */
+ H5O_LINK, /*0x0006 Link */
+ H5O_EFL, /*0x0007 Data storage -- external data files */
+ H5O_LAYOUT, /*0x0008 Data Layout */
+#ifdef H5O_ENABLE_BOGUS
+ H5O_BOGUS, /*0x0009 "Bogus" */
+#else /* H5O_ENABLE_BOGUS */
+ NULL, /*0x0009 "Bogus" */
+#endif /* H5O_ENABLE_BOGUS */
+ H5O_GINFO, /*0x000A Group Information */
+ H5O_PLINE, /*0x000B Data storage -- filter pipeline */
+ H5O_ATTR, /*0x000C Attribute list */
+ H5O_NAME, /*0x000D Object name */
+ H5O_MTIME, /*0x000E Object modification date and time */
+ H5O_SHARED, /*0x000F Shared header message */
+ H5O_CONT, /*0x0010 Object header continuation */
+ H5O_STAB, /*0x0011 Symbol table */
+ H5O_MTIME_NEW, /*0x0012 New Object modification date and time */
+};
+
+/* Declare a free list to manage the H5O_t struct */
+H5FL_DEFINE(H5O_t);
+
+/* Declare a free list to manage the H5O_mesg_t sequence information */
+H5FL_SEQ_DEFINE(H5O_mesg_t);
+
+/* Declare a free list to manage the H5O_chunk_t sequence information */
+H5FL_SEQ_DEFINE(H5O_chunk_t);
+
+/* Declare a free list to manage the chunk image information */
+H5FL_BLK_DEFINE(chunk_image);
+
+/* Library private variables */
+
+/* Local variables */
+static H5O_typeinfo_t *H5O_type_g = NULL; /*object typing info */
+static size_t H5O_ntypes_g = 0; /*entries in type table */
+static size_t H5O_atypes_g = 0; /*entries allocated */
+
+/* Declare external the free list for time_t's */
+H5FL_EXTERN(time_t);
+
+/* Declare extern the free list for H5O_cont_t's */
+H5FL_EXTERN(H5O_cont_t);
+
+/* Declare a free list to manage the H5O_addr_map_t struct */
+H5FL_DEFINE_STATIC(H5O_addr_map_t);
+
/* PRIVATE PROTOTYPES */
-static herr_t H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint,
- H5G_entry_t *ent/*out*/, haddr_t header);
+static herr_t H5O_register_type(H5G_obj_t type, htri_t(*isa)(H5O_loc_t *, hid_t),
+ const char *_desc);
+static herr_t H5O_new(H5F_t *f, hid_t dxpl_id, size_t size_hint,
+ H5O_loc_t *loc/*out*/, haddr_t header);
static herr_t H5O_reset_real(const H5O_class_t *type, void *native);
-static herr_t H5O_free_mesg(H5O_mesg_t *mesg);
static void * H5O_copy_real(const H5O_class_t *type, const void *mesg,
void *dst);
-static int H5O_count_real (H5G_entry_t *ent, const H5O_class_t *type,
+static int H5O_count_real(H5O_loc_t *loc, const H5O_class_t *type,
hid_t dxpl_id);
-static htri_t H5O_exists_real(H5G_entry_t *ent, const H5O_class_t *type,
- int sequence, hid_t dxpl_id);
+static htri_t H5O_exists_real(H5O_loc_t *loc, const H5O_class_t *type,
+ int sequence, hid_t dxpl_id);
#ifdef NOT_YET
static herr_t H5O_share(H5F_t *f, hid_t dxpl_id, const H5O_class_t *type, const void *mesg,
H5HG_t *hobj/*out*/);
#endif /* NOT_YET */
static unsigned H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
const H5O_class_t **type_p, int sequence);
-static int H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type,
+static int H5O_modify_real(H5O_loc_t *loc, const H5O_class_t *type,
int overwrite, unsigned flags, unsigned update_flags, const void *mesg,
hid_t dxpl_id);
static int H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
const H5O_class_t *type, unsigned flags, const void *mesg,
unsigned * oh_flags_ptr);
-static herr_t H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type,
+static herr_t H5O_remove_real(const H5O_loc_t *loc, const H5O_class_t *type,
int sequence, H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id);
static unsigned H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
const H5O_class_t *type, size_t size, hbool_t * oh_dirtied_ptr);
+static htri_t H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
+static htri_t H5O_merge_null(H5F_t *f, H5O_t *oh);
+static htri_t H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
+static herr_t H5O_condense_header(H5F_t *f, H5O_t *oh, hid_t dxpl_id);
static htri_t H5O_alloc_extend_chunk(H5F_t *f, H5O_t *oh,
unsigned chunkno, size_t size, unsigned * msg_idx);
static unsigned H5O_alloc_new_chunk(H5F_t *f, hid_t dxpl_id, H5O_t *oh,
@@ -111,121 +202,185 @@ static unsigned H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags,
static herr_t H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type,
const void *mesg, unsigned flags, unsigned update_flags,
unsigned * oh_flags_ptr);
-static herr_t H5O_iterate_real(const H5G_entry_t *ent, const H5O_class_t *type,
+static herr_t H5O_iterate_real(const H5O_loc_t *loc, const H5O_class_t *type,
H5AC_protect_t prot, hbool_t internal, void *op, void *op_data, hid_t dxpl_id);
static void * H5O_copy_mesg_file(const H5O_class_t *type, H5F_t *file_src,
void *mesg_src, H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
-static herr_t H5O_post_copy_mesg_file(const H5O_class_t *type, H5F_t *file_src,
- const void *mesg_src, H5G_entry_t *loc_dst,
- hid_t dxpl_id, H5SL_t *map_list);
-static herr_t H5O_copy_header_real(const H5G_entry_t *ent_src,
- H5G_entry_t *ent_dst /*out */, hid_t dxpl_id, H5SL_t *map_list);
+static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src,
+ H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5SL_t *map_list);
static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data);
-/* Metadata cache callbacks */
-static H5O_t *H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1,
- void *_udata2);
-static herr_t H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh);
-static herr_t H5O_dest(H5F_t *f, H5O_t *oh);
-static herr_t H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy);
-static herr_t H5O_compute_size(const H5F_t *f, const H5O_t *oh, size_t *size_ptr);
-
-/* H5O inherits cache-like properties from H5AC */
-static const H5AC_class_t H5AC_OHDR[1] = {{
- H5AC_OHDR_ID,
- (H5AC_load_func_t)H5O_load,
- (H5AC_flush_func_t)H5O_flush,
- (H5AC_dest_func_t)H5O_dest,
- (H5AC_clear_func_t)H5O_clear,
- (H5AC_size_func_t)H5O_compute_size,
-}};
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_init
+ *
+ * Purpose: Initialize the interface from some other package.
+ *
+ * Return: Success: non-negative
+ *
+ * Failure: negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, September 28, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_init(void)
+{
+ herr_t ret_value = SUCCEED; /* Return value */
-/* ID to type mapping */
-static const H5O_class_t *const message_type_g[] = {
- H5O_NULL, /*0x0000 Null */
- H5O_SDSPACE, /*0x0001 Simple Dimensionality */
- NULL, /*0x0002 Data space (fiber bundle?) */
- H5O_DTYPE, /*0x0003 Data Type */
- H5O_FILL, /*0x0004 Old data storage -- fill value */
- H5O_FILL_NEW, /*0x0005 New Data storage -- fill value */
- NULL, /*0x0006 Data storage -- compact object */
- H5O_EFL, /*0x0007 Data storage -- external data files */
- H5O_LAYOUT, /*0x0008 Data Layout */
-#ifdef H5O_ENABLE_BOGUS
- H5O_BOGUS, /*0x0009 "Bogus" */
-#else /* H5O_ENABLE_BOGUS */
- NULL, /*0x0009 "Bogus" */
-#endif /* H5O_ENABLE_BOGUS */
- NULL, /*0x000A Not assigned */
- H5O_PLINE, /*0x000B Data storage -- filter pipeline */
- H5O_ATTR, /*0x000C Attribute list */
- H5O_NAME, /*0x000D Object name */
- H5O_MTIME, /*0x000E Object modification date and time */
- H5O_SHARED, /*0x000F Shared header message */
- H5O_CONT, /*0x0010 Object header continuation */
- H5O_STAB, /*0x0011 Symbol table */
- H5O_MTIME_NEW, /*0x0012 New Object modification date and time */
-};
+ FUNC_ENTER_NOAPI(H5O_init, FAIL)
+ /* FUNC_ENTER() does all the work */
-/* Library private variables */
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_init() */
-/*
- * An array of functions indexed by symbol table entry cache type
- * (H5G_type_t) that are called to retrieve constant messages cached in the
- * symbol table entry.
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_init_interface
+ *
+ * Purpose: Initialize the H5O interface.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * Tuesday, January 6, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
*/
-static void *(*H5O_fast_g[H5G_NCACHED]) (const H5G_cache_t *,
- const H5O_class_t *,
- void *);
+static herr_t
+H5O_init_interface(void)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_init_interface)
-/* Declare a free list to manage the H5O_t struct */
-H5FL_DEFINE_STATIC(H5O_t);
+ /*
+ * Initialize the type info table. Begin with the most general types and
+ * end with the most specific. For instance, any object that has a data
+ * type message is a datatype but only some of them are datasets.
+ */
+ H5O_register_type(H5G_TYPE, H5T_isa, "datatype");
+ H5O_register_type(H5G_GROUP, H5G_isa, "group");
+ H5O_register_type(H5G_DATASET, H5D_isa, "dataset");
-/* Declare a free list to manage the H5O_mesg_t sequence information */
-H5FL_SEQ_DEFINE_STATIC(H5O_mesg_t);
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_init_interface() */
-/* Declare a free list to manage the H5O_chunk_t sequence information */
-H5FL_SEQ_DEFINE_STATIC(H5O_chunk_t);
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_term_interface
+ *
+ * Purpose: Terminates the H5O interface
+ *
+ * Return: Success: Positive if anything is done that might
+ * affect other interfaces; zero otherwise.
+ *
+ * Failure: Negative.
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+int
+H5O_term_interface(void)
+{
+ int n = 0;
-/* Declare a free list to manage the chunk image information */
-H5FL_BLK_DEFINE_STATIC(chunk_image);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_term_interface)
-/* Declare external the free list for time_t's */
-H5FL_EXTERN(time_t);
+ if(H5_interface_initialize_g) {
+ size_t u;
-/* Declare extern the free list for H5O_cont_t's */
-H5FL_EXTERN(H5O_cont_t);
+ /* Empty the object type table */
+ for(u = 0; u < H5O_ntypes_g; u++)
+ H5MM_xfree(H5O_type_g[u].desc);
+ H5O_ntypes_g = H5O_atypes_g = 0;
+ H5O_type_g = H5MM_xfree(H5O_type_g);
-/* Declare a free list to manage the H5O_addr_map_t struct */
-H5FL_DEFINE_STATIC(H5O_addr_map_t);
+ /* Mark closed */
+ H5_interface_initialize_g = 0;
+ n = 1; /*H5O*/
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(n)
+} /* H5O_term_interface() */
/*-------------------------------------------------------------------------
- * Function: H5O_init_interface
+ * Function: H5O_register_type
*
- * Purpose: Initialize the H5O interface.
+ * Purpose: Register a new object type so H5O_get_type() can detect it.
+ * One should always register a general type before a more
+ * specific type. For instance, any object that has a datatype
+ * message is a datatype, but only some of those objects are
+ * datasets.
*
- * Return: Non-negative on success/Negative on failure
+ * Return: Success: Non-negative
*
- * Programmer: Robb Matzke
- * Tuesday, January 6, 1998
+ * Failure: Negative
*
- * Modifications:
+ * Programmer: Quincey Koziol
+ * Monday, September 19, 2005
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_init_interface(void)
+H5O_register_type(H5G_obj_t type, htri_t(*isa)(H5O_loc_t *, hid_t), const char *_desc)
{
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_init_interface);
+ char *desc = NULL;
+ size_t i;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_register_type)
+
+ HDassert(type >= 0);
+ HDassert(isa);
+ HDassert(_desc);
+
+ /* Copy the description */
+ if(NULL == (desc = H5MM_strdup(_desc)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for object type description")
/*
- * Initialize functions that decode messages from symbol table entries.
+ * If the type is already registered then just update its entry without
+ * moving it to the end
*/
- H5O_fast_g[H5G_CACHED_STAB] = H5O_stab_fast;
+ for(i = 0; i < H5O_ntypes_g; i++) {
+ if (H5O_type_g[i].type == type) {
+ H5O_type_g[i].isa = isa;
+ H5MM_xfree(H5O_type_g[i].desc);
+ H5O_type_g[i].desc = desc;
+ HGOTO_DONE(SUCCEED);
+ } /* end if */
+ } /* end for */
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ /* Increase table size */
+ if(H5O_ntypes_g >= H5O_atypes_g) {
+ size_t n = MAX(32, 2 * H5O_atypes_g);
+ H5O_typeinfo_t *x = H5MM_realloc(H5O_type_g, n * sizeof(H5O_typeinfo_t));
+
+ if (!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for objec type table")
+ H5O_atypes_g = n;
+ H5O_type_g = x;
+ } /* end if */
+
+ /* Add a new entry */
+ H5O_type_g[H5O_ntypes_g].type = type;
+ H5O_type_g[H5O_ntypes_g].isa = isa;
+ H5O_type_g[H5O_ntypes_g].desc = desc; /*already copied*/
+ H5O_ntypes_g++;
+
+done:
+ if(ret_value < 0)
+ H5MM_xfree(desc);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_register_type() */
/*-------------------------------------------------------------------------
@@ -246,47 +401,38 @@ H5O_init_interface(void)
* matzke@llnl.gov
* Aug 5 1997
*
- * Modifications:
- *
- * Bill Wendling, 1. November 2002
- * Separated the create function into two different functions. One
- * which allocates space and an initialization function which
- * does the rest of the work (initializes, caches, and opens the
- * object header).
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/)
+H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5O_loc_t *loc/*out*/)
{
haddr_t header;
herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_NOAPI(H5O_create, FAIL);
+ FUNC_ENTER_NOAPI(H5O_create, FAIL)
/* check args */
- assert(f);
- assert(ent);
+ HDassert(f);
+ HDassert(loc);
- size_hint = H5O_ALIGN (MAX (H5O_MIN_SIZE, size_hint));
+ size_hint = H5O_ALIGN(MAX(H5O_MIN_SIZE, size_hint));
/* allocate disk space for header and first chunk */
- if (HADDR_UNDEF == (header = H5MF_alloc(f, H5FD_MEM_OHDR, dxpl_id,
- (hsize_t)H5O_SIZEOF_HDR(f) + size_hint)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
- "file allocation failed for object header header");
+ if(HADDR_UNDEF == (header = H5MF_alloc(f, H5FD_MEM_OHDR, dxpl_id,
+ (hsize_t)H5O_SIZEOF_HDR(f) + size_hint)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header header")
/* initialize the object header */
- if (H5O_init(f, dxpl_id, size_hint, ent, header) != SUCCEED)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to initialize object header");
+ if(H5O_new(f, dxpl_id, size_hint, loc, header) != SUCCEED)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to initialize object header")
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_create() */
/*-------------------------------------------------------------------------
- * Function: H5O_init
+ * Function: H5O_new
*
* Purpose: Initialize a new object header, sets the link count to 0,
* and caches the header. The object header is opened for
@@ -301,35 +447,28 @@ done:
* Programmer: Bill Wendling
* 1, November 2002
*
- * Modifications:
- *
- * JRM -- 6/6/05
- * Removed code modifying the is_dirty field of the
- * cache_info. This field is now managed by the cache
- * proper.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/, haddr_t header)
+H5O_new(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5O_loc_t *loc/*out*/, haddr_t header)
{
H5O_t *oh = NULL;
haddr_t tmp_addr;
herr_t ret_value = SUCCEED; /* return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_init);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_new)
/* check args */
- assert(f);
- assert(ent);
+ HDassert(f);
+ HDassert(loc);
size_hint = H5O_ALIGN(MAX(H5O_MIN_SIZE, size_hint));
- ent->file = f;
- ent->header = header;
+ loc->file = f;
+ loc->addr = header;
/* allocate the object header and fill in header fields */
- if (NULL == (oh = H5FL_MALLOC(H5O_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if(NULL == (oh = H5FL_MALLOC(H5O_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
oh->version = H5O_VERSION;
oh->nlink = 0;
@@ -338,23 +477,23 @@ H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/, had
oh->nchunks = 1;
oh->alloc_nchunks = H5O_NCHUNKS;
- if (NULL == (oh->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->alloc_nchunks)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if(NULL == (oh->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->alloc_nchunks)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
- tmp_addr = ent->header + (hsize_t)H5O_SIZEOF_HDR(f);
+ tmp_addr = loc->addr + (hsize_t)H5O_SIZEOF_HDR(f);
oh->chunk[0].dirty = TRUE;
oh->chunk[0].addr = tmp_addr;
oh->chunk[0].size = size_hint;
- if (NULL == (oh->chunk[0].image = H5FL_BLK_CALLOC(chunk_image, size_hint)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if(NULL == (oh->chunk[0].image = H5FL_BLK_CALLOC(chunk_image, size_hint)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* create the message list and initialize the first message */
oh->nmesgs = 1;
oh->alloc_nmesgs = H5O_NMESGS;
- if (NULL == (oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, (size_t)oh->alloc_nmesgs)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ if(NULL == (oh->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, (size_t)oh->alloc_nmesgs)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
oh->mesg[0].type = H5O_NULL;
oh->mesg[0].dirty = TRUE;
@@ -364,21 +503,21 @@ H5O_init(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5G_entry_t *ent/*out*/, had
oh->mesg[0].chunkno = 0;
/* cache it */
- if (H5AC_set(f, dxpl_id, H5AC_OHDR, ent->header, oh, H5AC__NO_FLAGS_SET) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to cache object header");
+ if(H5AC_set(f, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to cache object header")
/* open it */
- if (H5O_open(ent) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object header");
+ if(H5O_open(loc) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTOPENOBJ, FAIL, "unable to open object header")
done:
- if(ret_value<0 && oh) {
- if(H5O_dest(f,oh)<0)
- HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data");
+ if(ret_value < 0 && oh) {
+ if(H5O_dest(f, oh) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data")
} /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_new() */
/*-------------------------------------------------------------------------
@@ -392,32 +531,30 @@ done:
* Programmer: Robb Matzke
* Monday, January 5, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_open(const H5G_entry_t *obj_ent)
+H5O_open(const H5O_loc_t *loc)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_open, FAIL);
+ FUNC_ENTER_NOAPI(H5O_open, FAIL)
/* Check args */
- assert(obj_ent);
- assert(obj_ent->file);
+ HDassert(loc);
+ HDassert(loc->file);
#ifdef H5O_DEBUG
if (H5DEBUG(O))
- HDfprintf(H5DEBUG(O), "> %a\n", obj_ent->header);
+ HDfprintf(H5DEBUG(O), "> %a\n", loc->addr);
#endif
/* Increment open-lock counters */
- obj_ent->file->nopen_objs++;
+ loc->file->nopen_objs++;
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_open() */
/*-------------------------------------------------------------------------
@@ -430,565 +567,51 @@ done:
* Programmer: Robb Matzke
* Monday, January 5, 1998
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_close(H5G_entry_t *obj_ent)
+H5O_close(H5O_loc_t *loc)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_close, FAIL);
+ FUNC_ENTER_NOAPI(H5O_close, FAIL)
/* Check args */
- assert(obj_ent);
- assert(obj_ent->file);
- assert(obj_ent->file->nopen_objs > 0);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(loc->file->nopen_objs > 0);
/* Decrement open-lock counters */
- --obj_ent->file->nopen_objs;
+ --loc->file->nopen_objs;
#ifdef H5O_DEBUG
if (H5DEBUG(O)) {
- if (obj_ent->file->file_id < 0 && 1==obj_ent->file->shared->nrefs) {
+ if(loc->file->file_id < 0 && 1 == loc->file->shared->nrefs) {
HDfprintf(H5DEBUG(O), "< %a auto %lu remaining\n",
- obj_ent->header,
- (unsigned long)(obj_ent->file->nopen_objs));
+ loc->addr,
+ (unsigned long)(loc->file->nopen_objs));
} else {
- HDfprintf(H5DEBUG(O), "< %a\n", obj_ent->header);
+ HDfprintf(H5DEBUG(O), "< %a\n", loc->addr);
}
- }
+ } /* end if */
#endif
/*
* If the file open object count has reached the number of open mount points
* (each of which has a group open in the file) attempt to close the file.
*/
- if(obj_ent->file->nopen_objs == obj_ent->file->mtab.nmounts) {
+ if(loc->file->nopen_objs == loc->file->mtab.nmounts) {
/* Attempt to close down the file hierarchy */
- if(H5F_try_close(obj_ent->file) < 0)
- HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close")
+ if(H5F_try_close(loc->file) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCLOSEFILE, FAIL, "problem attempting file close")
} /* end if */
- /* Free the ID to name buffers */
- H5G_free_ent_name(obj_ent);
-
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_close() */
/*-------------------------------------------------------------------------
- * Function: H5O_load
- *
- * Purpose: Loads an object header from disk.
- *
- * Return: Success: Pointer to the new object header.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 5 1997
- *
- * Modifications:
- *
- * Robb Matzke, 1997-08-30
- * Plugged memory leaks that occur during error handling.
- *
- * Robb Matzke, 1998-01-07
- * Able to distinguish between constant and variable messages.
- *
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * Quincey Koziol, 2002-7-180
- * Added dxpl parameter to allow more control over I/O from metadata
- * cache.
- *-------------------------------------------------------------------------
- */
-static H5O_t *
-H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
- void UNUSED * _udata2)
-{
- H5O_t *oh = NULL;
- H5O_t *ret_value;
- uint8_t buf[16], *p;
- size_t mesg_size;
- size_t hdr_size;
- unsigned id;
- int mesgno;
- unsigned curmesg = 0, nmesgs;
- unsigned chunkno;
- haddr_t chunk_addr;
- size_t chunk_size;
- uint8_t flags;
-
- FUNC_ENTER_NOAPI(H5O_load, NULL);
-
- /* check args */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(!_udata1);
- assert(!_udata2);
-
- /* allocate ohdr and init chunk list */
- if (NULL==(oh = H5FL_CALLOC(H5O_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
-
- /* read fixed-lenth part of object header */
- hdr_size = H5O_SIZEOF_HDR(f);
- assert(hdr_size<=sizeof(buf));
- if (H5F_block_read(f, H5FD_MEM_OHDR, addr, hdr_size, dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header");
- p = buf;
-
- /* decode version */
- oh->version = *p++;
- if (H5O_VERSION != oh->version)
- HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header version number");
-
- /* reserved */
- p++;
-
- /* decode number of messages */
- UINT16DECODE(p, nmesgs);
-
- /* decode link count */
- UINT32DECODE(p, oh->nlink);
-
- /* decode first chunk info */
- chunk_addr = addr + (hsize_t)hdr_size;
- UINT32DECODE(p, chunk_size);
-
- /* build the message array */
- oh->alloc_nmesgs = MAX(H5O_NMESGS, nmesgs);
- if (NULL==(oh->mesg=H5FL_SEQ_CALLOC(H5O_mesg_t,(size_t)oh->alloc_nmesgs)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
-
- /* read each chunk from disk */
- while (H5F_addr_defined(chunk_addr)) {
- /* increase chunk array size */
- if (oh->nchunks >= oh->alloc_nchunks) {
- unsigned na = oh->alloc_nchunks + H5O_NCHUNKS;
- H5O_chunk_t *x = H5FL_SEQ_REALLOC (H5O_chunk_t, oh->chunk, (size_t)na);
-
- if (!x)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- oh->alloc_nchunks = na;
- oh->chunk = x;
- }
-
- /* read the chunk raw data */
- chunkno = oh->nchunks++;
- oh->chunk[chunkno].dirty = FALSE;
- oh->chunk[chunkno].addr = chunk_addr;
- oh->chunk[chunkno].size = chunk_size;
- if (NULL==(oh->chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image,chunk_size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if (H5F_block_read(f, H5FD_MEM_OHDR, chunk_addr, chunk_size, dxpl_id,
- oh->chunk[chunkno].image) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header data");
-
- /* load messages from this chunk */
- for (p = oh->chunk[chunkno].image; p < oh->chunk[chunkno].image + chunk_size; p += mesg_size) {
- UINT16DECODE(p, id);
- UINT16DECODE(p, mesg_size);
- assert (mesg_size==H5O_ALIGN (mesg_size));
- flags = *p++;
- p += 3; /*reserved*/
-
- /* Try to detect invalidly formatted object header messages */
- if (p + mesg_size > oh->chunk[chunkno].image + chunk_size)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "corrupt object header");
-
- /* Skip header messages we don't know about */
- /* (Usually from future versions of the library */
- if (id >= NELMTS(message_type_g) || NULL == message_type_g[id])
- continue;
-
- if (H5O_NULL_ID == id && oh->nmesgs > 0 &&
- H5O_NULL_ID == oh->mesg[oh->nmesgs - 1].type->id &&
- oh->mesg[oh->nmesgs - 1].chunkno == chunkno) {
- /* combine adjacent null messages */
- mesgno = oh->nmesgs - 1;
- oh->mesg[mesgno].raw_size += H5O_SIZEOF_MSGHDR(f) + mesg_size;
- } else {
- /* new message */
- if (oh->nmesgs >= nmesgs)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "corrupt object header");
- mesgno = oh->nmesgs++;
- oh->mesg[mesgno].type = message_type_g[id];
- oh->mesg[mesgno].dirty = FALSE;
- oh->mesg[mesgno].flags = flags;
- oh->mesg[mesgno].native = NULL;
- oh->mesg[mesgno].raw = p;
- oh->mesg[mesgno].raw_size = mesg_size;
- oh->mesg[mesgno].chunkno = chunkno;
- }
- }
-
- assert(p == oh->chunk[chunkno].image + chunk_size);
-
- /* decode next object header continuation message */
- for (chunk_addr = HADDR_UNDEF; !H5F_addr_defined(chunk_addr) && curmesg < oh->nmesgs; ++curmesg) {
- if (H5O_CONT_ID == oh->mesg[curmesg].type->id) {
- H5O_cont_t *cont;
-
- cont = (H5O_CONT->decode) (f, dxpl_id, oh->mesg[curmesg].raw, NULL);
- oh->mesg[curmesg].native = cont;
- chunk_addr = cont->addr;
- chunk_size = cont->size;
- cont->chunkno = oh->nchunks; /*the next chunk to allocate */
- }
- }
- }
-
- /* Set return value */
- ret_value = oh;
-
-done:
- if (!ret_value && oh) {
- if(H5O_dest(f,oh)<0)
- HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, NULL, "unable to destroy object header data");
- }
-
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_flush
- *
- * Purpose: Flushes (and destroys) an object header.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 5 1997
- *
- * Modifications:
- *
- * Robb Matzke, 1998-01-07
- * Handles constant vs non-constant messages.
- *
- * rky, 1998-08-28
- * Only p0 writes metadata to disk.
- *
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * Quincey Koziol, 2002-7-180
- * Added dxpl parameter to allow more control over I/O from metadata
- * cache.
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
-{
- uint8_t buf[16], *p;
- int id;
- unsigned u;
- H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
- herr_t (*encode)(H5F_t*, uint8_t*, const void*) = NULL;
- unsigned combine=0; /* Whether to combine the object header prefix & the first chunk */
- herr_t ret_value=SUCCEED; /* Return value */
-
- FUNC_ENTER_NOAPI(H5O_flush, FAIL);
-
- /* check args */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(oh);
-
- /* flush */
- if (oh->cache_info.is_dirty) {
- p = buf;
-
- /* encode version */
- *p++ = oh->version;
-
- /* reserved */
- *p++ = 0;
-
- /* encode number of messages */
- UINT16ENCODE(p, oh->nmesgs);
-
- /* encode link count */
- UINT32ENCODE(p, oh->nlink);
-
- /* encode body size */
- UINT32ENCODE(p, oh->chunk[0].size);
-
- /* zero to alignment */
- HDmemset (p, 0, (size_t)(H5O_SIZEOF_HDR(f)-12));
-
- /* write the object header prefix */
-
- /* Check if we can combine the object header prefix & the first chunk into one I/O operation */
- if(oh->chunk[0].dirty && (addr+H5O_SIZEOF_HDR(f))==oh->chunk[0].addr) {
- combine=1;
- } /* end if */
- else {
- if (H5F_block_write(f, H5FD_MEM_OHDR, addr, (size_t)H5O_SIZEOF_HDR(f),
- dxpl_id, buf) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header hdr to disk");
- } /* end else */
-
- /* encode messages */
- for (u = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) {
- if (curr_msg->dirty) {
- p = curr_msg->raw - H5O_SIZEOF_MSGHDR(f);
-
- id = curr_msg->type->id;
- UINT16ENCODE(p, id);
- assert (curr_msg->raw_size<H5O_MAX_SIZE);
- UINT16ENCODE(p, curr_msg->raw_size);
- *p++ = curr_msg->flags;
- *p++ = 0; /*reserved*/
- *p++ = 0; /*reserved*/
- *p++ = 0; /*reserved*/
-
- if (curr_msg->native) {
- assert(curr_msg->type->encode);
-
- /* allocate file space for chunks that have none yet */
- if (H5O_CONT_ID == curr_msg->type->id &&
- !H5F_addr_defined(((H5O_cont_t *)(curr_msg->native))->addr)) {
- /* We now allocate disk space on insertion, instead
- * of on flush from the cache, so this case is now an
- * error. -- JRM
- */
- HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, FAIL,
- "File space for message not allocated!?!");
- }
-
- /*
- * Encode the message. If the message is shared then we
- * encode a Shared Object message instead of the object
- * which is being shared.
- */
- assert(curr_msg->raw >=
- oh->chunk[curr_msg->chunkno].image);
- assert (curr_msg->raw_size ==
- H5O_ALIGN (curr_msg->raw_size));
- assert(curr_msg->raw + curr_msg->raw_size <=
- oh->chunk[curr_msg->chunkno].image +
- oh->chunk[curr_msg->chunkno].size);
- if (curr_msg->flags & H5O_FLAG_SHARED) {
- encode = H5O_SHARED->encode;
- } else {
- encode = curr_msg->type->encode;
- }
- if ((encode)(f, curr_msg->raw, curr_msg->native)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message");
- }
- curr_msg->dirty = FALSE;
- oh->chunk[curr_msg->chunkno].dirty = TRUE;
- }
- }
-
- /* write each chunk to disk */
- for (u = 0; u < oh->nchunks; u++) {
- if (oh->chunk[u].dirty) {
- assert(H5F_addr_defined(oh->chunk[u].addr));
- if(u==0 && combine) {
- /* Allocate space for the combined prefix and first chunk */
- if((p=H5FL_BLK_MALLOC(chunk_image,(H5O_SIZEOF_HDR(f)+oh->chunk[u].size)))==NULL)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
-
- /* Copy in the prefix */
- HDmemcpy(p,buf,(size_t)H5O_SIZEOF_HDR(f));
-
- /* Copy in the first chunk */
- HDmemcpy(p+H5O_SIZEOF_HDR(f),oh->chunk[u].image,oh->chunk[u].size);
-
- /* Write the combined prefix/chunk out */
- if (H5F_block_write(f, H5FD_MEM_OHDR, addr,
- (H5O_SIZEOF_HDR(f)+oh->chunk[u].size),
- dxpl_id, p) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header data to disk");
-
- /* Release the memory for the combined prefix/chunk */
- p = H5FL_BLK_FREE(chunk_image,p);
- } /* end if */
- else {
- if (H5F_block_write(f, H5FD_MEM_OHDR, oh->chunk[u].addr,
- (oh->chunk[u].size),
- dxpl_id, oh->chunk[u].image) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header data to disk");
- } /* end else */
- oh->chunk[u].dirty = FALSE;
- } /* end if */
- } /* end for */
- oh->cache_info.is_dirty = FALSE;
- }
-
- if (destroy) {
- if(H5O_dest(f,oh)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data");
- }
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_dest
- *
- * Purpose: Destroys an object header.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Jan 15 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_dest(H5F_t UNUSED *f, H5O_t *oh)
-{
- unsigned i;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_dest);
-
- /* check args */
- assert(oh);
-
- /* Verify that node is clean */
- assert (oh->cache_info.is_dirty==FALSE);
-
- /* destroy chunks */
- for (i = 0; i < oh->nchunks; i++) {
- /* Verify that chunk is clean */
- assert (oh->chunk[i].dirty==0);
-
- oh->chunk[i].image = H5FL_BLK_FREE(chunk_image,oh->chunk[i].image);
- }
- if(oh->chunk)
- oh->chunk = H5FL_SEQ_FREE(H5O_chunk_t,oh->chunk);
-
- /* destroy messages */
- for (i = 0; i < oh->nmesgs; i++) {
- /* Verify that message is clean */
- assert (oh->mesg[i].dirty==0);
-
- H5O_free_mesg(&oh->mesg[i]);
- }
- if(oh->mesg)
- oh->mesg = H5FL_SEQ_FREE(H5O_mesg_t,oh->mesg);
-
- /* destroy object header */
- H5FL_FREE(H5O_t,oh);
-
- FUNC_LEAVE_NOAPI(SUCCEED);
-} /* end H5O_dest() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_clear
- *
- * Purpose: Mark a object header in memory as non-dirty.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Quincey Koziol
- * koziol@ncsa.uiuc.edu
- * Mar 20 2003
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy)
-{
- unsigned u; /* Local index variable */
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_clear);
-
- /* check args */
- assert(oh);
-
- /* Mark chunks as clean */
- for (u = 0; u < oh->nchunks; u++)
- oh->chunk[u].dirty=FALSE;
-
- /* Mark messages as clean */
- for (u = 0; u < oh->nmesgs; u++)
- oh->mesg[u].dirty=FALSE;
-
- /* Mark whole header as clean */
- oh->cache_info.is_dirty=FALSE;
-
- if (destroy)
- if (H5O_dest(f, oh) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5O_clear() */
-
-
-/*-------------------------------------------------------------------------
- * Function: H5O_compute_size
- *
- * Purpose: Compute the size in bytes of the specified instance of
- * H5O_t on disk, and return it in *len_ptr. On failure,
- * the value of *len_ptr is undefined.
- *
- * The value returned will probably be low unless the object
- * has just been flushed, as we simply total up the size of
- * the header with the sizes of the chunks. Thus any message
- * that has been added since the last flush will not be
- * reflected in the total.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: John Mainzer
- * 5/13/04
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_compute_size(const H5F_t *f, const H5O_t *oh, size_t *size_ptr)
-{
- unsigned u;
- size_t size;
-
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_compute_size);
-
- /* check args */
- HDassert(f);
- HDassert(oh);
- HDassert(size_ptr);
-
- size = H5O_SIZEOF_HDR(f);
-
- for (u = 0; u < oh->nchunks; u++)
- size += oh->chunk[u].size;
-
- HDassert(size >= H5O_SIZEOF_HDR(f));
-
- *size_ptr = size;
-
- FUNC_LEAVE_NOAPI(SUCCEED);
-} /* H5O_compute_size() */
-
-
-/*-------------------------------------------------------------------------
* Function: H5O_reset
*
* Purpose: Some message data structures have internal fields that
@@ -1018,12 +641,12 @@ H5O_reset(unsigned type_id, void *native)
FUNC_ENTER_NOAPI(H5O_reset,FAIL);
/* check args */
- assert(type_id<NELMTS(message_type_g));
+ assert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
/* Call the "real" reset routine */
- if((ret_value=H5O_reset_real(type, native))<0)
+ if((ret_value=H5O_reset_real(type, native)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_READERROR, FAIL, "unable to reset object header");
done:
@@ -1098,7 +721,7 @@ H5O_free (unsigned type_id, void *mesg)
FUNC_ENTER_NOAPI(H5O_free, NULL);
/* check args */
- assert(type_id<NELMTS(message_type_g));
+ assert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
@@ -1122,7 +745,7 @@ done:
*
*-------------------------------------------------------------------------
*/
-static herr_t
+herr_t
H5O_free_mesg(H5O_mesg_t *mesg)
{
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_free_mesg)
@@ -1153,8 +776,6 @@ H5O_free_mesg(H5O_mesg_t *mesg)
* Programmer: Robb Matzke
* Thursday, May 21, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
void *
@@ -1163,15 +784,15 @@ H5O_free_real(const H5O_class_t *type, void *msg_native)
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_free_real)
/* check args */
- assert(type);
+ HDassert(type);
- if (msg_native) {
+ if(msg_native) {
H5O_reset_real(type, msg_native);
if (NULL!=(type->free))
(type->free)(msg_native);
else
H5MM_xfree (msg_native);
- }
+ } /* end if */
FUNC_LEAVE_NOAPI(NULL)
} /* end H5O_free_real() */
@@ -1207,7 +828,7 @@ H5O_copy (unsigned type_id, const void *mesg, void *dst)
FUNC_ENTER_NOAPI(H5O_copy, NULL);
/* check args */
- assert(type_id<NELMTS(message_type_g));
+ assert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
@@ -1273,91 +894,80 @@ done:
* matzke@llnl.gov
* Aug 5 1997
*
- * Modifications:
- *
- * Robb Matzke, 1998-08-27
- * This function can also be used to obtain the current number of links
- * if zero is passed for ADJUST. If that's the case then we don't check
- * for write access on the file.
- *
- * John Mainzer, 6/6/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
int
-H5O_link(const H5G_entry_t *ent, int adjust, hid_t dxpl_id)
+H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id)
{
H5O_t *oh = NULL;
- unsigned oh_flags=H5AC__NO_FLAGS_SET; /* used to indicate whether the
+ unsigned oh_flags = H5AC__NO_FLAGS_SET; /* used to indicate whether the
* object was deleted as a result
* of this action.
*/
int ret_value = FAIL;
- FUNC_ENTER_NOAPI(H5O_link, FAIL);
+ FUNC_ENTER_NOAPI(H5O_link, FAIL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- if (adjust!=0 && 0==(ent->file->intent & H5F_ACC_RDWR))
- HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file");
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ if(adjust != 0 && 0 == (loc->file->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file")
/* get header */
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header,
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr,
NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* adjust link count */
- if (adjust<0) {
- if (oh->nlink + adjust < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "link count would be negative");
+ if(adjust < 0) {
+ if(oh->nlink + adjust < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINKCOUNT, FAIL, "link count would be negative")
oh->nlink += adjust;
oh_flags |= H5AC__DIRTIED_FLAG;
/* Check if the object should be deleted */
- if(oh->nlink==0) {
+ if(oh->nlink == 0) {
/* Check if the object is still open by the user */
- if(H5FO_opened(ent->file,ent->header)!=NULL) {
+ if(H5FO_opened(loc->file, loc->addr) != NULL) {
/* Flag the object to be deleted when it's closed */
- if(H5FO_mark(ent->file,ent->header,TRUE)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion");
+ if(H5FO_mark(loc->file, loc->addr, TRUE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion")
} /* end if */
else {
/* Delete object right now */
- if(H5O_delete_oh(ent->file,dxpl_id,oh)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file");
+ if(H5O_delete_oh(loc->file, dxpl_id, oh) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file")
/* Mark the object header as deleted */
oh_flags = H5C__DELETED_FLAG;
} /* end else */
} /* end if */
- } else if (adjust>0) {
+ } else if (adjust > 0) {
/* A new object, or one that will be deleted */
- if(oh->nlink==0) {
+ if(oh->nlink == 0) {
/* Check if the object is current open, but marked for deletion */
- if(H5FO_marked(ent->file,ent->header)>0) {
+ if(H5FO_marked(loc->file, loc->addr) > 0) {
/* Remove "delete me" flag on the object */
- if(H5FO_mark(ent->file,ent->header,FALSE)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion");
+ if(H5FO_mark(loc->file, loc->addr, FALSE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't mark object for deletion")
} /* end if */
} /* end if */
oh->nlink += adjust;
oh_flags |= H5AC__DIRTIED_FLAG;
- }
+ } /* end if */
/* Set return value */
ret_value = oh->nlink;
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if (oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_link() */
/*-------------------------------------------------------------------------
@@ -1373,36 +983,30 @@ done:
* Programmer: Robb Matzke
* Tuesday, April 21, 1998
*
- * Modifications:
- * Changed to use IDs for types, instead of type objects, then
- * call "real" routine.
- * Quincey Koziol
- * Feb 14 2003
- *
*-------------------------------------------------------------------------
*/
int
-H5O_count (H5G_entry_t *ent, unsigned type_id, hid_t dxpl_id)
+H5O_count(H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id)
{
const H5O_class_t *type; /* Actual H5O class type for the ID */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_count, FAIL);
+ FUNC_ENTER_NOAPI(H5O_count, FAIL)
/* Check args */
- assert (ent);
- assert (ent->file);
- assert (H5F_addr_defined(ent->header));
- assert(type_id<NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
- assert (type);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type_id < NELMTS(message_type_g));
+ type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(type);
/* Call the "real" count routine */
- if((ret_value=H5O_count_real(ent, type, dxpl_id))<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to count object header messages");
+ if((ret_value = H5O_count_real(loc, type, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOUNT, FAIL, "unable to count object header messages")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_count() */
@@ -1419,43 +1023,41 @@ done:
* Programmer: Robb Matzke
* Tuesday, April 21, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static int
-H5O_count_real (H5G_entry_t *ent, const H5O_class_t *type, hid_t dxpl_id)
+H5O_count_real(H5O_loc_t *loc, const H5O_class_t *type, hid_t dxpl_id)
{
H5O_t *oh = NULL;
int acc;
unsigned u;
int ret_value;
- FUNC_ENTER_NOAPI(H5O_count_real, FAIL);
+ FUNC_ENTER_NOAPI(H5O_count_real, FAIL)
/* Check args */
- assert (ent);
- assert (ent->file);
- assert (H5F_addr_defined(ent->header));
- assert (type);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type);
/* Load the object header */
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Loop over all messages, counting the ones of the type looked for */
- for (u=acc=0; u<oh->nmesgs; u++)
- if (oh->mesg[u].type==type)
+ for(u = acc = 0; u < oh->nmesgs; u++)
+ if(oh->mesg[u].type == type)
acc++;
/* Set return value */
- ret_value=acc;
+ ret_value = acc;
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, H5AC__NO_FLAGS_SET) != SUCCEED)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if (oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) != SUCCEED)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_count_real() */
@@ -1475,35 +1077,29 @@ done:
* Programmer: Robb Matzke
* Monday, November 2, 1998
*
- * Modifications:
- * Changed to use IDs for types, instead of type objects, then
- * call "real" routine.
- * Quincey Koziol
- * Feb 14 2003
- *
*-------------------------------------------------------------------------
*/
htri_t
-H5O_exists(H5G_entry_t *ent, unsigned type_id, int sequence, hid_t dxpl_id)
+H5O_exists(H5O_loc_t *loc, unsigned type_id, int sequence, hid_t dxpl_id)
{
const H5O_class_t *type; /* Actual H5O class type for the ID */
htri_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_exists, FAIL);
+ FUNC_ENTER_NOAPI(H5O_exists, FAIL)
- assert(ent);
- assert(ent->file);
- assert(type_id<NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
- assert(type);
- assert(sequence>=0);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(type_id < NELMTS(message_type_g));
+ type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(type);
+ HDassert(sequence >= 0);
/* Call the "real" exists routine */
- if((ret_value=H5O_exists_real(ent, type, sequence, dxpl_id))<0)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, FAIL, "unable to verify object header message");
+ if((ret_value = H5O_exists_real(loc, type, sequence, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, FAIL, "unable to verify object header message")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_exists() */
@@ -1523,48 +1119,42 @@ done:
* Programmer: Robb Matzke
* Monday, November 2, 1998
*
- * Modifications:
- *
- * John Mainzer, 6/6/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
static htri_t
-H5O_exists_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence, hid_t dxpl_id)
+H5O_exists_real(H5O_loc_t *loc, const H5O_class_t *type, int sequence, hid_t dxpl_id)
{
- H5O_t *oh=NULL;
+ H5O_t *oh = NULL;
unsigned u;
htri_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_exists_real);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_exists_real)
- assert(ent);
- assert(ent->file);
- assert(type);
- assert(sequence>=0);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(type);
+ HDassert(sequence >= 0);
/* Load the object header */
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Scan through the messages looking for the right one */
- for (u=0; u<oh->nmesgs; u++) {
- if (type->id!=oh->mesg[u].type->id)
+ for(u = 0; u < oh->nmesgs; u++) {
+ if(type->id != oh->mesg[u].type->id)
continue;
- if (--sequence<0)
+ if(--sequence < 0)
break;
- }
+ } /* end for */
/* Set return value */
- ret_value=(sequence<0);
+ ret_value = (sequence < 0);
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, H5AC__NO_FLAGS_SET) != SUCCEED)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) != SUCCEED)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_exists_real() */
@@ -1589,37 +1179,31 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
- * Modifications:
- * Changed to use IDs for types, instead of type objects, then
- * call "real" routine.
- * Quincey Koziol
- * Feb 14 2003
- *
*-------------------------------------------------------------------------
*/
void *
-H5O_read(const H5G_entry_t *ent, unsigned type_id, int sequence, void *mesg, hid_t dxpl_id)
+H5O_read(const H5O_loc_t *loc, unsigned type_id, int sequence, void *mesg, hid_t dxpl_id)
{
const H5O_class_t *type; /* Actual H5O class type for the ID */
void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_read, NULL);
+ FUNC_ENTER_NOAPI(H5O_read, NULL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- assert(type_id<NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
- assert(type);
- assert(sequence >= 0);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type_id < NELMTS(message_type_g));
+ type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(type);
+ HDassert(sequence >= 0);
/* Call the "real" read routine */
- if((ret_value=H5O_read_real(ent, type, sequence, mesg, dxpl_id))==NULL)
- HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to load object header");
+ if((ret_value = H5O_read_real(loc, type, sequence, mesg, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to load object header")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_read() */
@@ -1644,58 +1228,33 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
- * Modifications:
- *
- * Bill Wendling, 2003-09-30
- * Protect the object header and pass it into the H5O_find_in_ohdr
- * function. This is done because the H5O_find_in_ohdr used to
- * protect the ohdr, find the message, and then unprotect it. This
- * saves time and also helps the FPHDF5 stuff, where unprotecting
- * actually destroys the object in the cache.
- *
- * John Mainzer, 6/6/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
void *
-H5O_read_real(const H5G_entry_t *ent, const H5O_class_t *type, int sequence, void *mesg, hid_t dxpl_id)
+H5O_read_real(const H5O_loc_t *loc, const H5O_class_t *type, int sequence, void *mesg, hid_t dxpl_id)
{
H5O_t *oh = NULL;
int idx;
- const H5G_cache_t *cache = NULL;
- H5G_type_t cache_type;
void *ret_value = NULL;
- FUNC_ENTER_NOAPI_NOINIT(H5O_read_real);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_read_real)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- assert(type);
- assert(sequence >= 0);
-
- /* can we get it from the symbol table entry? */
- cache = H5G_ent_cache(ent, &cache_type);
-
- if (H5O_fast_g[cache_type]) {
- ret_value = (H5O_fast_g[cache_type]) (cache, type, mesg);
- if (ret_value)
- HGOTO_DONE(ret_value);
- H5E_clear_stack(NULL); /*don't care, try reading from header */
- }
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type);
+ HDassert(sequence >= 0);
/* copy the message to the user-supplied buffer */
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header")
/* can we get it from the object header? */
- if ((idx = H5O_find_in_ohdr(ent->file, dxpl_id, oh, &type, sequence)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, NULL, "unable to find message in object header");
+ if((idx = H5O_find_in_ohdr(loc->file, dxpl_id, oh, &type, sequence)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, NULL, "unable to find message in object header")
- if (oh->mesg[idx].flags & H5O_FLAG_SHARED) {
+ if(oh->mesg[idx].flags & H5O_FLAG_SHARED) {
/*
* If the message is shared then then the native pointer points to an
* H5O_SHARED message. We use that information to look up the real
@@ -1704,7 +1263,7 @@ H5O_read_real(const H5G_entry_t *ent, const H5O_class_t *type, int sequence, voi
H5O_shared_t *shared;
shared = (H5O_shared_t *)(oh->mesg[idx].native);
- ret_value=H5O_shared_read(ent->file,dxpl_id,shared,type,mesg);
+ ret_value = H5O_shared_read(loc->file, dxpl_id, shared, type, mesg);
} else {
/*
* The message is not shared, but rather exists in the object
@@ -1712,15 +1271,15 @@ H5O_read_real(const H5G_entry_t *ent, const H5O_class_t *type, int sequence, voi
* the raw message) so we must copy the native message before
* returning.
*/
- if (NULL==(ret_value = (type->copy) (oh->mesg[idx].native, mesg, 0)))
- HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy message to user space");
- }
+ if(NULL==(ret_value = (type->copy) (oh->mesg[idx].native, mesg, 0)))
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to copy message to user space")
+ } /* end else */
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, NULL, "unable to release object header");
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, NULL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_read_real() */
@@ -1750,7 +1309,6 @@ static unsigned
H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p, int sequence)
{
unsigned u;
- const H5O_class_t *type = NULL;
unsigned ret_value;
FUNC_ENTER_NOAPI_NOINIT(H5O_find_in_ohdr);
@@ -1775,17 +1333,7 @@ H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p,
* Decode the message if necessary. If the message is shared then decode
* a shared message, ignoring the message type.
*/
- if (oh->mesg[u].flags & H5O_FLAG_SHARED)
- type = H5O_SHARED;
- else
- type = oh->mesg[u].type;
-
- if (NULL == oh->mesg[u].native) {
- assert(type->decode);
- oh->mesg[u].native = (type->decode) (f, dxpl_id, oh->mesg[u].raw, NULL);
- if (NULL == oh->mesg[u].native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, UFAIL, "unable to decode message");
- }
+ LOAD_NATIVE(f, dxpl_id, &(oh->mesg[u]))
/*
* Return the message type. If this is a shared message then return the
@@ -1833,45 +1381,33 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
- * Modifications:
- *
- * Robb Matzke, 7 Jan 1998
- * Handles constant vs non-constant messages. Once a message is made
- * constant it can never become non-constant. Constant messages cannot
- * be modified.
- *
- * Changed to use IDs for types, instead of type objects, then
- * call "real" routine.
- * Quincey Koziol
- * Feb 14 2003
- *
*-------------------------------------------------------------------------
*/
int
-H5O_modify(H5G_entry_t *ent, unsigned type_id, int overwrite,
+H5O_modify(H5O_loc_t *loc, unsigned type_id, int overwrite,
unsigned flags, unsigned update_flags, const void *mesg, hid_t dxpl_id)
{
const H5O_class_t *type; /* Actual H5O class type for the ID */
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_modify, FAIL);
+ FUNC_ENTER_NOAPI(H5O_modify, FAIL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- assert(type_id<NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
- assert(type);
- assert(mesg);
- assert (0==(flags & ~H5O_FLAG_BITS));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type_id < NELMTS(message_type_g));
+ type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(type);
+ HDassert(mesg);
+ HDassert(0 == (flags & ~H5O_FLAG_BITS));
/* Call the "real" modify routine */
- if((ret_value= H5O_modify_real(ent, type, overwrite, flags, update_flags, mesg, dxpl_id))<0)
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header");
+ if((ret_value = H5O_modify_real(loc, type, overwrite, flags, update_flags, mesg, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header message")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_modify() */
@@ -1907,25 +1443,13 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
- * Modifications:
- *
- * Robb Matzke, 7 Jan 1998
- * Handles constant vs non-constant messages. Once a message is made
- * constant it can never become non-constant. Constant messages cannot
- * be modified.
- *
- * John Mainzer, 6/6/05
- * Updated function to use the new dirtied parameter of
- * H5AC_unprotect() instead of manipulating the is_dirty
- * field of the cache info directly.
- *
*-------------------------------------------------------------------------
*/
static int
-H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
+H5O_modify_real(H5O_loc_t *loc, const H5O_class_t *type, int overwrite,
unsigned flags, unsigned update_flags, const void *mesg, hid_t dxpl_id)
{
- H5O_t *oh=NULL;
+ H5O_t *oh = NULL;
unsigned oh_flags = H5AC__NO_FLAGS_SET;
int sequence;
unsigned idx; /* Index of message to modify */
@@ -1936,67 +1460,67 @@ H5O_modify_real(H5G_entry_t *ent, const H5O_class_t *type, int overwrite,
FUNC_ENTER_NOAPI_NOINIT(H5O_modify_real)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- assert(type);
- assert(mesg);
- assert (0==(flags & ~H5O_FLAG_BITS));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type);
+ HDassert(mesg);
+ HDassert(0 == (flags & ~H5O_FLAG_BITS));
- if (0==(ent->file->intent & H5F_ACC_RDWR))
- HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file");
+ if(0 == (loc->file->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file")
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Count similar messages */
- for (idx = 0, sequence = -1, idx_msg=&oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++) {
- if (type->id != idx_msg->type->id)
+ for(idx = 0, sequence = -1, idx_msg=&oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++) {
+ if(type->id != idx_msg->type->id)
continue;
- if (++sequence == overwrite)
+ if(++sequence == overwrite)
break;
} /* end for */
/* Was the right message found? */
- if (overwrite >= 0 && (idx >= oh->nmesgs || sequence != overwrite)) {
+ if(overwrite >= 0 && (idx >= oh->nmesgs || sequence != overwrite)) {
/* But can we insert a new one with this sequence number? */
- if (overwrite == sequence + 1)
+ if(overwrite == sequence + 1)
overwrite = -1;
else
- HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message not found");
+ HGOTO_ERROR(H5E_OHDR, H5E_NOTFOUND, FAIL, "message not found")
} /* end if */
/* Check for creating new message */
- if (overwrite < 0) {
+ if(overwrite < 0) {
/* Create a new message */
- if((idx=H5O_new_mesg(ent->file,oh,&flags,type,mesg,&sh_mesg,&type,&mesg,dxpl_id,&oh_flags))==UFAIL)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message");
+ if((idx = H5O_new_mesg(loc->file, oh, &flags, type, mesg, &sh_mesg, &type, &mesg, dxpl_id, &oh_flags)) == UFAIL)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message")
/* Set the correct sequence number for the message created */
sequence++;
- } else if (oh->mesg[idx].flags & H5O_FLAG_CONSTANT) {
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify constant message");
- } else if (oh->mesg[idx].flags & H5O_FLAG_SHARED) {
- HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify shared (constant) message");
+ } else if(oh->mesg[idx].flags & H5O_FLAG_CONSTANT) {
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify constant message")
+ } else if(oh->mesg[idx].flags & H5O_FLAG_SHARED) {
+ HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to modify shared (constant) message")
}
/* Write the information to the message */
- if(H5O_write_mesg(oh,idx,type,mesg,flags,update_flags,&oh_flags)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to write message");
+ if(H5O_write_mesg(oh, idx, type, mesg, flags, update_flags, &oh_flags) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to write message")
/* Update the modification time message if any */
- if(update_flags&H5O_UPDATE_TIME)
- H5O_touch_oh(ent->file, dxpl_id, oh, FALSE, &oh_flags);
+ if(update_flags & H5O_UPDATE_TIME)
+ H5O_touch_oh(loc->file, dxpl_id, oh, FALSE, &oh_flags);
/* Set return value */
ret_value = sequence;
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_modify_real() */
@@ -2016,30 +1540,28 @@ done:
* koziol@ncsa.uiuc.edu
* Dec 31 2002
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
H5O_t *
-H5O_protect(H5G_entry_t *ent, hid_t dxpl_id)
+H5O_protect(H5O_loc_t *loc, hid_t dxpl_id)
{
H5O_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_protect, NULL);
+ FUNC_ENTER_NOAPI(H5O_protect, NULL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
- if (0==(ent->file->intent & H5F_ACC_RDWR))
- HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, NULL, "no write intent on file");
+ if(0 == (loc->file->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR (H5E_OHDR, H5E_WRITEERROR, NULL, "no write intent on file")
- if (NULL == (ret_value = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header");
+ if(NULL == (ret_value = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unable to load object header")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_protect() */
@@ -2058,33 +1580,26 @@ done:
* koziol@ncsa.uiuc.edu
* Dec 31 2002
*
- * Modifications:
- *
- * John Mainzer, 6/6/05
- * Updated function to use the new dirtied parameter of
- * H5AC_unprotect() instead of manipulating the is_dirty
- * field of the cache info directly.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_unprotect(H5G_entry_t *ent, H5O_t *oh, hid_t dxpl_id, unsigned oh_flags)
+H5O_unprotect(H5O_loc_t *loc, H5O_t *oh, hid_t dxpl_id, unsigned oh_flags)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_unprotect, FAIL);
+ FUNC_ENTER_NOAPI(H5O_unprotect, FAIL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- assert(oh);
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(oh);
- if (H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_unprotect() */
@@ -2128,7 +1643,7 @@ H5O_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, unsigned flags,
/* check args */
assert(f);
assert(oh);
- assert(type_id<NELMTS(message_type_g));
+ assert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
assert(0==(flags & ~H5O_FLAG_BITS));
@@ -2136,7 +1651,7 @@ H5O_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, unsigned flags,
assert(oh_flags_ptr);
/* Call the "real" append routine */
- if((ret_value=H5O_append_real( f, dxpl_id, oh, type, flags, mesg, oh_flags_ptr))<0)
+ if((ret_value=H5O_append_real( f, dxpl_id, oh, type, flags, mesg, oh_flags_ptr)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to append to object header");
done:
@@ -2159,13 +1674,6 @@ done:
* koziol@ncsa.uiuc.edu
* Dec 31 2002
*
- * Modifications:
- *
- * John Mainzer, 6/6/05
- * Updated function to use the new dirtied parameter of
- * H5AC_unprotect() instead of manipulating the is_dirty
- * of the cache info.
- *
*-------------------------------------------------------------------------
*/
static int
@@ -2191,7 +1699,7 @@ H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t *type,
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to create new message");
/* Write the information to the message */
- if(H5O_write_mesg(oh,idx,type,mesg,flags,0,oh_flags_ptr)<0)
+ if(H5O_write_mesg(oh,idx,type,mesg,flags,0,oh_flags_ptr) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to write message");
/* Set return value */
@@ -2213,14 +1721,6 @@ done:
* Programmer: Quincey Koziol
* Friday, September 3, 2003
*
- * Modifications:
- *
- * John Mainzer, 6/7/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- * In this case, that requires the addition of the oh_dirtied_ptr
- * parameter to track whether *oh is dirty.
- *
*-------------------------------------------------------------------------
*/
static unsigned
@@ -2250,7 +1750,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_class_t *orig_type,
if (NULL==orig_type->get_share)
HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, UFAIL, "message class is not sharable");
- if ((orig_type->get_share)(f, orig_mesg, sh_mesg/*out*/)<0) {
+ if ((orig_type->get_share)(f, orig_mesg, sh_mesg/*out*/) < 0) {
/*
* If the message isn't shared then turn off the shared bit
* and treat it as an unshared message.
@@ -2270,14 +1770,14 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_class_t *orig_type,
/* Compute the size needed to store the message on disk */
if ((size = ((*new_type)->raw_size) (f, *new_mesg)) >=H5O_MAX_SIZE)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, UFAIL, "object header message is too large (16k max)");
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, UFAIL, "object header message is too large");
/* Allocate space in the object headed for the message */
if ((ret_value = H5O_alloc(f, dxpl_id, oh, orig_type, size, oh_flags_ptr)) == UFAIL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, UFAIL, "unable to allocate space for message");
/* Increment any links in message */
- if((*new_type)->link && ((*new_type)->link)(f,dxpl_id,(*new_mesg))<0)
+ if((*new_type)->link && ((*new_type)->link)(f,dxpl_id,(*new_mesg)) < 0)
HGOTO_ERROR (H5E_OHDR, H5E_LINK, UFAIL, "unable to adjust shared object link count");
done:
@@ -2353,18 +1853,6 @@ done:
* Programmer: Robb Matzke
* Monday, July 27, 1998
*
- * Modifications:
- *
- * John Mainzer, 6/6/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- * In this case, that requires the addition of the oh_dirtied_ptr
- * parameter to track whether *oh is dirty.
- *
- * John Mainzer, 8/20/05
- * Added dxpl_id parameter needed by the revised version of
- * H5O_alloc().
- *
*-------------------------------------------------------------------------
*/
herr_t
@@ -2375,9 +1863,6 @@ H5O_touch_oh(H5F_t *f,
unsigned * oh_flags_ptr)
{
unsigned idx;
-#ifdef H5_HAVE_GETTIMEOFDAY
- struct timeval now_tv;
-#endif /* H5_HAVE_GETTIMEOFDAY */
time_t now;
size_t size;
herr_t ret_value=SUCCEED; /* Return value */
@@ -2388,14 +1873,18 @@ H5O_touch_oh(H5F_t *f,
assert(oh_flags_ptr);
/* Look for existing message */
- for (idx=0; idx<oh->nmesgs; idx++) {
+ for (idx=0; idx < oh->nmesgs; idx++) {
if (H5O_MTIME==oh->mesg[idx].type || H5O_MTIME_NEW==oh->mesg[idx].type)
break;
}
#ifdef H5_HAVE_GETTIMEOFDAY
- HDgettimeofday(&now_tv,NULL);
- now=now_tv.tv_sec;
+ {
+ struct timeval now_tv;
+
+ HDgettimeofday(&now_tv, NULL);
+ now = now_tv.tv_sec;
+ }
#else /* H5_HAVE_GETTIMEOFDAY */
now = HDtime(NULL);
#endif /* H5_HAVE_GETTIMEOFDAY */
@@ -2447,35 +1936,35 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_touch(H5G_entry_t *ent, hbool_t force, hid_t dxpl_id)
+H5O_touch(H5O_loc_t *loc, hbool_t force, hid_t dxpl_id)
{
H5O_t *oh = NULL;
unsigned oh_flags = H5AC__NO_FLAGS_SET;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_touch, FAIL);
+ FUNC_ENTER_NOAPI(H5O_touch, FAIL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
- if (0==(ent->file->intent & H5F_ACC_RDWR))
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file");
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ if(0 == (loc->file->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Get the object header */
- if (NULL==(oh=H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Create/Update the modification time message */
- if (H5O_touch_oh(ent->file, dxpl_id, oh, force, &oh_flags)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to update object modificaton time");
+ if(H5O_touch_oh(loc->file, dxpl_id, oh, force, &oh_flags) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to update object modificaton time")
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags)<0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_touch() */
#ifdef H5O_ENABLE_BOGUS
@@ -2490,46 +1979,35 @@ done:
* <koziol@ncsa.uiuc.edu>
* Tuesday, January 21, 2003
*
- * Modifications:
- *
- * John Mainzer, 6/16/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- * In this case, that requires the addition of the oh_dirtied_ptr
- * parameter to track whether *oh is dirty.
- *
- * John Mainzer, 8/20/05
- * Added dxpl_id parameter needed by call to H5O_alloc().
- *
*-------------------------------------------------------------------------
*/
herr_t
H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t * oh_flags_ptr)
{
int idx;
- size_t size;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER(H5O_bogus_oh, FAIL);
+ FUNC_ENTER(H5O_bogus_oh, FAIL)
- assert(f);
- assert(oh);
- assert(oh_flags_ptr);
+ HDassert(f);
+ HDassert(oh);
+ HDassert(oh_flags_ptr);
/* Look for existing message */
- for (idx=0; idx<oh->nmesgs; idx++)
- if (H5O_BOGUS==oh->mesg[idx].type)
+ for(idx = 0; idx < oh->nmesgs; idx++)
+ if(H5O_BOGUS == oh->mesg[idx].type)
break;
/* Create a new message */
- if (idx==oh->nmesgs) {
- size = (H5O_BOGUS->raw_size)(f, NULL);
- if ((idx=H5O_alloc(f, dxpl_id, oh, H5O_BOGUS, size, oh_flags_ptr))<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for 'bogus' message");
+ if(idx == oh->nmesgs) {
+ size_t size = (H5O_BOGUS->raw_size)(f, NULL);
+
+ if((idx = H5O_alloc(f, dxpl_id, oh, H5O_BOGUS, size, oh_flags_ptr)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for 'bogus' message")
/* Allocate the native message in memory */
- if (NULL==(oh->mesg[idx].native = H5MM_malloc(sizeof(H5O_bogus_t))))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "memory allocation failed for 'bogus' message");
+ if(NULL == (oh->mesg[idx].native = H5MM_malloc(sizeof(H5O_bogus_t))))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "memory allocation failed for 'bogus' message")
/* Update the native part */
((H5O_bogus_t *)(oh->mesg[idx].native))->u = H5O_BOGUS_VALUE;
@@ -2541,7 +2019,7 @@ H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t * oh_flags_ptr)
} /* end if */
done:
- FUNC_LEAVE(ret_value);
+ FUNC_LEAVE(ret_value)
} /* end H5O_bogus_oh() */
@@ -2556,45 +2034,39 @@ done:
* <koziol@ncsa.uiuc.edu>
* Tuesday, January 21, 2003
*
- * Modifications:
- *
- * John Mainzer, 6/16/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_bogus(H5G_entry_t *ent, hid_t dxpl_id)
+H5O_bogus(H5O_loc_t *loc, hid_t dxpl_id)
{
H5O_t *oh = NULL;
unsigned oh_flags = H5AC__NO_FLAGS_SET;
herr_t ret_value = SUCCEED;
- FUNC_ENTER(H5O_bogus, FAIL);
+ FUNC_ENTER(H5O_bogus, FAIL)
/* check args */
- assert(ent);
- assert(ent->file);
- assert(H5F_addr_defined(ent->header));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
/* Verify write access to the file */
- if (0==(ent->file->intent & H5F_ACC_RDWR))
- HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file");
+ if(0 == (loc->file->intent & H5F_ACC_RDWR))
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Get the object header */
- if (NULL==(oh=H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Create the "bogus" message */
- if (H5O_bogus_oh(ent->file, dxpl_id, oh, &oh_flags)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to update object 'bogus' message");
+ if(H5O_bogus_oh(ent->file, dxpl_id, oh, &oh_flags) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to update object 'bogus' message")
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags)<0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE(ret_value);
+ FUNC_LEAVE(ret_value)
} /* end H5O_bogus() */
#endif /* H5O_ENABLE_BOGUS */
@@ -2630,7 +2102,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_remove(H5G_entry_t *ent, unsigned type_id, int sequence, hbool_t adj_link, hid_t dxpl_id)
+H5O_remove(H5O_loc_t *loc, unsigned type_id, int sequence, hbool_t adj_link, hid_t dxpl_id)
{
const H5O_class_t *type; /* Actual H5O class type for the ID */
herr_t ret_value; /* Return value */
@@ -2638,15 +2110,15 @@ H5O_remove(H5G_entry_t *ent, unsigned type_id, int sequence, hbool_t adj_link, h
FUNC_ENTER_NOAPI(H5O_remove, FAIL)
/* check args */
- HDassert(ent);
- HDassert(ent->file);
- HDassert(H5F_addr_defined(ent->header));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
HDassert(type_id < NELMTS(message_type_g));
type = message_type_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
/* Call the "real" remove routine */
- if((ret_value = H5O_remove_real(ent, type, sequence, NULL, NULL, adj_link, dxpl_id))<0)
+ if((ret_value = H5O_remove_real(loc, type, sequence, NULL, NULL, adj_link, dxpl_id)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to remove object header message")
done:
@@ -2672,7 +2144,7 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_remove_op(H5G_entry_t *ent, unsigned type_id,
+H5O_remove_op(const H5O_loc_t *loc, unsigned type_id, int sequence,
H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id)
{
const H5O_class_t *type; /* Actual H5O class type for the ID */
@@ -2681,15 +2153,15 @@ H5O_remove_op(H5G_entry_t *ent, unsigned type_id,
FUNC_ENTER_NOAPI(H5O_remove_op, FAIL)
/* check args */
- HDassert(ent);
- HDassert(ent->file);
- HDassert(H5F_addr_defined(ent->header));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
HDassert(type_id < NELMTS(message_type_g));
type = message_type_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
/* Call the "real" remove routine */
- if((ret_value = H5O_remove_real(ent, type, H5O_ALL, op, op_data, adj_link, dxpl_id))<0)
+ if((ret_value = H5O_remove_real(loc, type, sequence, op, op_data, adj_link, dxpl_id)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to remove object header message")
done:
@@ -2710,8 +2182,6 @@ done:
* koziol@ncsa.uiuc.edu
* Sep 6 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -2731,12 +2201,12 @@ H5O_remove_cb(H5O_mesg_t *mesg/*in,out*/, unsigned idx, unsigned * oh_flags_ptr,
if(udata->op) {
/* Call the iterator callback */
if((try_remove = (udata->op)(mesg->native, idx, udata->op_data)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, H5O_ITER_ERROR, "unable to delete file space for object header message")
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, H5O_ITER_ERROR, "object header message deletion callback failed")
} /* end if */
else {
/* If there's no callback routine, does the sequence # match? */
- if ((int)idx == udata->sequence || H5O_ALL == udata->sequence)
- try_remove = TRUE;
+ if((int)idx == udata->sequence || H5O_ALL == udata->sequence)
+ try_remove = H5O_ITER_STOP;
} /* end else */
/* Try removing the message, if indicated */
@@ -2745,12 +2215,12 @@ H5O_remove_cb(H5O_mesg_t *mesg/*in,out*/, unsigned idx, unsigned * oh_flags_ptr,
* Keep track of how many times we failed trying to remove constant
* messages.
*/
- if (mesg->flags & H5O_FLAG_CONSTANT) {
+ if(mesg->flags & H5O_FLAG_CONSTANT) {
udata->nfailed++;
} /* end if */
else {
/* Free any space referred to in the file from this message */
- if(H5O_delete_mesg(udata->f, udata->dxpl_id, mesg, udata->adj_link)<0)
+ if(H5O_delete_mesg(udata->f, udata->dxpl_id, mesg, udata->adj_link) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, H5O_ITER_ERROR, "unable to delete file space for object header message")
/* Free any native information */
@@ -2768,7 +2238,7 @@ H5O_remove_cb(H5O_mesg_t *mesg/*in,out*/, unsigned idx, unsigned * oh_flags_ptr,
} /* end else */
/* Break out now, if we've found the correct message */
- if(udata->sequence != H5O_ALL)
+ if(udata->sequence == H5O_FIRST || udata->sequence != H5O_ALL)
HGOTO_DONE(H5O_ITER_STOP)
} /* end if */
@@ -2795,19 +2265,10 @@ done:
* matzke@llnl.gov
* Aug 28 1997
*
- * Modifications:
- *
- * Robb Matzke, 7 Jan 1998
- * Does not remove constant messages.
- *
- * John Mainzer, 6/6/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence,
+H5O_remove_real(const H5O_loc_t *loc, const H5O_class_t *type, int sequence,
H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id)
{
H5O_iter_ud1_t udata; /* User data for iterator */
@@ -2816,15 +2277,15 @@ H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence,
FUNC_ENTER_NOAPI_NOINIT(H5O_remove_real)
/* check args */
- HDassert(ent);
- HDassert(ent->file);
+ HDassert(loc);
+ HDassert(loc->file);
HDassert(type);
- if (0==(ent->file->intent & H5F_ACC_RDWR))
+ if (0==(loc->file->intent & H5F_ACC_RDWR))
HGOTO_ERROR (H5E_HEAP, H5E_WRITEERROR, FAIL, "no write intent on file")
/* Set up iterator operator data */
- udata.f = ent->file;
+ udata.f = loc->file;
udata.dxpl_id = dxpl_id;
udata.sequence = sequence;
udata.nfailed = 0;
@@ -2833,11 +2294,11 @@ H5O_remove_real(H5G_entry_t *ent, const H5O_class_t *type, int sequence,
udata.adj_link = adj_link;
/* Iterate over the messages, deleting appropriate one(s) */
- if(H5O_iterate_real(ent, type, H5AC_WRITE, TRUE, (void *)H5O_remove_cb, &udata, dxpl_id) < 0)
+ if(H5O_iterate_real(loc, type, H5AC_WRITE, TRUE, (void *)H5O_remove_cb, &udata, dxpl_id) < 0)
HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "error iterating over messages")
/* Fail if we tried to remove any constant messages */
- if (udata.nfailed)
+ if(udata.nfailed)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to remove constant message(s)")
done:
@@ -2847,6 +2308,517 @@ done:
/*-------------------------------------------------------------------------
*
+ * Function: H5O_move_msgs_forward
+ *
+ * Purpose: Move messages toward first chunk
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Oct 17 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
+{
+ hbool_t packed_msg; /* Flag to indicate that messages were packed */
+ hbool_t did_packing = FALSE; /* Whether any messages were packed */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_move_msgs_forward)
+
+ /* check args */
+ HDassert(oh != NULL);
+
+ /* Loop until no messages packed */
+ /* (Double loop is not very efficient, but it would be some extra work to add
+ * a list of messages to each chunk -QAK)
+ */
+ do {
+ H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
+ unsigned u; /* Local index variable */
+
+ /* Reset packed messages flag */
+ packed_msg = FALSE;
+
+ /* Scan through messages for messages that can be moved earlier in chunks */
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
+ if(H5O_NULL_ID == curr_msg->type->id) {
+ H5O_chunk_t *chunk; /* Pointer to chunk that null message is in */
+
+ /* Check if null message is not last in chunk */
+ chunk = &(oh->chunk[curr_msg->chunkno]);
+ if((curr_msg->raw + curr_msg->raw_size) != (chunk->image + chunk->size)) {
+ H5O_mesg_t *nonnull_msg; /* Pointer to current message to operate on */
+ unsigned v; /* Local index variable */
+
+ /* Loop over messages again, looking for the message in the chunk after the null message */
+ for(v = 0, nonnull_msg = &oh->mesg[0]; v < oh->nmesgs; v++, nonnull_msg++) {
+ /* Locate message that is immediately after the null message */
+ if((curr_msg->chunkno == nonnull_msg->chunkno) &&
+ ((curr_msg->raw + curr_msg->raw_size) == (nonnull_msg->raw - H5O_SIZEOF_MSGHDR(f)))) {
+ /* Don't swap messages if the second message is also a null message */
+ /* (We'll merge them together later, in another routine) */
+ if(H5O_NULL_ID != nonnull_msg->type->id) {
+ /* Make certain non-null message has been translated into native form */
+ /* (So that when we mark it dirty, it will get copied back into raw chunk image) */
+ LOAD_NATIVE(f, dxpl_id, nonnull_msg)
+
+ /* Adjust non-null message's offset in chunk */
+ nonnull_msg->raw = curr_msg->raw;
+
+ /* Adjust null message's offset in chunk */
+ curr_msg->raw = nonnull_msg->raw +
+ nonnull_msg->raw_size + H5O_SIZEOF_MSGHDR(f);
+
+ /* Mark messages dirty */
+ curr_msg->dirty = TRUE;
+ nonnull_msg->dirty = TRUE;
+
+ /* Set the flag to indicate that the null message
+ * was packed - if its not at the end its chunk,
+ * we'll move it again on the next pass.
+ */
+ packed_msg = TRUE;
+ } /* end if */
+
+ /* Break out of loop */
+ break;
+ } /* end if */
+ } /* end for */
+ /* Should have been message after null message */
+ HDassert(v < oh->nmesgs);
+ } /* end if */
+ } /* end if */
+ else {
+ H5O_mesg_t *null_msg; /* Pointer to current message to operate on */
+ unsigned v; /* Local index variable */
+
+ /* Loop over messages again, looking for large enough null message in earlier chunk */
+ for(v = 0, null_msg = &oh->mesg[0]; v < oh->nmesgs; v++, null_msg++) {
+ if(H5O_NULL_ID == null_msg->type->id && curr_msg->chunkno > null_msg->chunkno
+ && curr_msg->raw_size <= null_msg->raw_size) {
+ unsigned old_chunkno; /* Old message information */
+ uint8_t *old_raw;
+ size_t old_raw_size;
+
+ /* Keep old information about non-null message */
+ old_chunkno = curr_msg->chunkno;
+ old_raw = curr_msg->raw;
+ old_raw_size = curr_msg->raw_size;
+
+ /* Make certain non-null message has been translated into native form */
+ /* (So that when we mark it dirty, it will get copied back into raw chunk image) */
+ LOAD_NATIVE(f, dxpl_id, curr_msg)
+
+ /* Change information for non-null message */
+ if(curr_msg->raw_size == null_msg->raw_size) {
+ /* Point non-null message at null message's space */
+ curr_msg->chunkno = null_msg->chunkno;
+ curr_msg->raw = null_msg->raw;
+
+ /* Mark non-null message dirty */
+ curr_msg->dirty = TRUE;
+
+ /* Point null message at old non-null space */
+ /* (Instead of freeing it and allocating new message) */
+ null_msg->chunkno = old_chunkno;
+ null_msg->raw = old_raw;
+
+ /* Mark null message dirty */
+ null_msg->dirty = TRUE;
+ } /* end if */
+ else {
+ unsigned new_null_msg; /* Message index for new null message */
+
+ /* Point non-null message at null message's space */
+ curr_msg->chunkno = null_msg->chunkno;
+ curr_msg->raw = null_msg->raw;
+
+ /* Mark non-null message dirty */
+ curr_msg->dirty = TRUE;
+
+ /* Adjust null message's size & offset */
+ null_msg->raw += curr_msg->raw_size + H5O_SIZEOF_MSGHDR(f);
+ null_msg->raw_size -= curr_msg->raw_size + H5O_SIZEOF_MSGHDR(f);
+
+ /* Mark null message dirty */
+ null_msg->dirty = TRUE;
+
+ /* Create new null message for previous location of non-null message */
+ if(oh->nmesgs >= oh->alloc_nmesgs) {
+ unsigned na = oh->alloc_nmesgs + H5O_NMESGS;
+ H5O_mesg_t *x = H5FL_SEQ_REALLOC(H5O_mesg_t, oh->mesg, (size_t)na);
+
+ if(NULL == x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+ oh->alloc_nmesgs = na;
+ oh->mesg = x;
+ } /* end if */
+
+ /* Get message # for new message */
+ new_null_msg = oh->nmesgs++;
+
+ /* Initialize new null message */
+ oh->mesg[new_null_msg].type = H5O_NULL;
+ oh->mesg[new_null_msg].dirty = TRUE;
+ oh->mesg[new_null_msg].native = NULL;
+ oh->mesg[new_null_msg].raw = old_raw;
+ oh->mesg[new_null_msg].raw_size = old_raw_size;
+ oh->mesg[new_null_msg].chunkno = old_chunkno;
+ } /* end else */
+
+ /* Indicate that we packed messages */
+ packed_msg = TRUE;
+
+ /* Break out of loop */
+ /* (If it's possible to move messge to even ealier chunk
+ * we'll get it on the next pass - QAK)
+ */
+ break;
+ } /* end if */
+ } /* end for */
+
+ /* If we packed messages, get out of loop and start over */
+ /* (Don't know if this has any benefit one way or the other -QAK) */
+ if(packed_msg)
+ break;
+ } /* end else */
+ } /* end for */
+
+ /* If we did any packing, remember that */
+ if(packed_msg)
+ did_packing = TRUE;
+ } while(packed_msg);
+
+ /* Set return value */
+ ret_value = did_packing;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_move_msgs_forward() */
+
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5O_merge_null
+ *
+ * Purpose: Merge neighboring null messages in an object header
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Oct 10 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5O_merge_null(H5F_t *f, H5O_t *oh)
+{
+ hbool_t merged_msg; /* Flag to indicate that messages were merged */
+ hbool_t did_merging = FALSE; /* Whether any messages were merged */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_merge_null)
+
+ /* check args */
+ HDassert(oh != NULL);
+
+ /* Loop until no messages merged */
+ /* (Double loop is not very efficient, but it would be some extra work to add
+ * a list of messages to each chunk -QAK)
+ */
+ do {
+ H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
+ unsigned u; /* Local index variable */
+
+ /* Reset merged messages flag */
+ merged_msg = FALSE;
+
+ /* Scan messages for adjacent null messages & merge them */
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
+ if(H5O_NULL_ID == curr_msg->type->id) {
+ H5O_mesg_t *curr_msg2; /* Pointer to current message to operate on */
+ unsigned v; /* Local index variable */
+
+ /* Loop over messages again, looking for null message in same chunk */
+ for(v = 0, curr_msg2 = &oh->mesg[0]; v < oh->nmesgs; v++, curr_msg2++) {
+ if(u != v && H5O_NULL_ID == curr_msg2->type->id && curr_msg->chunkno == curr_msg2->chunkno) {
+
+ /* Check for second message after first message */
+ if((curr_msg->raw + curr_msg->raw_size) == (curr_msg2->raw - H5O_SIZEOF_MSGHDR(f))) {
+ /* Extend first null message length to cover second null message */
+ curr_msg->raw_size += (H5O_SIZEOF_MSGHDR(f) + curr_msg2->raw_size);
+
+ /* Message has been merged */
+ merged_msg = TRUE;
+ } /* end if */
+ /* Check for second message befre first message */
+ else if((curr_msg->raw - H5O_SIZEOF_MSGHDR(f)) == (curr_msg2->raw + curr_msg2->raw_size)) {
+ /* Adjust first message address and extend length to cover second message */
+ curr_msg->raw -= (H5O_SIZEOF_MSGHDR(f) + curr_msg2->raw_size);
+ curr_msg->raw_size += (H5O_SIZEOF_MSGHDR(f) + curr_msg2->raw_size);
+
+ /* Message has been merged */
+ merged_msg = TRUE;
+ } /* end if */
+
+ /* Second message has been merged, delete it */
+ if(merged_msg) {
+ /* Release any information/memory for second message */
+ H5O_free_mesg(curr_msg2);
+
+ /* Mark first message as dirty */
+ curr_msg->dirty = TRUE;
+
+ /* Remove second message from list of messages */
+ if(v < (oh->nmesgs - 1))
+ HDmemmove(&oh->mesg[v], &oh->mesg[v + 1], ((oh->nmesgs - 1) - v) * sizeof(H5O_mesg_t));
+
+ /* Decrement # of messages */
+ /* (Don't bother reducing size of message array for now -QAK) */
+ oh->nmesgs--;
+
+ /* Get out of loop */
+ break;
+ } /* end if */
+ } /* end if */
+ } /* end for */
+
+ /* Get out of loop if we merged messages */
+ if(merged_msg)
+ break;
+ } /* end if */
+ } /* end for */
+
+ /* If we did any merging, remember that */
+ if(merged_msg)
+ did_merging = TRUE;
+ } while(merged_msg);
+
+ /* Set return value */
+ ret_value = did_merging;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_merge_null() */
+
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5O_remove_empty_chunks
+ *
+ * Purpose: Attempt to eliminate empty chunks from object header.
+ *
+ * This examines a chunk to see if it's empty
+ * and removes it (and the continuation message that points to it)
+ * from the object header.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Oct 17 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static htri_t
+H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
+{
+ hbool_t deleted_chunk; /* Whether to a chunk was deleted */
+ hbool_t did_deleting = FALSE; /* Whether any chunks were deleted */
+ htri_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_remove_empty_chunks)
+
+ /* check args */
+ HDassert(oh != NULL);
+
+ /* Loop until no chunks are freed */
+ do {
+ H5O_mesg_t *null_msg; /* Pointer to null message found */
+ H5O_mesg_t *cont_msg; /* Pointer to continuation message found */
+ unsigned u, v; /* Local index variables */
+
+ /* Reset 'chunk deleted' flag */
+ deleted_chunk = FALSE;
+
+ /* Scan messages for null messages that fill an entire chunk */
+ for(u = 0, null_msg = &oh->mesg[0]; u < oh->nmesgs; u++, null_msg++) {
+ /* If a null message takes up an entire object header chunk (and
+ * its not the "base" chunk), delete that chunk from object header
+ */
+ if(H5O_NULL_ID == null_msg->type->id && null_msg->chunkno > 0 &&
+ (H5O_SIZEOF_MSGHDR(f) + null_msg->raw_size) == oh->chunk[null_msg->chunkno].size) {
+ H5O_mesg_t *curr_msg; /* Pointer to current message to operate on */
+ unsigned null_msg_no; /* Message # for null message */
+ unsigned deleted_chunkno; /* Chunk # to delete */
+
+ /* Locate continuation message that points to chunk */
+ for(v = 0, cont_msg = &oh->mesg[0]; v < oh->nmesgs; v++, cont_msg++) {
+ if(H5O_CONT_ID == cont_msg->type->id) {
+ /* Decode current continuation message if necessary */
+ if(NULL == cont_msg->native) {
+ HDassert(H5O_CONT->decode);
+ cont_msg->native = (H5O_CONT->decode) (f, dxpl_id, cont_msg->raw);
+ if(NULL == cont_msg->native)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message")
+ } /* end if */
+
+ /* Check for correct chunk to delete */
+ if(oh->chunk[null_msg->chunkno].addr == ((H5O_cont_t *)(cont_msg->native))->addr)
+ break;
+ } /* end if */
+ } /* end for */
+ /* Must be a continuation message that points to chunk containing null message */
+ HDassert(v < oh->nmesgs);
+ HDassert(cont_msg);
+
+ /* Initialize information about null message */
+ null_msg_no = u;
+ deleted_chunkno = null_msg->chunkno;
+
+ /*
+ * Convert continuation message into a null message
+ */
+
+ /* Free space for chunk referred to in the file from the continuation message */
+ if(H5O_delete_mesg(f, dxpl_id, cont_msg, TRUE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, H5O_ITER_ERROR, "unable to delete file space for object header message")
+
+ /* Free any native information */
+ H5O_free_mesg(cont_msg);
+
+ /* Change message type to nil and zero it */
+ cont_msg->type = H5O_NULL;
+ HDmemset(cont_msg->raw, 0, cont_msg->raw_size);
+
+ /* Indicate that the continuation message was modified */
+ cont_msg->dirty = TRUE;
+
+ /*
+ * Remove chunk from object header's data structure
+ */
+
+ /* Free memory for chunk image */
+ H5FL_BLK_FREE(chunk_image, oh->chunk[null_msg->chunkno].image);
+
+ /* Remove chunk from list of chunks */
+ if(null_msg->chunkno < (oh->nchunks - 1))
+ HDmemmove(&oh->chunk[null_msg->chunkno], &oh->chunk[null_msg->chunkno + 1], ((oh->nchunks - 1) - null_msg->chunkno) * sizeof(H5O_chunk_t));
+
+ /* Decrement # of chunks */
+ /* (Don't bother reducing size of chunk array for now -QAK) */
+ oh->nchunks--;
+
+ /*
+ * Delete null message (in empty chunk that was be freed) from list of messages
+ */
+
+ /* Release any information/memory for message */
+ H5O_free_mesg(null_msg);
+
+ /* Remove null message from list of messages */
+ if(null_msg_no < (oh->nmesgs - 1))
+ HDmemmove(&oh->mesg[null_msg_no], &oh->mesg[null_msg_no + 1], ((oh->nmesgs - 1) - null_msg_no) * sizeof(H5O_mesg_t));
+
+ /* Decrement # of messages */
+ /* (Don't bother reducing size of message array for now -QAK) */
+ oh->nmesgs--;
+
+ /* Adjust chunk # for messages in chunks after deleted chunk */
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
+ HDassert(curr_msg->chunkno != deleted_chunkno);
+ if(curr_msg->chunkno > deleted_chunkno)
+ curr_msg->chunkno--;
+ } /* end for */
+
+ /* Found chunk to delete */
+ deleted_chunk = TRUE;
+ break;
+ } /* end if */
+ } /* end for */
+
+ /* If we deleted any chunks, remember that */
+ if(deleted_chunk)
+ did_deleting = TRUE;
+ } while(deleted_chunk);
+
+ /* Set return value */
+ ret_value = did_deleting;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_remove_empty_chunks() */
+
+
+/*-------------------------------------------------------------------------
+ *
+ * Function: H5O_condense_header
+ *
+ * Purpose: Attempt to eliminate empty chunks from object header.
+ *
+ * Currently, this just examines a chunk to see if it's empty
+ * and removes it from the object header. It's possible that
+ * a more sophiticated algorithm would repack messages from
+ * one chunk to another.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Oct 4 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_condense_header(H5F_t *f, H5O_t *oh, hid_t dxpl_id)
+{
+ hbool_t rescan_header; /* Whether to rescan header */
+ htri_t result; /* Result from packing/merging/etc */
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_condense_header)
+
+ /* check args */
+ HDassert(oh != NULL);
+
+ /* Loop until no changed to the object header messages & chunks */
+ do {
+ /* Reset 'rescan chunks' flag */
+ rescan_header = FALSE;
+
+ /* Scan for messages that can be moved earlier in chunks */
+ result = H5O_move_msgs_forward(f, oh, dxpl_id);
+ if(result < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't move header messages forward")
+ if(result > 0)
+ rescan_header = TRUE;
+
+ /* Scan for adjacent null messages & merge them */
+ result = H5O_merge_null(f, oh);
+ if(result < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't pack null header messages")
+ if(result > 0)
+ rescan_header = TRUE;
+
+ /* Scan for empty chunks to remove */
+ result = H5O_remove_empty_chunks(f, oh, dxpl_id);
+ if(result < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't remove empty chunk")
+ if(result > 0)
+ rescan_header = TRUE;
+ } while(rescan_header);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_condense_header() */
+
+
+/*-------------------------------------------------------------------------
+ *
* Function: H5O_alloc_extend_chunk
*
* Purpose: Attempt to extend a chunk that is allocated on disk.
@@ -2993,9 +2965,8 @@ H5O_alloc_extend_chunk(H5F_t *f,
HDassert(((H5O_cont_t *)(oh->mesg[u].native))->size == old_size);
((H5O_cont_t *)(oh->mesg[u].native))->size = oh->chunk[chunkno].size;
- /* Flag continuation message & it's chunk as dirty */
+ /* Flag continuation message as dirty */
oh->mesg[u].dirty = TRUE;
- oh->chunk[oh->mesg[u].chunkno].dirty = TRUE;
} /* end if */
} /* end for */
@@ -3031,17 +3002,6 @@ done:
* matzke@llnl.gov
* Aug 7 1997
*
- * Modifications:
- *
- * John Mainzer, 8/17/05
- * Reworked function to allocate file space immediately,
- * instead of just allocating core space (as it used to).
- * This change was necessary, as we were allocating file
- * space on metadata cache eviction, which need not be
- * synchronized across all processes. As a result,
- * different processes were allocating different file
- * locations to the same chunk.
- *
*-------------------------------------------------------------------------
*/
static unsigned
@@ -3051,8 +3011,10 @@ H5O_alloc_new_chunk(H5F_t *f,
size_t size)
{
size_t cont_size; /*continuation message size */
- int found_null = (-1); /*best fit null message */
- int found_other = (-1); /*best fit other message */
+ int found_null = (-1); /*best fit null message */
+ int found_attr = (-1); /*best fit attribute message */
+ int found_link = (-1); /*best fit link message */
+ int found_other = (-1); /*best fit other message */
unsigned idx; /*message number */
uint8_t *p = NULL; /*ptr into new chunk */
H5O_cont_t *cont = NULL; /*native continuation message */
@@ -3061,11 +3023,11 @@ H5O_alloc_new_chunk(H5F_t *f,
haddr_t new_chunk_addr;
unsigned ret_value; /*return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_new_chunk);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_new_chunk)
/* check args */
- HDassert (oh);
- HDassert (size > 0);
+ HDassert(oh);
+ HDassert(size > 0);
size = H5O_ALIGN(size);
/*
@@ -3073,36 +3035,60 @@ H5O_alloc_new_chunk(H5F_t *f,
* continuation message. Failing that, find the smallest message
* that could be moved to make room for the continuation message.
* Don't ever move continuation message from one chunk to another.
+ * Prioritize attribute and link messages moving to later chunks,
+ * instead of more "important" messages.
*/
cont_size = H5O_ALIGN (H5F_SIZEOF_ADDR(f) + H5F_SIZEOF_SIZE(f));
- for (u=0; u<oh->nmesgs; u++) {
- if (H5O_NULL_ID == oh->mesg[u].type->id) {
- if (cont_size == oh->mesg[u].raw_size) {
- found_null = u;
- break;
- } else if (oh->mesg[u].raw_size >= cont_size &&
- (found_null < 0 ||
- (oh->mesg[u].raw_size <
- oh->mesg[found_null].raw_size))) {
- found_null = u;
- }
- } else if (H5O_CONT_ID == oh->mesg[u].type->id) {
- /*don't consider continuation messages */
- } else if (oh->mesg[u].raw_size >= cont_size &&
+ for(u = 0; u < oh->nmesgs; u++) {
+ int msg_id = oh->mesg[u].type->id; /* Temp. copy of message type ID */
+
+ if(H5O_NULL_ID == msg_id) {
+ if(cont_size == oh->mesg[u].raw_size) {
+ found_null = u;
+ break;
+ } else if(oh->mesg[u].raw_size >= cont_size &&
+ (found_null < 0 ||
+ oh->mesg[u].raw_size < oh->mesg[found_null].raw_size)) {
+ found_null = u;
+ }
+ } else if(H5O_CONT_ID == msg_id) {
+ /*don't consider continuation messages */
+ } else if(H5O_ATTR_ID == msg_id) {
+ if(oh->mesg[u].raw_size >= cont_size &&
+ (found_attr < 0 ||
+ oh->mesg[u].raw_size < oh->mesg[found_attr].raw_size))
+ found_attr = u;
+ } else if(H5O_LINK_ID == msg_id) {
+ if(oh->mesg[u].raw_size >= cont_size &&
+ (found_link < 0 ||
+ oh->mesg[u].raw_size < oh->mesg[found_link].raw_size))
+ found_link = u;
+ } else {
+ if(oh->mesg[u].raw_size >= cont_size &&
(found_other < 0 ||
- oh->mesg[u].raw_size < oh->mesg[found_other].raw_size)) {
- found_other = u;
- }
- }
- assert(found_null >= 0 || found_other >= 0);
+ oh->mesg[u].raw_size < oh->mesg[found_other].raw_size))
+ found_other = u;
+ } /* end else */
+ } /* end for */
+ HDassert(found_null >= 0 || found_attr >= 0 || found_link >= 0 || found_other >= 0);
/*
* If we must move some other message to make room for the null
* message, then make sure the new chunk has enough room for that
* other message.
+ *
+ * Move attributes first, then link messages, then other messages.
+ *
*/
- if (found_null < 0)
+ if(found_null < 0) {
+ if(found_attr >= 0)
+ found_other = found_attr;
+ else if(found_link >= 0)
+ found_other = found_link;
+
+ HDassert(found_other >= 0);
size += H5O_SIZEOF_MSGHDR(f) + oh->mesg[found_other].raw_size;
+ } /* end if */
/*
* The total chunk size must include the requested space plus enough
@@ -3110,7 +3096,7 @@ H5O_alloc_new_chunk(H5F_t *f,
* multiple of the alignment size.
*/
size = MAX(H5O_MIN_SIZE, size + H5O_SIZEOF_MSGHDR(f));
- assert (size == H5O_ALIGN (size));
+ HDassert(size == H5O_ALIGN (size));
/* allocate space in file to hold the new chunk */
new_chunk_addr = H5MF_alloc(f, H5FD_MEM_OHDR, dxpl_id, (hsize_t)size);
@@ -3120,47 +3106,46 @@ H5O_alloc_new_chunk(H5F_t *f,
/*
* Create the new chunk giving it a file address.
*/
- if ( oh->nchunks >= oh->alloc_nchunks ) {
-
+ if(oh->nchunks >= oh->alloc_nchunks) {
unsigned na = oh->alloc_nchunks + H5O_NCHUNKS;
H5O_chunk_t *x = H5FL_SEQ_REALLOC (H5O_chunk_t, oh->chunk, (size_t)na);
- if (!x)
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
+ if(!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
oh->alloc_nchunks = na;
oh->chunk = x;
- }
+ } /* end if */
chunkno = oh->nchunks++;
oh->chunk[chunkno].dirty = TRUE;
oh->chunk[chunkno].addr = new_chunk_addr;
oh->chunk[chunkno].size = size;
if (NULL==(oh->chunk[chunkno].image = p = H5FL_BLK_CALLOC(chunk_image,size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
/*
* Make sure we have enough space for all possible new messages
* that could be generated below.
*/
- if (oh->nmesgs + 3 > oh->alloc_nmesgs) {
- int old_alloc=oh->alloc_nmesgs;
+ if(oh->nmesgs + 3 > oh->alloc_nmesgs) {
+ int old_alloc = oh->alloc_nmesgs;
unsigned na = oh->alloc_nmesgs + MAX (H5O_NMESGS, 3);
H5O_mesg_t *x = H5FL_SEQ_REALLOC (H5O_mesg_t, oh->mesg, (size_t)na);
- if (!x)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
+ if(!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
oh->alloc_nmesgs = na;
oh->mesg = x;
/* Set new object header info to zeros */
HDmemset(&oh->mesg[old_alloc], 0,
(oh->alloc_nmesgs-old_alloc)*sizeof(H5O_mesg_t));
- }
+ } /* end if */
/*
* Describe the messages of the new chunk.
*/
- if (found_null < 0) {
+ if(found_null < 0) {
found_null = u = oh->nmesgs++;
oh->mesg[u].type = H5O_NULL;
oh->mesg[u].dirty = TRUE;
@@ -3178,7 +3163,7 @@ H5O_alloc_new_chunk(H5F_t *f,
oh->mesg[found_other].chunkno = chunkno;
p += H5O_SIZEOF_MSGHDR(f) + oh->mesg[found_other].raw_size;
size -= H5O_SIZEOF_MSGHDR(f) + oh->mesg[found_other].raw_size;
- }
+ } /* end if */
idx = oh->nmesgs++;
oh->mesg[idx].type = H5O_NULL;
oh->mesg[idx].dirty = TRUE;
@@ -3192,7 +3177,7 @@ H5O_alloc_new_chunk(H5F_t *f,
* is larger than the continuation message, then split it into
* two null messages.
*/
- if (oh->mesg[found_null].raw_size > cont_size) {
+ if(oh->mesg[found_null].raw_size > cont_size) {
u = oh->nmesgs++;
oh->mesg[u].type = H5O_NULL;
oh->mesg[u].dirty = TRUE;
@@ -3206,7 +3191,7 @@ H5O_alloc_new_chunk(H5F_t *f,
oh->mesg[found_null].dirty = TRUE;
oh->mesg[found_null].raw_size = cont_size;
- }
+ } /* end if */
/*
* Initialize the continuation message.
@@ -3221,10 +3206,10 @@ H5O_alloc_new_chunk(H5F_t *f,
oh->mesg[found_null].native = cont;
/* Set return value */
- ret_value=idx;
+ ret_value = idx;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_alloc_new_chunk() */
@@ -3241,23 +3226,6 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
- * Modifications:
- *
- * John Mainzer, 6/7/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field directly.
- * In this case, that requires the addition of the oh_dirtied_ptr
- * parameter to track whether *oh is dirty.
- *
- * John Mainzer, 8/19/05
- * Reworked the function to allocate disk space immediately instead
- * of waiting to cache eviction time. This is necessary since cache
- * evictions need not be synchronized across the processes in the
- * PHDF5 case.
- *
- * Note the use of a revised versions of H5O_alloc_new_chunk() and
- * H5O_alloc_extend_chunk().
- *
*-------------------------------------------------------------------------
*/
static unsigned
@@ -3268,25 +3236,24 @@ H5O_alloc(H5F_t *f,
size_t size,
unsigned * oh_flags_ptr)
{
- unsigned idx;
H5O_mesg_t *msg; /* Pointer to newly allocated message */
size_t aligned_size = H5O_ALIGN(size);
- htri_t tri_result;
+ unsigned idx; /* Index of message which fits allocation */
unsigned ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_alloc);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_alloc)
/* check args */
- HDassert (oh);
- HDassert (type);
- HDassert (oh_flags_ptr);
+ HDassert(oh);
+ HDassert(type);
+ HDassert(oh_flags_ptr);
/* look for a null message which is large enough */
- for (idx = 0; idx < oh->nmesgs; idx++) {
- if (H5O_NULL_ID == oh->mesg[idx].type->id &&
+ for(idx = 0; idx < oh->nmesgs; idx++) {
+ if(H5O_NULL_ID == oh->mesg[idx].type->id &&
oh->mesg[idx].raw_size >= aligned_size)
break;
- }
+ } /* end for */
#ifdef LATER
/*
@@ -3299,7 +3266,7 @@ H5O_alloc(H5F_t *f,
#endif
/* if we didn't find one, then allocate more header space */
- if (idx >= oh->nmesgs) {
+ if(idx >= oh->nmesgs) {
unsigned chunkno;
/* check to see if we can extend one of the chunks. If we can,
@@ -3308,62 +3275,56 @@ H5O_alloc(H5F_t *f,
* Note that in this new version of this function, all chunks
* must have file space allocated to them.
*/
- for (chunkno = 0; chunkno < oh->nchunks; chunkno++) {
- HDassert( H5F_addr_defined(oh->chunk[chunkno].addr) );
-
- tri_result = H5O_alloc_extend_chunk(f, oh, chunkno, size, &idx);
+ for(chunkno = 0; chunkno < oh->nchunks; chunkno++) {
+ htri_t tri_result;
- if ( tri_result == TRUE ) {
+ HDassert(H5F_addr_defined(oh->chunk[chunkno].addr));
+ tri_result = H5O_alloc_extend_chunk(f, oh, chunkno, size, &idx);
+ if(tri_result == TRUE)
break;
-
- } else if ( tri_result == FALSE ) {
-
+ else if(tri_result == FALSE)
idx = UFAIL;
-
- } else {
-
- HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, UFAIL, \
- "H5O_alloc_extend_chunk failed unexpectedly");
- }
- }
+ else
+ HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, UFAIL, "H5O_alloc_extend_chunk failed unexpectedly")
+ } /* end for */
/* if idx is still UFAIL, we were not able to extend a chunk.
* Create a new one.
*/
- if(idx == UFAIL) {
+ if(idx == UFAIL)
if((idx = H5O_alloc_new_chunk(f, dxpl_id, oh, size)) == UFAIL)
HGOTO_ERROR(H5E_OHDR, H5E_NOSPACE, UFAIL, "unable to create a new object header data chunk")
- }
- }
+ } /* end if */
/* Set pointer to newly allocated message */
msg = &(oh->mesg[idx]);
/* do we need to split the null message? */
- if (msg->raw_size > aligned_size) {
+ if(msg->raw_size > aligned_size) {
H5O_mesg_t *null_msg; /* Pointer to null message */
- size_t mesg_size = aligned_size+ H5O_SIZEOF_MSGHDR(f); /* Total size of newly allocated message */
+ size_t mesg_size = aligned_size + H5O_SIZEOF_MSGHDR(f); /* Total size of newly allocated message */
HDassert(msg->raw_size - aligned_size >= H5O_SIZEOF_MSGHDR(f));
- if (oh->nmesgs >= oh->alloc_nmesgs) {
- int old_alloc=oh->alloc_nmesgs;
+ /* Check if we need to extend message table */
+ if(oh->nmesgs >= oh->alloc_nmesgs) {
+ int old_alloc = oh->alloc_nmesgs;
unsigned na = oh->alloc_nmesgs + H5O_NMESGS;
H5O_mesg_t *x = H5FL_SEQ_REALLOC(H5O_mesg_t, oh->mesg, (size_t)na);
- if (!x)
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed");
- oh->alloc_nmesgs = na;
- oh->mesg = x;
+ if(!x)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed")
+ oh->alloc_nmesgs = na;
+ oh->mesg = x;
/* Set new object header info to zeros */
- HDmemset(&oh->mesg[old_alloc],0,
+ HDmemset(&oh->mesg[old_alloc], 0,
(oh->alloc_nmesgs-old_alloc)*sizeof(H5O_mesg_t));
/* "Retarget" local 'msg' pointer into newly allocated array of messages */
- msg=&oh->mesg[idx];
- }
+ msg = &oh->mesg[idx];
+ } /* end if */
null_msg = &(oh->mesg[oh->nmesgs++]);
null_msg->type = H5O_NULL;
null_msg->dirty = TRUE;
@@ -3372,7 +3333,7 @@ H5O_alloc(H5F_t *f,
null_msg->raw_size = msg->raw_size - mesg_size;
null_msg->chunkno = msg->chunkno;
msg->raw_size = aligned_size;
- }
+ } /* end if */
/* initialize the new message */
msg->type = type;
@@ -3385,7 +3346,7 @@ H5O_alloc(H5F_t *f,
ret_value = idx;
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* H5O_alloc() */
#ifdef NOT_YET
@@ -3427,9 +3388,9 @@ H5O_share (H5F_t *f, hid_t dxpl_id, const H5O_class_t *type, const void *mesg,
if ((size = (type->raw_size)(f, mesg))>0) {
if (NULL==(buf = H5MM_malloc (size)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- if ((type->encode)(f, buf, mesg)<0)
+ if ((type->encode)(f, buf, mesg) < 0)
HGOTO_ERROR (H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode message");
- if (H5HG_insert (f, dxpl_id, size, buf, hobj)<0)
+ if (H5HG_insert (f, dxpl_id, size, buf, hobj) < 0)
HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, FAIL, "unable to store message in global heap");
}
@@ -3454,8 +3415,6 @@ done:
* koziol@ncsa.uiuc.edu
* Feb 13 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
size_t
@@ -3467,7 +3426,7 @@ H5O_raw_size(unsigned type_id, const H5F_t *f, const void *mesg)
FUNC_ENTER_NOAPI(H5O_raw_size,0)
/* Check args */
- HDassert(type_id<NELMTS(message_type_g));
+ HDassert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
HDassert(type->raw_size);
@@ -3506,7 +3465,7 @@ H5O_mesg_size(unsigned type_id, const H5F_t *f, const void *mesg)
FUNC_ENTER_NOAPI(H5O_mesg_size,0)
/* Check args */
- HDassert(type_id<NELMTS(message_type_g));
+ HDassert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
HDassert(type->raw_size);
@@ -3553,23 +3512,23 @@ H5O_get_share(unsigned type_id, H5F_t *f, const void *mesg, H5O_shared_t *share)
const H5O_class_t *type; /* Actual H5O class type for the ID */
herr_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5O_get_share,FAIL);
+ FUNC_ENTER_NOAPI(H5O_get_share,FAIL)
/* Check args */
- assert(type_id<NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
- assert (type);
- assert (type->get_share);
- assert (f);
- assert (mesg);
- assert (share);
+ HDassert(type_id < NELMTS(message_type_g));
+ type = message_type_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(type);
+ HDassert(type->get_share);
+ HDassert(f);
+ HDassert(mesg);
+ HDassert(share);
/* Compute the raw data size for the mesg */
- if ((ret_value = (type->get_share)(f, mesg, share))<0)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve shared message information");
+ if((ret_value = (type->get_share)(f, mesg, share)) < 0)
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTGET, FAIL, "unable to retrieve shared message information")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_get_share() */
@@ -3587,36 +3546,33 @@ done:
* koziol@ncsa.uiuc.edu
* Mar 19 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr)
{
- H5O_t *oh=NULL; /* Object header information */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5O_t *oh = NULL; /* Object header information */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_delete,FAIL);
+ FUNC_ENTER_NOAPI(H5O_delete,FAIL)
/* Check args */
- assert (f);
- assert(H5F_addr_defined(addr));
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
/* Get the object header information */
- if (NULL == (oh = H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_WRITE)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Delete object */
- if(H5O_delete_oh(f,dxpl_id,oh)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file");
+ if(H5O_delete_oh(f, dxpl_id, oh) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "can't delete object from file")
done:
- if (oh &&
- H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG)<0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__DIRTIED_FLAG | H5C__DELETED_FLAG) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_delete() */
@@ -3635,54 +3591,36 @@ done:
* koziol@ncsa.uiuc.edu
* Mar 19 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh)
{
H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
- H5O_chunk_t *curr_chk; /* Pointer to current chunk being operated on */
unsigned u;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_delete_oh);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_delete_oh)
/* Check args */
- assert (f);
- assert (oh);
+ HDassert(f);
+ HDassert(oh);
/* Walk through the list of object header messages, asking each one to
* delete any file space used
*/
- for (u = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) {
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
/* Free any space referred to in the file from this message */
- if(H5O_delete_mesg(f, dxpl_id, curr_msg, TRUE)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message");
+ if(H5O_delete_mesg(f, dxpl_id, curr_msg, TRUE) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message")
} /* end for */
- /* Free all the chunks for the object header */
- for (u = 0, curr_chk=&oh->chunk[0]; u < oh->nchunks; u++,curr_chk++) {
- haddr_t chk_addr; /* Actual address of chunk */
- hsize_t chk_size; /* Actual size of chunk */
-
- if(u==0) {
- chk_addr = curr_chk->addr - H5O_SIZEOF_HDR(f);
- chk_size = curr_chk->size + H5O_SIZEOF_HDR(f);
- } /* end if */
- else {
- chk_addr = curr_chk->addr;
- chk_size = curr_chk->size;
- } /* end else */
-
- /* Free the file space for the chunk */
- if (H5MF_xfree(f, H5FD_MEM_OHDR, dxpl_id, chk_addr, chk_size)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object header");
- } /* end for */
+ /* Free main (first) object header "chunk" */
+ if(H5MF_xfree(f, H5FD_MEM_OHDR, dxpl_id, (oh->chunk[0].addr - H5O_SIZEOF_HDR(f)), (hsize_t)(oh->chunk[0].size + H5O_SIZEOF_HDR(f))) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object header")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_delete_oh() */
@@ -3699,8 +3637,6 @@ done:
* koziol@ncsa.uiuc.edu
* September 26 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -3709,15 +3645,15 @@ H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link)
const H5O_class_t *type; /* Type of object to free */
herr_t ret_value=SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_delete_mesg);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_delete_mesg)
/* Check args */
- assert (f);
- assert (mesg);
+ HDassert(f);
+ HDassert(mesg);
/* Get the message to free's type */
if(mesg->flags & H5O_FLAG_SHARED)
- type=H5O_SHARED;
+ type = H5O_SHARED;
else
type = mesg->type;
@@ -3726,19 +3662,19 @@ H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link)
/*
* Decode the message if necessary.
*/
- if (NULL == mesg->native) {
- assert(type->decode);
- mesg->native = (type->decode) (f, dxpl_id, mesg->raw, NULL);
- if (NULL == mesg->native)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message");
+ if(NULL == mesg->native) {
+ HDassert(type->decode);
+ mesg->native = (type->decode) (f, dxpl_id, mesg->raw);
+ if(NULL == mesg->native)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message")
} /* end if */
- if ((type->del)(f, dxpl_id, mesg->native, adj_link)<0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message");
+ if((type->del)(f, dxpl_id, mesg->native, adj_link) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTDELETE, FAIL, "unable to delete file space for object header message")
} /* end if */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_delete_msg() */
@@ -3753,57 +3689,51 @@ done:
* koziol@ncsa.uiuc.edu
* Oct 7 2003
*
- * Modifications:
- *
- * John Mainzer, 6/16/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5O_get_info(H5G_entry_t *ent, H5O_stat_t *ostat, hid_t dxpl_id)
+H5O_get_info(H5O_loc_t *loc, H5O_stat_t *ostat, hid_t dxpl_id)
{
- H5O_t *oh=NULL; /* Object header information */
+ H5O_t *oh = NULL; /* Object header information */
H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
hsize_t total_size; /* Total amount of space used in file */
hsize_t free_space; /* Free space in object header */
unsigned u; /* Local index variable */
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5O_get_info,FAIL);
+ FUNC_ENTER_NOAPI(H5O_get_info,FAIL)
/* Check args */
- assert (ent);
- assert (ostat);
+ HDassert(loc);
+ HDassert(ostat);
/* Get the object header information */
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* Iterate over all the messages, accumulating the total size & free space */
- total_size=H5O_SIZEOF_HDR(ent->file);
- free_space=0;
- for (u = 0, curr_msg=&oh->mesg[0]; u < oh->nmesgs; u++,curr_msg++) {
+ total_size = H5O_SIZEOF_HDR(loc->file);
+ free_space = 0;
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
/* Accumulate the size for this message */
- total_size+= H5O_SIZEOF_MSGHDR(ent->file) + curr_msg->raw_size;
+ total_size += H5O_SIZEOF_MSGHDR(loc->file) + curr_msg->raw_size;
/* Check for this message being free space */
- if (H5O_NULL_ID == curr_msg->type->id)
- free_space+= H5O_SIZEOF_MSGHDR(ent->file) + curr_msg->raw_size;
+ if(H5O_NULL_ID == curr_msg->type->id)
+ free_space+= H5O_SIZEOF_MSGHDR(loc->file) + curr_msg->raw_size;
} /* end for */
/* Set the information for this object header */
- ostat->size=total_size;
- ostat->free=free_space;
- ostat->nmesgs=oh->nmesgs;
- ostat->nchunks=oh->nchunks;
+ ostat->size = total_size;
+ ostat->free = free_space;
+ ostat->nmesgs = oh->nmesgs;
+ ostat->nchunks = oh->nchunks;
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, H5AC__NO_FLAGS_SET)<0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_get_info() */
@@ -3834,12 +3764,12 @@ H5O_encode(H5F_t *f, unsigned char *buf, void *obj, unsigned type_id)
FUNC_ENTER_NOAPI(H5O_encode,FAIL);
/* check args */
- assert(type_id<NELMTS(message_type_g));
+ assert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
/* Encode */
- if ((type->encode)(f, buf, obj)<0)
+ if ((type->encode)(f, buf, obj) < 0)
HGOTO_ERROR (H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode message");
done:
@@ -3874,12 +3804,12 @@ H5O_decode(H5F_t *f, const unsigned char *buf, unsigned type_id)
FUNC_ENTER_NOAPI(H5O_decode,NULL);
/* check args */
- assert(type_id<NELMTS(message_type_g));
+ assert(type_id < NELMTS(message_type_g));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
/* decode */
- if((ret_value = (type->decode)(f, 0, buf, NULL))==NULL)
+ if((ret_value = (type->decode)(f, 0, buf))==NULL)
HGOTO_ERROR (H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode message");
done:
@@ -3925,24 +3855,24 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_iterate(const H5G_entry_t *ent, unsigned type_id, H5O_operator_t op,
+H5O_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t op,
void *op_data, hid_t dxpl_id)
{
- const H5O_class_t *type; /* Actual H5O class type for the ID */
- herr_t ret_value=0; /* Return value */
+ const H5O_class_t *type; /* Actual H5O class type for the ID */
+ herr_t ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5O_iterate, FAIL)
/* check args */
- HDassert(ent);
- HDassert(ent->file);
- HDassert(H5F_addr_defined(ent->header));
- HDassert(type_id<NELMTS(message_type_g));
- type=message_type_g[type_id]; /* map the type ID to the actual type object */
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
+ HDassert(type_id < NELMTS(message_type_g));
+ type = message_type_g[type_id]; /* map the type ID to the actual type object */
HDassert(type);
/* Call the "real" iterate routine */
- if((ret_value=H5O_iterate_real(ent, type, H5AC_READ, FALSE, (void *)op, op_data, dxpl_id))<0)
+ if((ret_value = H5O_iterate_real(loc, type, H5AC_READ, FALSE, (void *)op, op_data, dxpl_id)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_BADITER, FAIL, "unable to iterate over object header messages")
done:
@@ -3984,49 +3914,37 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_iterate_real(const H5G_entry_t *ent, const H5O_class_t *type, H5AC_protect_t prot,
+H5O_iterate_real(const H5O_loc_t *loc, const H5O_class_t *type, H5AC_protect_t prot,
hbool_t internal, void *op, void *op_data, hid_t dxpl_id)
{
- H5O_t *oh=NULL; /* Pointer to actual object header */
+ H5O_t *oh = NULL; /* Pointer to actual object header */
unsigned oh_flags = H5AC__NO_FLAGS_SET; /* Start iteration with no flags set on object header */
unsigned idx; /* Absolute index of current message in all messages */
unsigned sequence; /* Relative index of current message for messages of type */
H5O_mesg_t *idx_msg; /* Pointer to current message */
- herr_t ret_value=0; /* Return value */
+ herr_t ret_value = H5O_ITER_CONT; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_iterate_real)
/* check args */
- HDassert(ent);
- HDassert(ent->file);
- HDassert(H5F_addr_defined(ent->header));
+ HDassert(loc);
+ HDassert(loc->file);
+ HDassert(H5F_addr_defined(loc->addr));
HDassert(type);
HDassert(op);
/* Protect the object header to iterate over */
- if (NULL == (oh = H5AC_protect(ent->file, dxpl_id, H5AC_OHDR, ent->header, NULL, NULL, prot)))
+ if (NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, prot)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
/* Iterate over messages */
- for (sequence = 0, idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs; idx++, idx_msg++) {
- if (type->id == idx_msg->type->id) {
+ for(sequence = 0, idx = 0, idx_msg = &oh->mesg[0]; idx < oh->nmesgs && !ret_value; idx++, idx_msg++) {
+ if(type->id == idx_msg->type->id) {
/*
* Decode the message if necessary. If the message is shared then decode
* a shared message, ignoring the message type.
*/
- if (NULL == idx_msg->native) {
- const H5O_class_t *decode_type;
-
- if (idx_msg->flags & H5O_FLAG_SHARED)
- decode_type = H5O_SHARED;
- else
- decode_type = type;
-
- /* Decode the message if necessary */
- HDassert(decode_type->decode);
- if (NULL == (idx_msg->native = (decode_type->decode) (ent->file, dxpl_id, idx_msg->raw, NULL)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode message")
- } /* end if */
+ LOAD_NATIVE(loc->file, dxpl_id, idx_msg)
/* Check for making an "internal" (i.e. within the H5O package) callback */
if(internal) {
@@ -4040,27 +3958,155 @@ H5O_iterate_real(const H5G_entry_t *ent, const H5O_class_t *type, H5AC_protect_t
break;
} /* end else */
+ /* Check for error from iterator */
+ if(ret_value < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "iterator function failed")
+
/* Increment sequence value for message type */
sequence++;
} /* end if */
} /* end for */
- /* Check if object header was modified */
- if(oh_flags & H5AC__DIRTIED_FLAG) {
- /* Shouldn't be able to modify object header if we don't have write access */
- HDassert(prot == H5AC_WRITE);
- H5O_touch_oh(ent->file, dxpl_id, oh, FALSE, &oh_flags);
- } /* end if */
-
done:
- if (oh && H5AC_unprotect(ent->file, dxpl_id, H5AC_OHDR, ent->header, oh, oh_flags) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+ if(oh) {
+ /* Check if object header was modified */
+ if(oh_flags & H5AC__DIRTIED_FLAG) {
+ /* Shouldn't be able to modify object header if we don't have write access */
+ HDassert(prot == H5AC_WRITE);
+
+ /* Try to condense object header info */
+ if(H5O_condense_header(loc->file, oh, dxpl_id) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTPACK, FAIL, "can't pack object header")
+
+ H5O_touch_oh(loc->file, dxpl_id, oh, FALSE, &oh_flags);
+ } /* end if */
+
+ if(H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, oh_flags) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_iterate_real() */
/*-------------------------------------------------------------------------
+ * Function: H5O_obj_type
+ *
+ * Purpose: Returns the type of object pointed to by `loc'.
+ *
+ * Return: Success: An object type defined in H5Gpublic.h
+ * Failure: H5G_UNKNOWN
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, November 4, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+H5G_obj_t
+H5O_obj_type(H5O_loc_t *loc, hid_t dxpl_id)
+{
+ size_t i; /* Local index variable */
+ H5G_obj_t ret_value = H5G_UNKNOWN; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_obj_type, H5G_UNKNOWN)
+
+ /* Test whether entry qualifies as a particular type of object */
+ /* (Note: loop is in reverse order, to test specific objects first) */
+ for(i = H5O_ntypes_g; i > 0; --i) {
+ htri_t isa; /* Is entry a particular type? */
+
+ if((isa = (H5O_type_g[i-1].isa)(loc, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type")
+ else if(isa)
+ HGOTO_DONE(H5O_type_g[i-1].type)
+ } /* end for */
+
+ if(0 == i)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_obj_type() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_loc_reset
+ *
+ * Purpose: Reset a object location to an empty state
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 19, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_loc_reset(H5O_loc_t *loc)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_loc_reset)
+
+ /* Check arguments */
+ HDassert(loc);
+
+ /* Clear the object location to an empty state */
+ HDmemset(loc, 0, sizeof(H5O_loc_t));
+ loc->addr = HADDR_UNDEF;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_loc_reset() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_loc_copy
+ *
+ * Purpose: Copy object location information
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Monday, September 19, 2005
+ *
+ * Notes: 'depth' parameter determines how much of the group entry
+ * structure we want to copy. The values are:
+ * H5O_COPY_SHALLOW - Copy all the field values from the source
+ * to the destination, but not copying objects pointed to.
+ * (Destination "takes ownership" of objects pointed to)
+ * H5O_COPY_DEEP - Copy all the fields from the source to
+ * the destination, deep copying objects pointed to.
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5O_copy_depth_t depth)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_loc_copy)
+
+ /* Check arguments */
+ HDassert(src);
+ HDassert(dst);
+ HDassert(depth == H5O_COPY_SHALLOW || depth == H5O_COPY_DEEP);
+
+ /* Copy the top level information */
+ HDmemcpy(dst, src, sizeof(H5O_loc_t));
+
+ /* Deep copy the names */
+ if(depth == H5G_COPY_DEEP) {
+ /* Nothing currently */
+ ;
+ } else if(depth == H5G_COPY_SHALLOW) {
+ /* Discarding 'const' qualifier OK - QAK */
+ H5O_loc_reset((H5O_loc_t *)src);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_loc_copy() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_copy_mesg_file
*
* Purpose: Copies a message to file. If MESG is is the null pointer then a null
@@ -4100,47 +4146,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_post_copy_mesg_file
- *
- * Purpose: Copies what's left to file after the object a meesage is copied.
- * This function is need for situations like copying symbol tables.
- * Copying a member of symbol table requires the parent object header
- * exists in file. For this case, the first round of the message will
- * create symbol table enttries but will not go deep copying member
- * objects in the symbol table. The post copy will do that.
- *
- * Return: Non-negative on success/Negative on failure
- *
- * Programmer: Peter Cao
- * September 28, 2005
- *
- *-------------------------------------------------------------------------
- */
-static herr_t
-H5O_post_copy_mesg_file (const H5O_class_t *type, H5F_t *file_src,
- const void *mesg_src, H5G_entry_t *loc_dst,
- hid_t dxpl_id, H5SL_t *map_list)
-{
- herr_t ret_value = SUCCEED;
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_post_copy_mesg_file)
-
- /* check args */
- HDassert(type);
- HDassert(file_src);
- HDassert(mesg_src);
- HDassert(loc_dst->file);
- HDassert(map_list);
-
- if(type->post_copy_file && (type->post_copy_file)(file_src, mesg_src, loc_dst, dxpl_id, map_list) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to copy object header message to file")
-
-done:
- FUNC_LEAVE_NOAPI(ret_value)
-} /* H5O_post_copy_mesg_file */
-
-
-/*-------------------------------------------------------------------------
* Function: H5O_copy_header_real
*
* Purpose: copy header object from one location to another.
@@ -4150,48 +4155,49 @@ done:
* Programmer: Peter Cao
* May 30, 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_copy_header_real(const H5G_entry_t *ent_src,
- H5G_entry_t *ent_dst /*out */, hid_t dxpl_id, H5SL_t *map_list)
+H5O_copy_header_real(const H5O_loc_t *oloc_src,
+ H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5SL_t *map_list)
{
- H5O_addr_map_t *addr_map; /* Address mapping of object copied */
- uint8_t buf[16], *p;
- H5O_t *oh = NULL;
- unsigned chunkno = 0, mesgno = 0;
- size_t chunk_size, hdr_size;
- haddr_t addr_new;
- H5O_mesg_t *mesg_src;
- H5O_chunk_t *chunk;
- herr_t ret_value = SUCCEED;
+ H5O_addr_map_t *addr_map = NULL; /* Address mapping of object copied */
+ uint8_t buf[16], *p;
+ H5O_t *oh_src = NULL; /* Object header for source object */
+ H5O_t *oh_dst = NULL; /* Object header for destination object */
+ unsigned chunkno = 0, mesgno = 0;
+ size_t chunk_size, hdr_size;
+ haddr_t addr_new;
+ H5O_mesg_t *mesg_src; /* Message in source object header */
+ H5O_mesg_t *mesg_dst; /* Message in source object header */
+ H5O_chunk_t *chunk = NULL;
+ unsigned dst_oh_flags = H5AC__NO_FLAGS_SET; /* used to indicate whether destination header was modified */
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI_NOINIT(H5O_copy_header_real)
- HDassert(ent_src);
- HDassert(ent_src->file);
- HDassert(H5F_addr_defined(ent_src->header));
- HDassert(ent_dst->file);
+ HDassert(oloc_src);
+ HDassert(oloc_src->file);
+ HDassert(H5F_addr_defined(oloc_src->addr));
+ HDassert(oloc_dst->file);
HDassert(map_list);
- if(NULL == (oh = H5AC_protect(ent_src->file, dxpl_id, H5AC_OHDR, ent_src->header, NULL, NULL, H5AC_READ)))
+ if(NULL == (oh_src = H5AC_protect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, NULL, NULL, H5AC_READ)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
/* get the size of the file header of the destination file */
- hdr_size = H5O_SIZEOF_HDR(ent_dst->file);
+ hdr_size = H5O_SIZEOF_HDR(oloc_dst->file);
/* allocate memory space for the destitnation chunks */
- if(NULL == (chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh->nchunks)))
+ if(NULL == (chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, (size_t)oh_src->nchunks)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Allocate space for the first chunk */
- if(HADDR_UNDEF == (addr_new = H5MF_alloc(ent_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)hdr_size + oh->chunk[0].size)))
+ if(HADDR_UNDEF == (addr_new = H5MF_alloc(oloc_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)hdr_size + oh_src->chunk[0].size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header")
/* Return the first chunk address */
- ent_dst->header = addr_new;
+ oloc_dst->addr = addr_new;
/* Set chunk's address */
chunk[0].addr = addr_new + (hsize_t)hdr_size;
@@ -4206,13 +4212,13 @@ H5O_copy_header_real(const H5G_entry_t *ent_src,
*p++ = 0;
/* encode number of messages */
- UINT16ENCODE(p, oh->nmesgs);
+ UINT16ENCODE(p, oh_src->nmesgs);
/* encode link count (at zero initially) */
UINT32ENCODE(p, 0);
/* encode body size */
- UINT32ENCODE(p, oh->chunk[0].size);
+ UINT32ENCODE(p, oh_src->chunk[0].size);
/* zero to alignment */
HDmemset(p, 0, (size_t)(hdr_size-12));
@@ -4221,17 +4227,17 @@ H5O_copy_header_real(const H5G_entry_t *ent_src,
because continuation chunk message will need to know the chunk address of address of
continuation block.
*/
- for(chunkno = 1; chunkno < oh->nchunks; chunkno++) {
- if(HADDR_UNDEF == (chunk[chunkno].addr = H5MF_alloc(ent_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)oh->chunk[chunkno].size)))
+ for(chunkno = 1; chunkno < oh_src->nchunks; chunkno++) {
+ if(HADDR_UNDEF == (chunk[chunkno].addr = H5MF_alloc(oloc_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)oh_src->chunk[chunkno].size)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header")
} /* end for */
/* Loop through chunks to copy chunk information */
- for(chunkno = 0; chunkno < oh->nchunks; chunkno++) {
- chunk_size = oh->chunk[chunkno].size;
+ for(chunkno = 0; chunkno < oh_src->nchunks; chunkno++) {
+ chunk_size = oh_src->chunk[chunkno].size;
/* copy chunk information */
- chunk[chunkno].dirty = oh->chunk[chunkno].dirty;
+ chunk[chunkno].dirty = oh_src->chunk[chunkno].dirty;
chunk[chunkno].size = chunk_size;
/* create memory image for the new chunk */
@@ -4242,13 +4248,13 @@ H5O_copy_header_real(const H5G_entry_t *ent_src,
/* (This copies over all the messages which don't require special
* callbacks to fix them up.)
*/
- HDmemcpy(chunk[chunkno].image, oh->chunk[chunkno].image, chunk_size);
+ HDmemcpy(chunk[chunkno].image, oh_src->chunk[chunkno].image, chunk_size);
/* Loop through messages, to fix up any which refer to addresses in the source file, etc. */
- for(mesgno = 0; mesgno < oh->nmesgs; mesgno++) {
+ for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) {
const H5O_class_t *copy_type;
- mesg_src = &(oh->mesg[mesgno]);
+ mesg_src = &(oh_src->mesg[mesgno]);
/* check if the message belongs to this chunk */
if(mesg_src->chunkno != chunkno)
@@ -4271,31 +4277,31 @@ H5O_copy_header_real(const H5G_entry_t *ent_src,
if(NULL == mesg_src->native) {
/* Decode the message if necessary */
HDassert(copy_type->decode);
- if(NULL == (mesg_src->native = (copy_type->decode)(ent_src->file, dxpl_id, mesg_src->raw, NULL)))
+ if(NULL == (mesg_src->native = (copy_type->decode)(oloc_src->file, dxpl_id, mesg_src->raw)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, FAIL, "unable to decode a message")
} /* end if (NULL == mesg_src->native) */
/* Copy the source message */
if(H5O_CONT_ID == copy_type->id) {
- if((dst_native = H5O_copy_mesg_file(copy_type, ent_src->file, mesg_src->native,
- ent_dst->file, dxpl_id, map_list, chunk)) == NULL)
+ if((dst_native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native,
+ oloc_dst->file, dxpl_id, map_list, chunk)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
} /* end if */
else {
- if((dst_native = H5O_copy_mesg_file(copy_type, ent_src->file, mesg_src->native,
- ent_dst->file, dxpl_id, map_list, NULL)) == NULL)
+ if((dst_native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native,
+ oloc_dst->file, dxpl_id, map_list, NULL)) == NULL)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
} /* end else */
/* Calculate address in destination raw chunk */
- p = chunk[chunkno].image + (mesg_src->raw - oh->chunk[chunkno].image);
+ p = chunk[chunkno].image + (mesg_src->raw - oh_src->chunk[chunkno].image);
/*
* Encode the message. If the message is shared then we
* encode a Shared Object message instead of the object
* which is being shared.
*/
- if((copy_type->encode)(ent_dst->file, p, dst_native) < 0)
+ if((copy_type->encode)(oloc_dst->file, p, dst_native) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message")
/* Release native destination info */
@@ -4305,52 +4311,98 @@ H5O_copy_header_real(const H5G_entry_t *ent_src,
/* Write the object header to the file if this is the first chunk */
if(chunkno == 0)
- if(H5F_block_write(ent_dst->file, H5FD_MEM_OHDR, addr_new, hdr_size, dxpl_id, buf) < 0)
+ if(H5F_block_write(oloc_dst->file, H5FD_MEM_OHDR, addr_new, hdr_size, dxpl_id, buf) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header hdr to disk")
/* Write this chunk into disk */
- if(H5F_block_write(ent_dst->file, H5FD_MEM_OHDR, chunk[chunkno].addr, chunk[chunkno].size, dxpl_id, chunk[chunkno].image) < 0)
+ if(H5F_block_write(oloc_dst->file, H5FD_MEM_OHDR, chunk[chunkno].addr, chunk[chunkno].size, dxpl_id, chunk[chunkno].image) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header data to disk")
} /* end of chunkno loop */
+
+ /* Protect destination object header, so we can modify messages in it */
+ if(NULL == (oh_dst = H5AC_protect(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, NULL, NULL, H5AC_WRITE)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+ HDassert(oh_dst->nmesgs == oh_src->nmesgs);
+
/* Allocate space for the address mapping of the object copied */
if(NULL == (addr_map = H5FL_MALLOC(H5O_addr_map_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Insert the address mapping for the new object into the copied list */
/* (Do this here, because "post copy" possibly checks it) */
- addr_map->src_addr = ent_src->header;
- addr_map->dst_addr = ent_dst->header;
+ addr_map->src_addr = oloc_src->addr;
+ addr_map->dst_addr = oloc_dst->addr;
+ addr_map->is_locked = TRUE; /* We've locked the object currently */
+ addr_map->inc_ref_count = 0; /* Start with no additional ref counts to add */
if(H5SL_insert(map_list, addr_map, &(addr_map->src_addr)) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTINSERT, FAIL, "can't insert object into skip list")
/* "post copy" loop over messages */
- for(mesgno = 0; mesgno < oh->nmesgs; mesgno++) {
+ for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) {
const H5O_class_t *copy_type;
- mesg_src = &(oh->mesg[mesgno]);
+ mesg_src = &(oh_src->mesg[mesgno]);
- if (mesg_src->flags & H5O_FLAG_SHARED)
+ if(mesg_src->flags & H5O_FLAG_SHARED)
copy_type = H5O_SHARED;
else
copy_type = mesg_src->type;
HDassert(copy_type);
- if(mesg_src->native) {
- if((H5O_post_copy_mesg_file(copy_type, ent_src->file, mesg_src->native,
- ent_dst, dxpl_id, map_list)) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message")
+ if(copy_type->post_copy_file && mesg_src->native) {
+ hbool_t modified = FALSE;
+
+ /* Get destination message */
+ mesg_dst = &(oh_dst->mesg[mesgno]);
+ HDassert(mesg_dst->type == mesg_src->type);
+
+ /* Make certain the destination's native info is available */
+ LOAD_NATIVE(oloc_dst->file, dxpl_id, mesg_dst)
+
+ /* Perform "post copy" operation on messge */
+ if((copy_type->post_copy_file)(oloc_src->file, mesg_src->native, oloc_dst, mesg_dst->native, &modified, dxpl_id, map_list) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'post copy' operation on message")
+
+ /* Mark message and header as dirty if the destination message was modified */
+ if(modified) {
+ mesg_dst->dirty = TRUE;
+ dst_oh_flags |= H5AC__DIRTIED_FLAG;
+ } /* end if */
} /* end if */
} /* end for */
done:
- /* Release pointer to object header itself */
- if(oh != NULL) {
- for(chunkno = 0; chunkno < oh->nchunks; chunkno++)
- H5FL_BLK_FREE(chunk_image, chunk[chunkno].image);
- H5FL_SEQ_FREE(H5O_chunk_t, chunk);
+ /* Release pointer to source object header and it's derived objects */
+ if(oh_src != NULL) {
+ /* Release all the chunks used to copy messages */
+ if(chunk) {
+ for(chunkno = 0; chunkno < oh_src->nchunks; chunkno++)
+ H5FL_BLK_FREE(chunk_image, chunk[chunkno].image);
+ H5FL_SEQ_FREE(H5O_chunk_t, chunk);
+ } /* end if */
+
+ /* Unprotect the source object header */
+ if(H5AC_unprotect(oloc_src->file, dxpl_id, H5AC_OHDR, oloc_src->addr, oh_src, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+ } /* end if */
+
+ /* Release pointer to destination object header */
+ if(oh_dst != NULL) {
+ /* Perform operations on address mapping for object, if it's in use */
+ if(addr_map) {
+ /* Indicate that the destination address will no longer be locked */
+ addr_map->is_locked = FALSE;
+
+ /* Increment object header's reference count, if any descendents have created links to link to this object */
+ if(addr_map->inc_ref_count) {
+ oh_dst->nlink += addr_map->inc_ref_count;
+ dst_oh_flags |= H5AC__DIRTIED_FLAG;
+ } /* end if */
+ } /* end if */
- if(H5AC_unprotect(ent_src->file, dxpl_id, H5AC_OHDR, ent_src->header, oh, H5AC__NO_FLAGS_SET) < 0)
+ /* Unprotect the destination object header */
+ if(H5AC_unprotect(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, oh_dst, dst_oh_flags) < 0)
HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
} /* end if */
@@ -4372,39 +4424,56 @@ done:
*-------------------------------------------------------------------------
*/
herr_t
-H5O_copy_header_map(const H5G_entry_t *ent_src,
- H5G_entry_t *ent_dst /*out */, hid_t dxpl_id, H5SL_t *map_list)
+H5O_copy_header_map(const H5O_loc_t *oloc_src,
+ H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5SL_t *map_list)
{
H5O_addr_map_t *addr_map; /* Address mapping of object copied */
+ hbool_t inc_link; /* Whether to increment the link count for the object */
herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5O_copy_header_map, FAIL)
/* Sanity check */
- HDassert(ent_src);
- HDassert(ent_dst);
- HDassert(ent_dst->file);
+ HDassert(oloc_src);
+ HDassert(oloc_dst);
+ HDassert(oloc_dst->file);
HDassert(map_list);
/* Look up the address of the object to copy in the skip list */
- addr_map = (H5O_addr_map_t *)H5SL_search(map_list, &(ent_src->header));
+ addr_map = (H5O_addr_map_t *)H5SL_search(map_list, &(oloc_src->addr));
/* Check if address is already in list of objects copied */
if(addr_map == NULL) {
/* Copy object for the first time */
/* Copy object referred to */
- if(H5O_copy_header_real(ent_src, ent_dst, dxpl_id, map_list) < 0)
+ if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, map_list) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+
+ /* When an object is copied for the first time, increment it's link */
+ inc_link = TRUE;
} /* end if */
else {
/* Object has already been copied, set it's address in destination file */
- ent_dst->header = addr_map->dst_addr;
+ oloc_dst->addr = addr_map->dst_addr;
+
+ /* If the object is locked currently (because we are copying a group
+ * hierarchy and this is a link to a group higher in the hierarchy),
+ * increment it's deferred reference count instead of incrementing the
+ * reference count now.
+ */
+ if(addr_map->is_locked) {
+ addr_map->inc_ref_count++;
+ inc_link = FALSE;
+ } /* end if */
+ else
+ inc_link = TRUE;
} /* end else */
- /* Increment destination object's link count */
- if(H5O_link(ent_dst, 1, dxpl_id) < 0)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to increment object link count")
+ /* Increment destination object's link count, if allowed */
+ if(inc_link)
+ if(H5O_link(oloc_dst, 1, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to increment object link count")
done:
FUNC_LEAVE_NOAPI(ret_value)
@@ -4457,25 +4526,24 @@ H5O_copy_free_addrmap_cb(void *item, void UNUSED *key, void UNUSED *op_data)
*-------------------------------------------------------------------------
*/
herr_t
-H5O_copy_header(const H5G_entry_t *ent_src,
- H5G_entry_t *ent_dst /*out */, hid_t dxpl_id)
+H5O_copy_header(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id)
{
- H5SL_t *map_list = NULL; /* Skip list to hold address mappings */
- herr_t ret_value = SUCCEED;
+ H5SL_t *map_list = NULL; /* Skip list to hold address mappings */
+ herr_t ret_value = SUCCEED;
FUNC_ENTER_NOAPI(H5O_copy_header, FAIL)
- HDassert(ent_src);
- HDassert(ent_src->file);
- HDassert(H5F_addr_defined(ent_src->header));
- HDassert(ent_dst->file);
+ HDassert(oloc_src);
+ HDassert(oloc_src->file);
+ HDassert(H5F_addr_defined(oloc_src->addr));
+ HDassert(oloc_dst->file);
/* Create a skip list to keep track of which objects are copied */
if((map_list = H5SL_create(H5SL_TYPE_HADDR, 0.5, 16)) == NULL)
HGOTO_ERROR(H5E_SLIST, H5E_CANTCREATE, FAIL, "cannot make skip list")
/* copy the object from the source file to the destination file */
- if(H5O_copy_header_real(ent_src, ent_dst, dxpl_id, map_list) < 0)
+ if(H5O_copy_header_real(oloc_src, oloc_dst, dxpl_id, map_list) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
done:
@@ -4511,7 +4579,7 @@ H5O_debug_id(hid_t type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *str
FUNC_ENTER_NOAPI(H5O_debug_id,FAIL);
/* Check args */
- assert(type_id>=0 && type_id<(hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0])));
+ assert(type_id>=0 && type_id < (hid_t)(sizeof(message_type_g)/sizeof(message_type_g[0])));
type=message_type_g[type_id]; /* map the type ID to the actual type object */
assert(type);
assert(type->debug);
@@ -4522,7 +4590,7 @@ H5O_debug_id(hid_t type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *str
assert(fwidth >= 0);
/* Call the debug method in the class */
- if ((ret_value = (type->debug)(f, dxpl_id, mesg, stream, indent, fwidth))<0)
+ if ((ret_value = (type->debug)(f, dxpl_id, mesg, stream, indent, fwidth)) < 0)
HGOTO_ERROR (H5E_OHDR, H5E_BADTYPE, FAIL, "unable to debug message");
done:
@@ -4531,7 +4599,7 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5O_debug
+ * Function: H5O_debug_real
*
* Purpose: Prints debugging info about an object header.
*
@@ -4541,38 +4609,28 @@ done:
* matzke@llnl.gov
* Aug 6 1997
*
- * Modifications:
- * Robb Matzke, 1999-07-28
- * The ADDR argument is passed by value.
- *
- * John Mainzer, 6/16/05
- * Modified function to use the new dirtied parameter to
- * H5AC_unprotect() instead of modfying the is_dirty field.
*-------------------------------------------------------------------------
*/
herr_t
-H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth)
+H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, int indent, int fwidth)
{
- H5O_t *oh = NULL;
unsigned i, chunkno;
size_t mesg_total = 0, chunk_total = 0;
int *sequence;
haddr_t tmp_addr;
- herr_t ret_value = SUCCEED;
- void *(*decode)(H5F_t*, hid_t, const uint8_t*, H5O_shared_t*);
+ void *(*decode)(H5F_t*, hid_t, const uint8_t*);
herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int)=NULL;
+ herr_t ret_value = SUCCEED;
- FUNC_ENTER_NOAPI(H5O_debug, FAIL);
+ FUNC_ENTER_NOAPI(H5O_debug_real, FAIL)
/* check args */
- assert(f);
- assert(H5F_addr_defined(addr));
- assert(stream);
- assert(indent >= 0);
- assert(fwidth >= 0);
-
- if (NULL == (oh = H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_READ)))
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header");
+ HDassert(f);
+ HDassert(oh);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
/* debug */
HDfprintf(stream, "%*sObject Header...\n", indent, "");
@@ -4597,7 +4655,7 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
(unsigned) (oh->nchunks), (unsigned) (oh->alloc_nchunks));
/* debug each chunk */
- for (i=0, chunk_total=0; i<oh->nchunks; i++) {
+ for (i=0, chunk_total=0; i < oh->nchunks; i++) {
chunk_total += oh->chunk[i].size;
HDfprintf(stream, "%*sChunk %d...\n", indent, "", i);
@@ -4619,7 +4677,7 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
/* debug each message */
if (NULL==(sequence = H5MM_calloc(NELMTS(message_type_g)*sizeof(int))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
- for (i=0, mesg_total=0; i<oh->nmesgs; i++) {
+ for (i=0, mesg_total=0; i < oh->nmesgs; i++) {
mesg_total += H5O_SIZEOF_MSGHDR(f) + oh->mesg[i].raw_size;
HDfprintf(stream, "%*sMessage %d...\n", indent, "", i);
@@ -4638,6 +4696,9 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
(unsigned) (oh->mesg[i].type->id),
oh->mesg[i].type->name,
sequence[oh->mesg[i].type->id]++);
+ HDfprintf (stream, "%*s%-*s %d\n", indent+3, "", MAX (0, fwidth-3),
+ "Dirty:",
+ (int)(oh->mesg[i].dirty));
HDfprintf (stream, "%*s%-*s %s\n", indent+3, "", MAX (0, fwidth-3),
"Shared:",
(oh->mesg[i].flags & H5O_FLAG_SHARED) ? "Yes" : "No");
@@ -4658,6 +4719,9 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
chunkno = oh->mesg[i].chunkno;
if (chunkno >= oh->nchunks)
HDfprintf(stream, "*** BAD CHUNK NUMBER\n");
+ HDfprintf(stream, "%*s%-*s %u\n", indent + 3, "", MAX(0, fwidth - 3),
+ "Raw data offset in chunk:",
+ (unsigned) (oh->mesg[i].raw - oh->chunk[chunkno].image));
/* check the size */
if ((oh->mesg[i].raw + oh->mesg[i].raw_size >
@@ -4675,7 +4739,7 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
debug = oh->mesg[i].type->debug;
}
if (NULL==oh->mesg[i].native && decode)
- oh->mesg[i].native = (decode)(f, dxpl_id, oh->mesg[i].raw, NULL);
+ oh->mesg[i].native = (decode)(f, dxpl_id, oh->mesg[i].raw);
if (NULL==oh->mesg[i].native)
debug = NULL;
@@ -4692,17 +4756,9 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
H5O_shared_t *shared = (H5O_shared_t*)(oh->mesg[i].native);
void *mesg = NULL;
- if (shared->in_gh) {
- void *p = H5HG_read (f, dxpl_id, oh->mesg[i].native, NULL);
- mesg = (oh->mesg[i].type->decode)(f, dxpl_id, p, oh->mesg[i].native);
- H5MM_xfree (p);
- } else {
- mesg = H5O_read_real(&(shared->u.ent), oh->mesg[i].type, 0, NULL, dxpl_id);
- }
- if (oh->mesg[i].type->debug) {
- (oh->mesg[i].type->debug)(f, dxpl_id, mesg, stream, indent+3,
- MAX (0, fwidth-3));
- }
+ mesg = H5O_read_real(&(shared->oloc), oh->mesg[i].type, 0, NULL, dxpl_id);
+ if (oh->mesg[i].type->debug)
+ (oh->mesg[i].type->debug)(f, dxpl_id, mesg, stream, indent+3, MAX (0, fwidth-3));
H5O_free_real(oh->mesg[i].type, mesg);
}
}
@@ -4712,8 +4768,48 @@ H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int f
HDfprintf(stream, "*** TOTAL SIZE DOES NOT MATCH ALLOCATED SIZE!\n");
done:
- if (oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__NO_FLAGS_SET) < 0)
- HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header");
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_debug_real() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_debug
+ *
+ * Purpose: Prints debugging info about an object header.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 6 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, int fwidth)
+{
+ H5O_t *oh = NULL;
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI(H5O_debug, FAIL)
+
+ /* check args */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+
+ if(NULL == (oh = H5AC_protect(f, dxpl_id, H5AC_OHDR, addr, NULL, NULL, H5AC_READ)))
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header")
+
+ /* debug */
+ H5O_debug_real(f, dxpl_id, oh, addr, stream, indent, fwidth);
+
+done:
+ if(oh && H5AC_unprotect(f, dxpl_id, H5AC_OHDR, addr, oh, H5AC__NO_FLAGS_SET) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header")
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_debug() */
- FUNC_LEAVE_NOAPI(ret_value);
-}
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index 9ac5570..4d97b12 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -28,7 +28,7 @@
/* PRIVATE PROTOTYPES */
static herr_t H5O_attr_encode (H5F_t *f, uint8_t *p, const void *mesg);
-static void *H5O_attr_decode (H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_attr_decode (H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static void *H5O_attr_copy (const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_attr_size (const H5F_t *f, const void *_mesg);
static herr_t H5O_attr_reset (void *_mesg);
@@ -105,7 +105,7 @@ H5FL_EXTERN(H5S_extent_t);
*
--------------------------------------------------------------------------*/
static void *
-H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *sh)
+H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p)
{
H5A_t *attr = NULL;
H5S_extent_t *extent; /*extent dimensionality information */
@@ -155,7 +155,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *
H5O_shared_t *shared; /* Shared information */
/* Get the shared information */
- if (NULL == (shared = (H5O_SHARED->decode) (f, dxpl_id, p, NULL)))
+ if (NULL == (shared = (H5O_SHARED->decode) (f, dxpl_id, p)))
HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode shared message");
/* Get the actual datatype information */
@@ -166,7 +166,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *
H5O_free_real(H5O_SHARED, shared);
} /* end if */
else {
- if((attr->dt=(H5O_DTYPE->decode)(f,dxpl_id,p,NULL))==NULL)
+ if((attr->dt=(H5O_DTYPE->decode)(f,dxpl_id,p))==NULL)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype");
} /* end else */
if(version < H5O_ATTR_VERSION_NEW)
@@ -178,7 +178,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *
if (NULL==(attr->ds = H5FL_CALLOC(H5S_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- if((extent=(H5O_SDSPACE->decode)(f,dxpl_id,p,NULL))==NULL)
+ if((extent=(H5O_SDSPACE->decode)(f,dxpl_id,p))==NULL)
HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute dataspace");
/* Copy the extent information */
@@ -629,9 +629,10 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, void *native_src,
/* Copy the top level of the attribute */
*attr_dst = *attr_src;
- /* Don't have an opened group entry for copy */
- H5G_ent_reset(&(attr_dst->ent));
- attr_dst->ent_opened = 0;
+ /* Don't have an opened group location for copy */
+ H5O_loc_reset(&(attr_dst->oloc));
+ H5G_name_reset(&(attr_dst->path));
+ attr_dst->obj_opened = 0;
/* Copy attribute's name */
attr_dst->name = H5MM_strdup(attr_src->name);
@@ -642,21 +643,21 @@ H5O_attr_copy_file(H5F_t UNUSED *file_src, void *native_src,
/* Check for named datatype being copied */
if(H5T_committed(attr_src->dt)) {
- H5G_entry_t *ent_src; /* Pointer to source datatype's group entry */
- H5G_entry_t *ent_dst; /* Pointer to dest. datatype's group entry */
+ H5O_loc_t *src_oloc; /* Pointer to source datatype's object location */
+ H5O_loc_t *dst_oloc; /* Pointer to dest. datatype's object location */
/* Get group entries for source & destination */
- ent_src = H5T_entof(attr_src->dt);
- HDassert(ent_src);
- ent_dst = H5T_entof(attr_dst->dt);
- HDassert(ent_dst);
+ src_oloc = H5T_oloc(attr_src->dt);
+ HDassert(src_oloc);
+ dst_oloc = H5T_oloc(attr_dst->dt);
+ HDassert(dst_oloc);
- /* Reset group entry for new object */
- H5G_ent_reset(ent_dst);
- ent_dst->file = file_dst;
+ /* Reset object location for new object */
+ H5O_loc_reset(dst_oloc);
+ dst_oloc->file = file_dst;
/* Copy the shared object from source to destination */
- if(H5O_copy_header_map(ent_src, ent_dst, dxpl_id, map_list) < 0)
+ if(H5O_copy_header_map(src_oloc, dst_oloc, dxpl_id, map_list) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
} /* end if */
@@ -725,11 +726,11 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in
"Initialized:",
(unsigned int)mesg->initialized);
fprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
- "Opened:",
- (unsigned int)mesg->ent_opened);
- fprintf(stream, "%*sSymbol table entry...\n", indent, "");
- H5G_ent_debug(f, dxpl_id, &(mesg->ent), stream, indent+3, MAX(0, fwidth-3),
- HADDR_UNDEF);
+ "Object opened:",
+ (unsigned int)mesg->obj_opened);
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Object:",
+ mesg->oloc.addr);
fprintf(stream, "%*sData type...\n", indent, "");
fprintf(stream, "%*s%-*s %lu\n", indent+3, "", MAX(0,fwidth-3),
diff --git a/src/H5Obogus.c b/src/H5Obogus.c
index 7296860..7596ae2 100644
--- a/src/H5Obogus.c
+++ b/src/H5Obogus.c
@@ -39,7 +39,7 @@
#ifdef H5O_ENABLE_BOGUS
/* PRIVATE PROTOTYPES */
-static void *H5O_bogus_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_bogus_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static herr_t H5O_bogus_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static size_t H5O_bogus_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_bogus_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
@@ -85,8 +85,7 @@ const H5O_class_t H5O_BOGUS[1] = {{
*-------------------------------------------------------------------------
*/
static void *
-H5O_bogus_decode(H5F_t UNUSED *f, hid_t dxpl_id, const uint8_t *p,
- H5O_shared_t UNUSED *sh)
+H5O_bogus_decode(H5F_t UNUSED *f, hid_t dxpl_id, const uint8_t *p)
{
H5O_bogus_t *mesg=NULL;
void *ret_value; /* Return value */
@@ -96,7 +95,6 @@ H5O_bogus_decode(H5F_t UNUSED *f, hid_t dxpl_id, const uint8_t *p,
/* check args */
assert(f);
assert(p);
- assert(!sh);
/* Allocate the bogus message */
if (NULL==(mesg = H5MM_calloc(sizeof(H5O_bogus_t))))
diff --git a/src/H5Ocache.c b/src/H5Ocache.c
new file mode 100644
index 0000000..e5e20e4
--- /dev/null
+++ b/src/H5Ocache.c
@@ -0,0 +1,554 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Ocache.c
+ * Sep 28 2005
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Object header metadata cache virtual functions.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#define H5O_PACKAGE /*suppress error about including H5Opkg */
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5O_cache_init_interface
+
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5Opkg.h" /* Object headers */
+
+/* Private typedefs */
+
+/* PRIVATE PROTOTYPES */
+
+/* Metadata cache callbacks */
+static H5O_t *H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void *_udata1,
+ void *_udata2);
+static herr_t H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh);
+static herr_t H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy);
+static herr_t H5O_compute_size(const H5F_t *f, const H5O_t *oh, size_t *size_ptr);
+
+/* H5O inherits cache-like properties from H5AC */
+const H5AC_class_t H5AC_OHDR[1] = {{
+ H5AC_OHDR_ID,
+ (H5AC_load_func_t)H5O_load,
+ (H5AC_flush_func_t)H5O_flush,
+ (H5AC_dest_func_t)H5O_dest,
+ (H5AC_clear_func_t)H5O_clear,
+ (H5AC_size_func_t)H5O_compute_size,
+}};
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_cache_init_interface
+ *
+ * Purpose: Initialize the H5O interface. (Just calls
+ * H5O_init_iterface currently).
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, September 28, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_cache_init_interface(void)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_cache_init_interface)
+
+ FUNC_LEAVE_NOAPI(H5O_init())
+} /* end H5O_cache_init_interface() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_load
+ *
+ * Purpose: Loads an object header from disk.
+ *
+ * Return: Success: Pointer to the new object header.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 5 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5O_t *
+H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1,
+ void UNUSED * _udata2)
+{
+ H5O_t *oh = NULL;
+ H5O_t *ret_value;
+ uint8_t buf[16], *p;
+ size_t mesg_size;
+ size_t hdr_size;
+ unsigned id;
+ int mesgno;
+ unsigned curmesg = 0, nmesgs;
+ unsigned chunkno;
+ unsigned skipped_msgs = 0; /* Number of unknown messages skipped */
+ unsigned merged_null_msgs = 0; /* Number of null messages merged together */
+ haddr_t chunk_addr;
+ size_t chunk_size;
+ uint8_t flags;
+
+ FUNC_ENTER_NOAPI(H5O_load, NULL)
+
+ /* check args */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(!_udata1);
+ HDassert(!_udata2);
+
+ /* allocate ohdr and init chunk list */
+ if (NULL==(oh = H5FL_CALLOC(H5O_t)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+ /* read fixed-lenth part of object header */
+ hdr_size = H5O_SIZEOF_HDR(f);
+ assert(hdr_size<=sizeof(buf));
+ if (H5F_block_read(f, H5FD_MEM_OHDR, addr, hdr_size, dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header");
+ p = buf;
+
+ /* decode version */
+ oh->version = *p++;
+ if (H5O_VERSION != oh->version)
+ HGOTO_ERROR(H5E_OHDR, H5E_VERSION, NULL, "bad object header version number");
+
+ /* reserved */
+ p++;
+
+ /* decode number of messages */
+ UINT16DECODE(p, nmesgs);
+
+ /* decode link count */
+ UINT32DECODE(p, oh->nlink);
+
+ /* decode first chunk info */
+ chunk_addr = addr + (hsize_t)hdr_size;
+ UINT32DECODE(p, chunk_size);
+
+ /* build the message array */
+ oh->alloc_nmesgs = MAX(H5O_NMESGS, nmesgs);
+ if (NULL==(oh->mesg=H5FL_SEQ_CALLOC(H5O_mesg_t,(size_t)oh->alloc_nmesgs)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+
+ /* read each chunk from disk */
+ while(H5F_addr_defined(chunk_addr)) {
+ /* increase chunk array size */
+ if(oh->nchunks >= oh->alloc_nchunks) {
+ unsigned na = oh->alloc_nchunks + H5O_NCHUNKS;
+ H5O_chunk_t *x = H5FL_SEQ_REALLOC (H5O_chunk_t, oh->chunk, (size_t)na);
+
+ if(!x)
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ oh->alloc_nchunks = na;
+ oh->chunk = x;
+ } /* end if */
+
+ /* read the chunk raw data */
+ chunkno = oh->nchunks++;
+ oh->chunk[chunkno].dirty = FALSE;
+ oh->chunk[chunkno].addr = chunk_addr;
+ oh->chunk[chunkno].size = chunk_size;
+ if(NULL==(oh->chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image, chunk_size)))
+ HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ if(H5F_block_read(f, H5FD_MEM_OHDR, chunk_addr, chunk_size, dxpl_id, oh->chunk[chunkno].image) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_READERROR, NULL, "unable to read object header data");
+
+ /* load messages from this chunk */
+ for(p = oh->chunk[chunkno].image; p < oh->chunk[chunkno].image + chunk_size; p += mesg_size) {
+ UINT16DECODE(p, id);
+ UINT16DECODE(p, mesg_size);
+ HDassert(mesg_size==H5O_ALIGN (mesg_size));
+ flags = *p++;
+ p += 3; /*reserved*/
+
+ /* Try to detect invalidly formatted object header messages */
+ if(p + mesg_size > oh->chunk[chunkno].image + chunk_size)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "corrupt object header")
+
+ /* Skip header messages we don't know about */
+ /* (Usually from future versions of the library */
+ if(id >= NELMTS(message_type_g) || NULL == message_type_g[id]) {
+ skipped_msgs++;
+ continue;
+ } /* end if */
+
+ if(H5O_NULL_ID == id && oh->nmesgs > 0 &&
+ H5O_NULL_ID == oh->mesg[oh->nmesgs - 1].type->id &&
+ oh->mesg[oh->nmesgs - 1].chunkno == chunkno) {
+ /* combine adjacent null messages */
+ mesgno = oh->nmesgs - 1;
+ oh->mesg[mesgno].raw_size += H5O_SIZEOF_MSGHDR(f) + mesg_size;
+ merged_null_msgs++;
+ } else {
+ /* new message */
+ if (oh->nmesgs >= nmesgs)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "corrupt object header - too many messages");
+ mesgno = oh->nmesgs++;
+ oh->mesg[mesgno].type = message_type_g[id];
+ oh->mesg[mesgno].dirty = FALSE;
+ oh->mesg[mesgno].flags = flags;
+ oh->mesg[mesgno].native = NULL;
+ oh->mesg[mesgno].raw = p;
+ oh->mesg[mesgno].raw_size = mesg_size;
+ oh->mesg[mesgno].chunkno = chunkno;
+ } /* end else */
+ } /* end for */
+
+ HDassert(p == oh->chunk[chunkno].image + chunk_size);
+
+ /* decode next object header continuation message */
+ for(chunk_addr = HADDR_UNDEF; !H5F_addr_defined(chunk_addr) && curmesg < oh->nmesgs; ++curmesg) {
+ if(H5O_CONT_ID == oh->mesg[curmesg].type->id) {
+ H5O_cont_t *cont;
+
+ cont = (H5O_CONT->decode) (f, dxpl_id, oh->mesg[curmesg].raw);
+ oh->mesg[curmesg].native = cont;
+ chunk_addr = cont->addr;
+ chunk_size = cont->size;
+ cont->chunkno = oh->nchunks; /*the next chunk to allocate */
+ } /* end if */
+ } /* end for */
+ } /* end while */
+
+ /* Sanity check for the correct # of messages in object header */
+ if((oh->nmesgs + skipped_msgs + merged_null_msgs) != nmesgs)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "corrupt object header - too few messages")
+
+ /* Set return value */
+ ret_value = oh;
+
+done:
+ if(!ret_value && oh) {
+ if(H5O_dest(f,oh) < 0)
+ HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, NULL, "unable to destroy object header data")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_load() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_flush
+ *
+ * Purpose: Flushes (and destroys) an object header.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Robb Matzke
+ * matzke@llnl.gov
+ * Aug 5 1997
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh)
+{
+ uint8_t buf[16], *p;
+ int id;
+ H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */
+ herr_t (*encode)(H5F_t*, uint8_t*, const void*) = NULL;
+ unsigned combine = 0; /* Whether to combine the object header prefix & the first chunk */
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI(H5O_flush, FAIL)
+
+ /* check args */
+ HDassert(f);
+ HDassert(H5F_addr_defined(addr));
+ HDassert(oh);
+
+ /* flush */
+ if(oh->cache_info.is_dirty) {
+ /* Encode any dirty messages */
+ for(u = 0, curr_msg = &oh->mesg[0]; u < oh->nmesgs; u++, curr_msg++) {
+ if(curr_msg->dirty) {
+ p = curr_msg->raw - H5O_SIZEOF_MSGHDR(f);
+
+ id = curr_msg->type->id;
+ UINT16ENCODE(p, id);
+ HDassert(curr_msg->raw_size < H5O_MAX_SIZE);
+ UINT16ENCODE(p, curr_msg->raw_size);
+ *p++ = curr_msg->flags;
+ *p++ = 0; /*reserved*/
+ *p++ = 0; /*reserved*/
+ *p++ = 0; /*reserved*/
+
+ if(curr_msg->native) {
+ HDassert(curr_msg->type->encode);
+
+ /* allocate file space for chunks that have none yet */
+ if(H5O_CONT_ID == curr_msg->type->id && !H5F_addr_defined(((H5O_cont_t *)(curr_msg->native))->addr))
+ /* We now allocate disk space on insertion, instead
+ * of on flush from the cache, so this case is now an
+ * error. -- JRM
+ */
+ HGOTO_ERROR(H5E_OHDR, H5E_SYSTEM, FAIL, "File space for message not allocated!?!")
+
+ /*
+ * Encode the message. If the message is shared then we
+ * encode a Shared Object message instead of the object
+ * which is being shared.
+ */
+ HDassert(curr_msg->raw >= oh->chunk[curr_msg->chunkno].image);
+ HDassert(curr_msg->raw_size == H5O_ALIGN (curr_msg->raw_size));
+ HDassert(curr_msg->raw + curr_msg->raw_size <=
+ oh->chunk[curr_msg->chunkno].image + oh->chunk[curr_msg->chunkno].size);
+ if(curr_msg->flags & H5O_FLAG_SHARED)
+ encode = H5O_SHARED->encode;
+ else
+ encode = curr_msg->type->encode;
+ if((encode)(f, curr_msg->raw, curr_msg->native) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message")
+ } /* end if */
+ curr_msg->dirty = FALSE;
+ oh->chunk[curr_msg->chunkno].dirty = TRUE;
+ } /* end if */
+ } /* end for */
+
+ /* Sanity check for the correct # of messages in object header */
+ if(oh->nmesgs != u)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "corrupt object header - too few messages")
+
+ /* Encode header prefix */
+ p = buf;
+
+ /* encode version */
+ *p++ = oh->version;
+
+ /* reserved */
+ *p++ = 0;
+
+ /* encode number of messages */
+ UINT16ENCODE(p, oh->nmesgs);
+
+ /* encode link count */
+ UINT32ENCODE(p, oh->nlink);
+
+ /* encode body size */
+ UINT32ENCODE(p, oh->chunk[0].size);
+
+ /* zero to alignment */
+ HDmemset (p, 0, (size_t)(H5O_SIZEOF_HDR(f)-12));
+
+ /* write the object header prefix */
+
+ /* Check if we can combine the object header prefix & the first chunk into one I/O operation */
+ if(oh->chunk[0].dirty && (addr + H5O_SIZEOF_HDR(f)) == oh->chunk[0].addr) {
+ combine = 1;
+ } /* end if */
+ else {
+ if(H5F_block_write(f, H5FD_MEM_OHDR, addr, (size_t)H5O_SIZEOF_HDR(f), dxpl_id, buf) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header hdr to disk")
+ } /* end else */
+
+ /* write each chunk to disk */
+ for(u = 0; u < oh->nchunks; u++) {
+ if(oh->chunk[u].dirty) {
+ HDassert(H5F_addr_defined(oh->chunk[u].addr));
+ if(u == 0 && combine) {
+ /* Allocate space for the combined prefix and first chunk */
+ if((p = H5FL_BLK_MALLOC(chunk_image,(H5O_SIZEOF_HDR(f)+oh->chunk[u].size))) == NULL)
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
+
+ /* Copy in the prefix */
+ HDmemcpy(p, buf, (size_t)H5O_SIZEOF_HDR(f));
+
+ /* Copy in the first chunk */
+ HDmemcpy(p + H5O_SIZEOF_HDR(f), oh->chunk[u].image, oh->chunk[u].size);
+
+ /* Write the combined prefix/chunk out */
+ if(H5F_block_write(f, H5FD_MEM_OHDR, addr,
+ (H5O_SIZEOF_HDR(f) + oh->chunk[u].size), dxpl_id, p) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header data to disk")
+
+ /* Release the memory for the combined prefix/chunk */
+ p = H5FL_BLK_FREE(chunk_image,p);
+ } /* end if */
+ else {
+ if(H5F_block_write(f, H5FD_MEM_OHDR, oh->chunk[u].addr,
+ (oh->chunk[u].size), dxpl_id, oh->chunk[u].image) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_WRITEERROR, FAIL, "unable to write object header data to disk")
+ } /* end else */
+ oh->chunk[u].dirty = FALSE;
+ } /* end if */
+ } /* end for */
+ oh->cache_info.is_dirty = FALSE;
+ } /* end if */
+
+ if (destroy) {
+ if(H5O_dest(f,oh) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_flush() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_dest
+ *
+ * Purpose: Destroys an object header.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Jan 15 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5O_dest(H5F_t UNUSED *f, H5O_t *oh)
+{
+ unsigned i;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_dest);
+
+ /* check args */
+ assert(oh);
+
+ /* Verify that node is clean */
+ assert (oh->cache_info.is_dirty==FALSE);
+
+ /* destroy chunks */
+ for (i = 0; i < oh->nchunks; i++) {
+ /* Verify that chunk is clean */
+ assert (oh->chunk[i].dirty==0);
+
+ oh->chunk[i].image = H5FL_BLK_FREE(chunk_image,oh->chunk[i].image);
+ }
+ if(oh->chunk)
+ oh->chunk = H5FL_SEQ_FREE(H5O_chunk_t,oh->chunk);
+
+ /* destroy messages */
+ for (i = 0; i < oh->nmesgs; i++) {
+ /* Verify that message is clean */
+ assert (oh->mesg[i].dirty==0);
+
+ H5O_free_mesg(&oh->mesg[i]);
+ }
+ if(oh->mesg)
+ oh->mesg = H5FL_SEQ_FREE(H5O_mesg_t,oh->mesg);
+
+ /* destroy object header */
+ H5FL_FREE(H5O_t,oh);
+
+ FUNC_LEAVE_NOAPI(SUCCEED);
+} /* end H5O_dest() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_clear
+ *
+ * Purpose: Mark a object header in memory as non-dirty.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Mar 20 2003
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_clear(H5F_t *f, H5O_t *oh, hbool_t destroy)
+{
+ unsigned u; /* Local index variable */
+ herr_t ret_value = SUCCEED;
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_clear);
+
+ /* check args */
+ assert(oh);
+
+ /* Mark chunks as clean */
+ for (u = 0; u < oh->nchunks; u++)
+ oh->chunk[u].dirty=FALSE;
+
+ /* Mark messages as clean */
+ for (u = 0; u < oh->nmesgs; u++)
+ oh->mesg[u].dirty=FALSE;
+
+ /* Mark whole header as clean */
+ oh->cache_info.is_dirty=FALSE;
+
+ if (destroy)
+ if (H5O_dest(f, oh) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data");
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5O_clear() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_compute_size
+ *
+ * Purpose: Compute the size in bytes of the specified instance of
+ * H5O_t on disk, and return it in *len_ptr. On failure,
+ * the value of *len_ptr is undefined.
+ *
+ * The value returned will probably be low unless the object
+ * has just been flushed, as we simply total up the size of
+ * the header with the sizes of the chunks. Thus any message
+ * that has been added since the last flush will not be
+ * reflected in the total.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: John Mainzer
+ * 5/13/04
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_compute_size(const H5F_t *f, const H5O_t *oh, size_t *size_ptr)
+{
+ unsigned u;
+ size_t size;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_compute_size);
+
+ /* check args */
+ HDassert(f);
+ HDassert(oh);
+ HDassert(size_ptr);
+
+ size = H5O_SIZEOF_HDR(f);
+
+ for (u = 0; u < oh->nchunks; u++)
+ size += oh->chunk[u].size;
+
+ HDassert(size >= H5O_SIZEOF_HDR(f));
+
+ *size_ptr = size;
+
+ FUNC_LEAVE_NOAPI(SUCCEED);
+} /* H5O_compute_size() */
+
diff --git a/src/H5Ocont.c b/src/H5Ocont.c
index afa5ab7..f471c61 100644
--- a/src/H5Ocont.c
+++ b/src/H5Ocont.c
@@ -23,25 +23,24 @@
* the H5O package. Therefore, do not change
* any definitions in this file!
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
#define H5O_PACKAGE /*suppress error about including H5Opkg */
-#include "H5private.h"
-#include "H5Eprivate.h"
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free Lists */
-#include "H5MMprivate.h"
-#include "H5Opkg.h" /* Object header functions */
+#include "H5MFprivate.h" /* File memory management */
+#include "H5Opkg.h" /* Object headers */
/* PRIVATE PROTOTYPES */
-static void *H5O_cont_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_cont_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static herr_t H5O_cont_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static size_t H5O_cont_size(const H5F_t *f, const void *_mesg);
static herr_t H5O_cont_free(void *mesg);
+static herr_t H5O_cont_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
static void *H5O_cont_copy_file(H5F_t *file_src, void *mesg_src,
H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
static herr_t H5O_cont_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream,
@@ -58,7 +57,7 @@ const H5O_class_t H5O_CONT[1] = {{
H5O_cont_size, /*size of header continuation */
NULL, /*reset method */
H5O_cont_free, /* free method */
- NULL, /* file delete method */
+ H5O_cont_delete, /* file delete method */
NULL, /* link method */
NULL, /*get share method */
NULL, /*set share method */
@@ -89,7 +88,7 @@ H5FL_DEFINE(H5O_cont_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_cont_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *sh)
+H5O_cont_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
H5O_cont_t *cont = NULL;
void *ret_value;
@@ -99,7 +98,6 @@ H5O_cont_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_t U
/* check args */
assert(f);
assert(p);
- assert (!sh);
/* decode */
if (NULL==(cont = H5FL_MALLOC(H5O_cont_t)))
@@ -213,6 +211,39 @@ H5O_cont_free (void *mesg)
/*-------------------------------------------------------------------------
+ * Function: H5O_cont_delete
+ *
+ * Purpose: Free file space referenced by message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, October 10, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_cont_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t UNUSED adj_link)
+{
+ const H5O_cont_t *mesg = (const H5O_cont_t *) _mesg;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_cont_delete)
+
+ /* check args */
+ HDassert(f);
+ HDassert(mesg);
+
+ /* Release space for chunk */
+ if(H5MF_xfree(f, H5FD_MEM_OHDR, dxpl_id, mesg->addr, (hsize_t)mesg->size) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to free object header chunk")
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_cont_delete() */
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_cont_copy_file
*
* Purpose: Copies a continuation block message from _MESG to _DEST in file
@@ -228,7 +259,7 @@ H5O_cont_free (void *mesg)
*/
static void *
H5O_cont_copy_file(H5F_t UNUSED *file_src, void *mesg_src,
- H5F_t *file_dst, hid_t UNUSED dxpl_id, H5SL_t UNUSED *map_list, void *udata)
+ H5F_t UNUSED *file_dst, hid_t UNUSED dxpl_id, H5SL_t UNUSED *map_list, void *udata)
{
H5O_cont_t *cont_src = (H5O_cont_t *) mesg_src;
H5O_chunk_t *chunk = (H5O_chunk_t *)udata;
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 05ca879..73d8909 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -26,7 +26,7 @@
/* PRIVATE PROTOTYPES */
static herr_t H5O_dtype_encode (H5F_t *f, uint8_t *p, const void *mesg);
-static void *H5O_dtype_decode (H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_dtype_decode (H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static void *H5O_dtype_copy (const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_dtype_size (const H5F_t *f, const void *_mesg);
static herr_t H5O_dtype_reset (void *_mesg);
@@ -67,10 +67,6 @@ const H5O_class_t H5O_DTYPE[1] = {{
* class objects (array definitely, potentially compound & vlen sequences also) */
#define H5O_DTYPE_VERSION_UPDATED 2
-/* Declare external the free list for H5T_t's */
-H5FL_EXTERN(H5T_t);
-H5FL_EXTERN(H5T_shared_t);
-
/*-------------------------------------------------------------------------
* Function: H5O_dtype_decode_helper
@@ -823,8 +819,7 @@ done:
function using malloc() and is returned to the caller.
--------------------------------------------------------------------------*/
static void *
-H5O_dtype_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p,
- H5O_shared_t UNUSED *sh)
+H5O_dtype_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
H5T_t *dt = NULL;
void *ret_value; /* Return value */
@@ -1103,8 +1098,6 @@ H5O_dtype_free (void *mesg)
* Programmer: Robb Matzke
* Monday, June 1, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
static herr_t
@@ -1112,25 +1105,26 @@ H5O_dtype_get_share(H5F_t UNUSED *f, const void *_mesg,
H5O_shared_t *sh/*out*/)
{
const H5T_t *dt = (const H5T_t *)_mesg;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_dtype_get_share)
- FUNC_ENTER_NOAPI_NOINIT(H5O_dtype_get_share);
+ HDassert(dt);
+ HDassert(sh);
- assert (dt);
- assert (sh);
+ /* Check for object location address defined */
+ if(!H5F_addr_defined(dt->oloc.addr))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype is not sharable")
- if (H5F_addr_defined (dt->ent.header)) {
- /* If the address is defined, this had better be a named datatype */
- HDassert (H5T_STATE_NAMED==dt->shared->state || H5T_STATE_OPEN==dt->shared->state);
+ /* If the address is defined, this had better be a named datatype */
+ HDassert(H5T_STATE_NAMED == dt->shared->state || H5T_STATE_OPEN == dt->shared->state);
- sh->in_gh = FALSE;
- sh->u.ent = dt->ent;
- } else
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype is not sharable");
+ /* Copy object location info */
+ H5O_loc_copy(&(sh->oloc), &(dt->oloc), H5O_COPY_DEEP);
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_dtype_get_share() */
/*-------------------------------------------------------------------------
@@ -1143,33 +1137,27 @@ done:
* Programmer: Robb Matzke
* Thursday, June 4, 1998
*
- * Modifications:
- *
- * Pedro Vicente, <pvn@ncsa.uiuc.edu> 22 Aug 2002
- * Added `id to name' support.
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_dtype_set_share (H5F_t UNUSED *f, void *_mesg/*in,out*/,
+H5O_dtype_set_share(H5F_t UNUSED *f, void *_mesg/*in,out*/,
const H5O_shared_t *sh)
{
H5T_t *dt = (H5T_t *)_mesg;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_dtype_set_share);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_dtype_set_share)
- assert (dt);
- assert (sh);
- assert (!sh->in_gh);
+ HDassert(dt);
+ HDassert(sh);
- /* NULL copy here, names not appropriate */
- H5G_ent_copy(&(dt->ent),&(sh->u.ent),H5G_COPY_NULL);
+ /* Retrieve object location information */
+ H5O_loc_copy(&(dt->oloc), &(sh->oloc), H5O_COPY_DEEP);
/* Note that the datatype is a named datatype */
dt->shared->state = H5T_STATE_NAMED;
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_dtype_set_share() */
/*--------------------------------------------------------------------------
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index 8c78cae..24f8c3b 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -28,7 +28,7 @@
#include "H5Opkg.h" /* Object headers */
/* PRIVATE PROTOTYPES */
-static void *H5O_efl_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_efl_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static herr_t H5O_efl_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_efl_copy(const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_efl_size(const H5F_t *f, const void *_mesg);
@@ -81,7 +81,7 @@ const H5O_class_t H5O_EFL[1] = {{
*-------------------------------------------------------------------------
*/
static void *
-H5O_efl_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *sh)
+H5O_efl_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p)
{
H5O_efl_t *mesg = NULL;
int version;
@@ -95,7 +95,6 @@ H5O_efl_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *s
/* Check args */
assert(f);
assert(p);
- assert (!sh);
if (NULL==(mesg = H5MM_calloc(sizeof(H5O_efl_t))))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
diff --git a/src/H5Ofill.c b/src/H5Ofill.c
index b68c106..f6e68a0 100644
--- a/src/H5Ofill.c
+++ b/src/H5Ofill.c
@@ -30,7 +30,7 @@
#include "H5Pprivate.h" /* Property lists */
-static void *H5O_fill_new_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_fill_new_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static herr_t H5O_fill_new_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_fill_new_copy(const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_fill_new_size(const H5F_t *f, const void *_mesg);
@@ -39,7 +39,7 @@ static herr_t H5O_fill_new_free(void *_mesg);
static herr_t H5O_fill_new_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *stream,
int indent, int fwidth);
-static void *H5O_fill_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_fill_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static herr_t H5O_fill_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_fill_copy(const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_fill_size(const H5F_t *f, const void *_mesg);
@@ -119,8 +119,7 @@ H5FL_DEFINE(H5O_fill_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_fill_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p,
- H5O_shared_t UNUSED *sh)
+H5O_fill_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
H5O_fill_new_t *mesg=NULL;
int version;
@@ -130,7 +129,6 @@ H5O_fill_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p,
assert(f);
assert(p);
- assert(!sh);
if (NULL==(mesg=H5FL_CALLOC(H5O_fill_new_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message");
@@ -193,8 +191,7 @@ done:
*-------------------------------------------------------------------------
*/
static void *
-H5O_fill_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p,
- H5O_shared_t UNUSED *sh)
+H5O_fill_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
H5O_fill_t *mesg=NULL;
void *ret_value;
@@ -203,7 +200,6 @@ H5O_fill_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p,
assert(f);
assert(p);
- assert(!sh);
if (NULL==(mesg=H5FL_CALLOC(H5O_fill_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed for fill value message");
diff --git a/src/H5Oginfo.c b/src/H5Oginfo.c
new file mode 100644
index 0000000..6aeda3d
--- /dev/null
+++ b/src/H5Oginfo.c
@@ -0,0 +1,334 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Oginfo.c
+ * Aug 23 2005
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Group Information messages.
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#define H5O_PACKAGE /*suppress error about including H5Opkg */
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5Opkg.h" /* Object headers */
+
+
+/* PRIVATE PROTOTYPES */
+static void *H5O_ginfo_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
+static herr_t H5O_ginfo_encode(H5F_t *f, uint8_t *p, const void *_mesg);
+static void *H5O_ginfo_copy(const void *_mesg, void *_dest, unsigned update_flags);
+static size_t H5O_ginfo_size(const H5F_t *f, const void *_mesg);
+static herr_t H5O_ginfo_free(void *_mesg);
+static herr_t H5O_ginfo_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
+ FILE * stream, int indent, int fwidth);
+
+/* This message derives from H5O */
+const H5O_class_t H5O_GINFO[1] = {{
+ H5O_GINFO_ID, /*message id number */
+ "ginfo", /*message name for debugging */
+ sizeof(H5O_ginfo_t), /*native message size */
+ H5O_ginfo_decode, /*decode message */
+ H5O_ginfo_encode, /*encode message */
+ H5O_ginfo_copy, /*copy the native value */
+ H5O_ginfo_size, /*size of symbol table entry */
+ NULL, /*default reset method */
+ H5O_ginfo_free, /* free method */
+ NULL, /* file delete method */
+ NULL, /* link method */
+ NULL, /*get share method */
+ NULL, /*set share method */
+ NULL, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_ginfo_debug /*debug the message */
+}};
+
+/* Current version of group info information */
+#define H5O_GINFO_VERSION 1
+
+/* Declare a free list to manage the H5O_ginfo_t struct */
+H5FL_DEFINE_STATIC(H5O_ginfo_t);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_ginfo_decode
+ *
+ * Purpose: Decode a message and return a pointer to
+ * a newly allocated one.
+ *
+ * Return: Success: Ptr to new message in native order.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 30 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_ginfo_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p)
+{
+ H5O_ginfo_t *ginfo = NULL; /* Pointer to group information message */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_ginfo_decode)
+
+ /* check args */
+ HDassert(f);
+ HDassert(p);
+
+ /* decode */
+ if(*p++ != H5O_GINFO_VERSION)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")
+
+ /* Allocate space for message */
+ if(NULL == (ginfo = H5FL_CALLOC(H5O_ginfo_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Get the local heap size hint */
+ UINT32DECODE(p, ginfo->lheap_size_hint)
+
+ /* Get the max. # of links to store compactly & the min. # of links to store densely */
+ UINT32DECODE(p, ginfo->max_compact)
+ UINT32DECODE(p, ginfo->min_dense)
+
+ /* Get the estimated # of entries & name lengths */
+ UINT32DECODE(p, ginfo->est_num_entries)
+ UINT32DECODE(p, ginfo->est_name_len)
+
+ /* Set return value */
+ ret_value=ginfo;
+
+done:
+ if(ret_value == NULL)
+ if(ginfo != NULL)
+ H5FL_FREE(H5O_ginfo_t, ginfo);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_ginfo_decode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_ginfo_encode
+ *
+ * Purpose: Encodes a message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 30 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_ginfo_encode(H5F_t UNUSED *f, uint8_t *p, const void *_mesg)
+{
+ const H5O_ginfo_t *ginfo = (const H5O_ginfo_t *) _mesg;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_ginfo_encode)
+
+ /* check args */
+ HDassert(f);
+ HDassert(p);
+ HDassert(ginfo);
+
+ /* encode */
+ *p++ = H5O_GINFO_VERSION;
+
+ /* Store the local heap size hint for the group */
+ UINT32ENCODE(p, ginfo->lheap_size_hint)
+
+ /* Store the max. # of links to store compactly & the min. # of links to store densely */
+ UINT32ENCODE(p, ginfo->max_compact)
+ UINT32ENCODE(p, ginfo->min_dense)
+
+ /* Store the estimated # of entries & name lengths */
+ UINT32ENCODE(p, ginfo->est_num_entries)
+ UINT32ENCODE(p, ginfo->est_name_len)
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_ginfo_encode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_ginfo_copy
+ *
+ * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
+ * necessary.
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 30 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_ginfo_copy(const void *_mesg, void *_dest, unsigned UNUSED update_flags)
+{
+ const H5O_ginfo_t *ginfo = (const H5O_ginfo_t *) _mesg;
+ H5O_ginfo_t *dest = (H5O_ginfo_t *) _dest;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_ginfo_copy)
+
+ /* check args */
+ HDassert(ginfo);
+ if(!dest && NULL == (dest = H5FL_MALLOC(H5O_ginfo_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* copy */
+ *dest = *ginfo;
+
+ /* Set return value */
+ ret_value=dest;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_ginfo_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_ginfo_size
+ *
+ * Purpose: Returns the size of the raw message in bytes not counting
+ * the message type or size fields, but only the data fields.
+ * This function doesn't take into account alignment.
+ *
+ * Return: Success: Message data size in bytes without alignment.
+ *
+ * Failure: zero
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 30 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5O_ginfo_size(const H5F_t UNUSED *f, const void UNUSED *_mesg)
+{
+ size_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_ginfo_size)
+
+ /* Set return value */
+ ret_value = 1 + /* Version */
+ 4 + /* Local heap size hint */
+ 4 + /* "Max compact" links */
+ 4 + /* "Min dense" links */
+ 4 + /* Estimated # of entries in group */
+ 4; /* Estimated length of name of entry in group */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_ginfo_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_ginfo_free
+ *
+ * Purpose: Free's the message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, August 30, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_ginfo_free(void *mesg)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_ginfo_free)
+
+ HDassert(mesg);
+
+ H5FL_FREE(H5O_ginfo_t, mesg);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_ginfo_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_ginfo_debug
+ *
+ * Purpose: Prints debugging info for a message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 30 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_ginfo_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * stream,
+ int indent, int fwidth)
+{
+ const H5O_ginfo_t *ginfo = (const H5O_ginfo_t *) _mesg;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_ginfo_debug)
+
+ /* check args */
+ HDassert(f);
+ HDassert(ginfo);
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Local heap size hint:", ginfo->lheap_size_hint);
+
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Max. compact links:", ginfo->max_compact);
+
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Min. dense links:", ginfo->min_dense);
+
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Estimated # of objects in group:", ginfo->est_num_entries);
+
+ HDfprintf(stream, "%*s%-*s %u\n", indent, "", fwidth,
+ "Estimated length of object in group's name:", ginfo->est_name_len);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_ginfo_debug() */
+
+
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 3103053..0844010 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -32,7 +32,7 @@
#include "H5Pprivate.h" /* Property lists */
/* PRIVATE PROTOTYPES */
-static void *H5O_layout_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_layout_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static herr_t H5O_layout_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_layout_copy(const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_layout_size(const H5F_t *f, const void *_mesg);
@@ -105,7 +105,7 @@ H5FL_DEFINE(H5O_layout_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *sh)
+H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
H5O_layout_t *mesg = NULL;
unsigned u;
@@ -116,7 +116,6 @@ H5O_layout_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_t
/* check args */
assert(f);
assert(p);
- assert (!sh);
/* decode */
if (NULL==(mesg = H5FL_CALLOC(H5O_layout_t)))
@@ -768,3 +767,4 @@ H5O_layout_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE
FUNC_LEAVE_NOAPI(SUCCEED);
}
+
diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c
new file mode 100644
index 0000000..cc0ce2d
--- /dev/null
+++ b/src/H5Olinfo.c
@@ -0,0 +1,301 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Olinfo.c
+ * Aug 23 2005
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Link Information messages.
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#define H5O_PACKAGE /*suppress error about including H5Opkg */
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5Opkg.h" /* Object headers */
+
+
+/* PRIVATE PROTOTYPES */
+static void *H5O_linfo_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
+static herr_t H5O_linfo_encode(H5F_t *f, uint8_t *p, const void *_mesg);
+static void *H5O_linfo_copy(const void *_mesg, void *_dest, unsigned update_flags);
+static size_t H5O_linfo_size(const H5F_t *f, const void *_mesg);
+static herr_t H5O_linfo_free(void *_mesg);
+static herr_t H5O_linfo_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
+ FILE * stream, int indent, int fwidth);
+
+/* This message derives from H5O */
+const H5O_class_t H5O_LINFO[1] = {{
+ H5O_LINFO_ID, /*message id number */
+ "linfo", /*message name for debugging */
+ sizeof(H5O_linfo_t), /*native message size */
+ H5O_linfo_decode, /*decode message */
+ H5O_linfo_encode, /*encode message */
+ H5O_linfo_copy, /*copy the native value */
+ H5O_linfo_size, /*size of symbol table entry */
+ NULL, /*default reset method */
+ H5O_linfo_free, /* free method */
+ NULL, /* file delete method */
+ NULL, /* link method */
+ NULL, /*get share method */
+ NULL, /*set share method */
+ NULL, /* copy native value to file */
+ NULL, /* post copy native value to file */
+ H5O_linfo_debug /*debug the message */
+}};
+
+/* Current version of link info information */
+#define H5O_LINFO_VERSION 1
+
+/* Declare a free list to manage the hsize_t struct */
+H5FL_DEFINE_STATIC(H5O_linfo_t);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_linfo_decode
+ *
+ * Purpose: Decode a message and return a pointer to
+ * a newly allocated one.
+ *
+ * Return: Success: Ptr to new message in native order.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 23 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_linfo_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
+{
+ H5O_linfo_t *linfo = NULL; /* Link info */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_linfo_decode)
+
+ /* check args */
+ HDassert(f);
+ HDassert(p);
+
+ /* decode */
+ if(*p++ != H5O_LINFO_VERSION)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")
+
+ /* Allocate space for message */
+ if (NULL == (linfo = H5FL_MALLOC(H5O_linfo_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Get the number of links in the group */
+ H5F_DECODE_LENGTH(f, p, linfo->nlinks)
+
+ /* Set return value */
+ ret_value = linfo;
+
+done:
+ if(ret_value == NULL)
+ if(linfo != NULL)
+ H5FL_FREE(H5O_linfo_t, linfo);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_linfo_decode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_linfo_encode
+ *
+ * Purpose: Encodes a message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 23 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_linfo_encode(H5F_t *f, uint8_t *p, const void *_mesg)
+{
+ const H5O_linfo_t *linfo = (const H5O_linfo_t *) _mesg;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_linfo_encode)
+
+ /* check args */
+ HDassert(f);
+ HDassert(p);
+ HDassert(linfo);
+
+ /* encode */
+ *p++ = H5O_LINFO_VERSION;
+
+ /* Store the number of links in the group */
+ H5F_ENCODE_LENGTH(f, p, linfo->nlinks)
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_linfo_encode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_linfo_copy
+ *
+ * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
+ * necessary.
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 23 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_linfo_copy(const void *_mesg, void *_dest, unsigned UNUSED update_flags)
+{
+ const H5O_linfo_t *linfo = (const H5O_linfo_t *) _mesg;
+ H5O_linfo_t *dest = (H5O_linfo_t *) _dest;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_linfo_copy)
+
+ /* check args */
+ HDassert(linfo);
+ if(!dest && NULL == (dest = H5FL_MALLOC(H5O_linfo_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* copy */
+ *dest = *linfo;
+
+ /* Set return value */
+ ret_value=dest;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_linfo_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_linfo_size
+ *
+ * Purpose: Returns the size of the raw message in bytes not counting
+ * the message type or size fields, but only the data fields.
+ * This function doesn't take into account alignment.
+ *
+ * Return: Success: Message data size in bytes without alignment.
+ *
+ * Failure: zero
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 23 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5O_linfo_size(const H5F_t *f, const void UNUSED *_mesg)
+{
+ size_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_linfo_size)
+
+ /* Set return value */
+ ret_value = 1 + /* Version */
+ H5F_SIZEOF_SIZE(f); /* Number of links */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_linfo_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_linfo_free
+ *
+ * Purpose: Free's the message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Tuesday, August 23, 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_linfo_free(void *mesg)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_linfo_free)
+
+ HDassert(mesg);
+
+ H5FL_FREE(H5O_linfo_t, mesg);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_linfo_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_linfo_debug
+ *
+ * Purpose: Prints debugging info for a message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 23 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_linfo_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * stream,
+ int indent, int fwidth)
+{
+ const H5O_linfo_t *linfo = (const H5O_linfo_t *) _mesg;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_linfo_debug)
+
+ /* check args */
+ HDassert(f);
+ HDassert(linfo);
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+
+ HDfprintf(stream, "%*s%-*s %Hu\n", indent, "", fwidth,
+ "Number of links:", linfo->nlinks);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_linfo_debug() */
+
diff --git a/src/H5Olink.c b/src/H5Olink.c
new file mode 100644
index 0000000..2284ecb
--- /dev/null
+++ b/src/H5Olink.c
@@ -0,0 +1,672 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * 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: H5Olink.c
+ * Aug 29 2005
+ * Quincey Koziol <koziol@ncsa.uiuc.edu>
+ *
+ * Purpose: Link messages.
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#define H5O_PACKAGE /*suppress error about including H5Opkg */
+
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free lists */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Opkg.h" /* Object headers */
+
+
+/* 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);
+static herr_t H5O_link_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link);
+static void *H5O_link_copy_file(H5F_t *file_src, void *native_src,
+ H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
+static herr_t H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src,
+ H5O_loc_t *dst_oloc, void *mesg_dst, hbool_t *modified, hid_t dxpl_id, H5SL_t *map_list);
+static herr_t H5O_link_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
+ FILE * stream, int indent, int fwidth);
+
+/* This message derives from H5O */
+const H5O_class_t H5O_LINK[1] = {{
+ H5O_LINK_ID, /*message id number */
+ "link", /*message name for debugging */
+ sizeof(H5O_link_t), /*native message size */
+ H5O_link_decode, /*decode message */
+ H5O_link_encode, /*encode message */
+ H5O_link_copy, /*copy the native value */
+ H5O_link_size, /*size of symbol table entry */
+ H5O_link_reset, /* reset method */
+ H5O_link_free, /* free method */
+ H5O_link_delete, /* file delete method */
+ NULL, /* link method */
+ NULL, /*get share method */
+ NULL, /*set share method */
+ H5O_link_copy_file, /* copy native value to file */
+ H5O_link_post_copy_file, /* post copy native value to file */
+ H5O_link_debug /*debug the message */
+}};
+
+/* Current version of link information */
+#define H5O_LINK_VERSION 1
+
+/* Declare a free list to manage the H5O_link_t struct */
+H5FL_DEFINE_STATIC(H5O_link_t);
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_decode
+ *
+ * Purpose: Decode a message and return a pointer to
+ * a newly allocated one.
+ *
+ * Return: Success: Ptr to new message in native order.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 29 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_link_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
+{
+ H5O_link_t *lnk = NULL; /* Pointer to link message */
+ uint16_t len; /* Length of a string in the message */
+ uint32_t tmp_time; /* Temporary copy of the time */
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_link_decode)
+
+ /* check args */
+ HDassert(f);
+ HDassert(p);
+
+ /* decode */
+ if(*p++ != H5O_LINK_VERSION)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for message")
+
+ /* Allocate space for message */
+ if(NULL == (lnk = H5FL_CALLOC(H5O_link_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Get the type of the link */
+ lnk->type = *p++;
+ if(lnk->type < H5G_LINK_HARD || lnk->type > H5G_LINK_SOFT)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad link type")
+
+ /* Get the link creation time from the file */
+ UINT32DECODE(p, tmp_time)
+ lnk->ctime = (time_t)tmp_time;
+
+ /* Get the link name's character set */
+ lnk->cset = (H5T_cset_t)*p++;
+ if(lnk->cset < H5T_CSET_ASCII || lnk->cset > H5T_CSET_UTF8)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad cset type")
+
+ /* Get the link's name */
+ UINT16DECODE(p, len)
+ if(len == 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "invalid name length")
+ if(NULL == (lnk->name = H5MM_malloc((size_t)len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemcpy(lnk->name, p, len);
+ lnk->name[len] = '\0';
+ p += len;
+
+ /* Get the appropriate information for each type of link */
+ switch(lnk->type) {
+ case H5G_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:
+ /* Get the link value */
+ UINT16DECODE(p, len)
+ if(len == 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "invalid link length")
+ if(NULL == (lnk->u.soft.name = H5MM_malloc((size_t)len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+ HDmemcpy(lnk->u.soft.name, p, len);
+ lnk->u.soft.name[len] = '\0';
+ p += len;
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "unknown link type")
+ break;
+ } /* end switch */
+
+ /* Set return value */
+ ret_value=lnk;
+
+done:
+ if(ret_value == NULL)
+ if(lnk != NULL) {
+ if(lnk->name != NULL)
+ H5MM_xfree(lnk->name);
+ if(lnk->type == H5G_LINK_SOFT && lnk->u.soft.name != NULL)
+ H5MM_xfree(lnk->u.soft.name);
+ H5FL_FREE(H5O_link_t, lnk);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_link_decode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_encode
+ *
+ * Purpose: Encodes a link message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 29 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_link_encode(H5F_t *f, uint8_t *p, const void *_mesg)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *) _mesg;
+ uint16_t len; /* Length of a string in the message */
+ uint32_t tmp_time; /* Temporary copy of the time */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_link_encode)
+
+ /* check args */
+ HDassert(f);
+ HDassert(p);
+ HDassert(lnk);
+
+ /* encode */
+ *p++ = H5O_LINK_VERSION;
+
+ /* Store the type of the link */
+ *p++ = lnk->type;
+
+ /* Store the link creation time from the file */
+ tmp_time = lnk->ctime;
+ UINT32ENCODE(p, tmp_time)
+
+ /* Store the link name's character set */
+ *p++ = (uint8_t)lnk->cset;
+
+ /* Store the link's name */
+ len = (uint16_t)HDstrlen(lnk->name);
+ HDassert(len > 0);
+ UINT16ENCODE(p, len)
+ HDmemcpy(p, lnk->name, len);
+ p += len;
+
+ /* Store the appropriate information for each type of link */
+ switch(lnk->type) {
+ case H5G_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:
+ /* Store the link value */
+ len = (uint16_t)HDstrlen(lnk->u.soft.name);
+ HDassert(len > 0);
+ UINT16ENCODE(p, len)
+ HDmemcpy(p, lnk->u.soft.name, len);
+ p += len;
+ break;
+
+ default:
+ HDassert((lnk->type == H5G_LINK_HARD) || (lnk->type == H5G_LINK_SOFT));
+ break;
+ } /* end switch */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_link_encode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_copy
+ *
+ * Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
+ * necessary.
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 29 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_link_copy(const void *_mesg, void *_dest, unsigned UNUSED update_flags)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *) _mesg;
+ H5O_link_t *dest = (H5O_link_t *) _dest;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_link_copy)
+
+ /* check args */
+ HDassert(lnk);
+ if(!dest && NULL == (dest = H5FL_MALLOC(H5O_link_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* copy */
+ *dest = *lnk;
+ HDassert(lnk->name);
+ dest->name = H5MM_xstrdup(lnk->name);
+ if(lnk->type == H5G_LINK_SOFT)
+ dest->u.soft.name = H5MM_xstrdup(lnk->u.soft.name);
+
+ /* Set return value */
+ ret_value=dest;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_link_copy() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_size
+ *
+ * Purpose: Returns the size of the raw message in bytes not counting
+ * the message type or size fields, but only the data fields.
+ * This function doesn't take into account alignment.
+ *
+ * Return: Success: Message data size in bytes without alignment.
+ *
+ * Failure: zero
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 29 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static size_t
+H5O_link_size(const H5F_t *f, const void *_mesg)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *)_mesg;
+ size_t ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_link_size)
+
+ /* Set return value */
+ ret_value = 1 + /* Version */
+ 1 + /* Link type */
+ 4 + /* Creation time */
+ 1 + /* Character set */
+ 2 + /* Name length */
+ HDstrlen(lnk->name); /* Name */
+
+ /* Add the appropriate length for each type of link */
+ switch(lnk->type) {
+ case H5G_LINK_HARD:
+ ret_value += H5F_SIZEOF_ADDR(f);
+ break;
+
+ case H5G_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));
+ break;
+ } /* end switch */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_link_size() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_reset
+ *
+ * Purpose: Frees resources within a message, but doesn't free
+ * the message itself.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 29, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_link_reset(void *_mesg)
+{
+ H5O_link_t *lnk = (H5O_link_t *)_mesg;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_link_reset)
+
+ if(lnk) {
+ /* 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);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_link_reset() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_free
+ *
+ * Purpose: Free's the message contents and the message itself
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 29, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_link_free(void *_mesg)
+{
+ H5O_link_t *lnk = (H5O_link_t *)_mesg;
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_link_free)
+
+ HDassert(lnk);
+
+ /* Free information for link */
+ if(lnk->type == H5G_LINK_SOFT)
+ lnk->u.soft.name = H5MM_xfree(lnk->u.soft.name);
+ lnk->name = H5MM_xfree(lnk->name);
+ H5FL_FREE(H5O_link_t, lnk);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_link_free() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_delete
+ *
+ * Purpose: Free file space referenced by message
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * Monday, August 29, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_link_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_t adj_link)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *)_mesg;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_link_delete)
+
+ /* check args */
+ HDassert(f);
+ HDassert(lnk);
+
+ /* Decrement reference count to the object, for hard links */
+ if(lnk->type == H5G_LINK_HARD) {
+ H5O_loc_t oloc;
+
+ /* Construct object location for object, in order to decrement it's ref count */
+ H5O_loc_reset(&oloc);
+ oloc.file = f;
+ HDassert(H5F_addr_defined(lnk->u.hard.addr));
+ oloc.addr = lnk->u.hard.addr;
+
+ /* Decrement the ref count for the object, if requested */
+ if(adj_link)
+ if(H5O_link(&oloc, -1, dxpl_id)<0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to decrement object link count")
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_link_delete() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_copy_file
+ *
+ * Purpose: Copies a message from _MESG to _DEST in file
+ *
+ * Return: Success: Ptr to _DEST
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * November 7, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static void *
+H5O_link_copy_file(H5F_t UNUSED *file_src, void *native_src,
+ H5F_t UNUSED *file_dst, hid_t UNUSED dxpl_id, H5SL_t UNUSED *map_list, void UNUSED *udata)
+{
+ H5O_link_t *link_src = (H5O_link_t *) native_src;
+ H5O_link_t *link_dst = NULL;
+ void *ret_value; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_link_copy_file)
+
+ /* check args */
+ HDassert(link_src);
+ HDassert(file_dst);
+
+ /* Allocate space for the destination stab */
+ if(NULL == (link_dst = H5FL_MALLOC(H5O_link_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Copy top-level information */
+ *link_dst = *link_src;
+
+ /* Deep copy the link's name */
+ if(NULL == (link_dst->name = H5MM_xstrdup(link_src->name)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* "Deep copy" other information for each kind of link */
+ switch(link_src->type) {
+ case H5G_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:
+ /* 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")
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, NULL, "unrecognized link type")
+ } /* end switch */
+
+ /* Set return value */
+ ret_value = link_dst;
+
+done:
+ if(!ret_value)
+ if(link_dst)
+ H5FL_FREE(H5O_link_t, link_dst);
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_link_copy_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_post_copy_file
+ *
+ * Purpose: Finish copying a message from between files
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * November 7, 2005
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src,
+ H5O_loc_t *dst_oloc, void *mesg_dst, hbool_t *modified, hid_t dxpl_id, H5SL_t *map_list)
+{
+ const H5O_link_t *link_src = (const H5O_link_t *)mesg_src;
+ H5O_link_t *link_dst = (H5O_link_t *)mesg_dst;
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_NOAPI_NOINIT(H5O_link_post_copy_file)
+
+ /* check args */
+ HDassert(link_src);
+ HDassert(dst_oloc);
+ HDassert(H5F_addr_defined(dst_oloc->addr));
+ HDassert(dst_oloc->file);
+ HDassert(link_dst);
+ HDassert(modified && *modified == FALSE);
+ HDassert(map_list);
+
+ /* Additional "deep copy" for each kind of link */
+ switch(link_src->type) {
+ case H5G_LINK_HARD:
+ /* Copy the object pointed to */
+ {
+ H5O_loc_t src_oloc; /* Temporary object location for source object */
+ H5O_loc_t new_oloc; /* Temporary object location for source object */
+
+ /* Build temporary object location for source */
+ H5O_loc_reset(&src_oloc);
+ src_oloc.file = file_src;
+ HDassert(H5F_addr_defined(link_src->u.hard.addr));
+ src_oloc.addr = link_src->u.hard.addr;
+
+ /* Build temporary object location for destination */
+ H5O_loc_reset(&new_oloc);
+ new_oloc.file = dst_oloc->file;
+
+ /* Copy the shared object from source to destination */
+ /* (Increments link count on destination) */
+ if(H5O_copy_header_map(&src_oloc, &new_oloc, dxpl_id, map_list) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object")
+
+ /* Update link information with new destination object's address */
+ link_dst->u.hard.addr = new_oloc.addr;
+
+ /* Indicate that the destination message was modified */
+ *modified = TRUE;
+ } /* end case */
+ break;
+
+ case H5G_LINK_SOFT:
+ HGOTO_DONE(SUCCEED)
+ break;
+
+ default:
+ HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unrecognized link type")
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* H5O_link_post_copy_file() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_link_debug
+ *
+ * Purpose: Prints debugging info for a message.
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * koziol@ncsa.uiuc.edu
+ * Aug 29 2005
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_link_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg, FILE * stream,
+ int indent, int fwidth)
+{
+ const H5O_link_t *lnk = (const H5O_link_t *) _mesg;
+ struct tm *tm;
+ char buf[128];
+
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_link_debug)
+
+ /* check args */
+ HDassert(f);
+ HDassert(lnk);
+ HDassert(stream);
+ HDassert(indent >= 0);
+ 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")));
+
+ tm = HDlocaltime(&(lnk->ctime));
+ HDstrftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S %Z", tm);
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Creation Time:", buf);
+
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Link Name Character Set:", (lnk->cset == H5T_CSET_ASCII ?
+ "ASCII" : (lnk->cset == H5T_CSET_UTF8 ? "UTF-8" : "Unknown")));
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Link Name:", lnk->name);
+
+ switch(lnk->type) {
+ case H5G_LINK_HARD:
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Object address:", lnk->u.hard.addr);
+ break;
+
+ case H5G_LINK_SOFT:
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Link Value:", lnk->u.soft.name);
+ break;
+
+ default:
+ break;
+ } /* end switch */
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_link_debug() */
+
diff --git a/src/H5Omtime.c b/src/H5Omtime.c
index 4244733..d452ea2 100644
--- a/src/H5Omtime.c
+++ b/src/H5Omtime.c
@@ -32,11 +32,11 @@
#endif
-static void *H5O_mtime_new_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_mtime_new_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static herr_t H5O_mtime_new_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static size_t H5O_mtime_new_size(const H5F_t *f, const void *_mesg);
-static void *H5O_mtime_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_mtime_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static herr_t H5O_mtime_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_mtime_copy(const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_mtime_size(const H5F_t *f, const void *_mesg);
@@ -115,8 +115,7 @@ H5FL_DEFINE(time_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_mtime_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p,
- H5O_shared_t UNUSED *sh)
+H5O_mtime_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
time_t *mesg;
uint32_t tmp_time; /* Temporary copy of the time */
@@ -127,7 +126,6 @@ H5O_mtime_new_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p,
/* check args */
assert(f);
assert(p);
- assert (!sh);
/* decode */
if(*p++ != H5O_MTIME_VERSION)
@@ -171,8 +169,7 @@ done:
*-------------------------------------------------------------------------
*/
static void *
-H5O_mtime_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p,
- H5O_shared_t UNUSED *sh)
+H5O_mtime_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
time_t *mesg, the_time;
int i;
@@ -184,7 +181,6 @@ H5O_mtime_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p,
/* check args */
assert(f);
assert(p);
- assert (!sh);
/* Initialize time zone information */
if (!ntzset) {
diff --git a/src/H5Oname.c b/src/H5Oname.c
index ba4433a..d6f7e3e 100644
--- a/src/H5Oname.c
+++ b/src/H5Oname.c
@@ -34,7 +34,7 @@
/* PRIVATE PROTOTYPES */
-static void *H5O_name_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_name_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static herr_t H5O_name_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_name_copy(const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_name_size(const H5F_t *f, const void *_mesg);
@@ -82,8 +82,7 @@ const H5O_class_t H5O_NAME[1] = {{
*-------------------------------------------------------------------------
*/
static void *
-H5O_name_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p,
- H5O_shared_t UNUSED *sh)
+H5O_name_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
H5O_name_t *mesg;
void *ret_value; /* Return value */
@@ -93,7 +92,6 @@ H5O_name_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p,
/* check args */
assert(f);
assert(p);
- assert (!sh);
/* decode */
if (NULL==(mesg = H5MM_calloc(sizeof(H5O_name_t))) ||
diff --git a/src/H5Opkg.h b/src/H5Opkg.h
index fdca31a..874ea91 100644
--- a/src/H5Opkg.h
+++ b/src/H5Opkg.h
@@ -23,6 +23,7 @@
#include "H5Oprivate.h" /* Object headers */
/* Other private headers needed by this file */
+#include "H5ACprivate.h" /* Metadata cache */
#include "H5SLprivate.h" /* Skip lists */
/*
@@ -62,7 +63,7 @@ typedef struct H5O_class_t {
int id; /*message type ID on disk */
const char *name; /*for debugging */
size_t native_size; /*size of native message */
- void *(*decode)(H5F_t*, hid_t, const uint8_t*, struct H5O_shared_t*);
+ void *(*decode)(H5F_t*, hid_t, const uint8_t*);
herr_t (*encode)(H5F_t*, uint8_t*, const void*);
void *(*copy)(const void*, void*, unsigned); /*copy native value */
size_t (*raw_size)(const H5F_t*, const void*);/*sizeof raw val */
@@ -73,7 +74,7 @@ typedef struct H5O_class_t {
herr_t (*get_share)(H5F_t*, const void*, struct H5O_shared_t*); /* Get shared information */
herr_t (*set_share)(H5F_t*, void*, const struct H5O_shared_t*); /* Set shared information */
void *(*copy_file)(H5F_t *, void *, H5F_t *, hid_t, H5SL_t *, void *); /*copy native value to file */
- herr_t (*post_copy_file)(H5F_t *, const void *, H5G_entry_t *, hid_t, H5SL_t *); /*"post copy" action when copying native value to file */
+ herr_t (*post_copy_file)(H5F_t *, const void *, H5O_loc_t *, void *, hbool_t *, hid_t, H5SL_t *); /*"post copy" action when copying native value to file */
herr_t (*debug)(H5F_t*, hid_t, const void*, FILE*, int, int);
} H5O_class_t;
@@ -107,6 +108,24 @@ typedef struct H5O_t {
H5O_chunk_t *chunk; /*array of chunks */
} H5O_t;
+/* H5O inherits cache-like properties from H5AC */
+H5_DLLVAR const H5AC_class_t H5AC_OHDR[1];
+
+/* ID to type mapping */
+H5_DLLVAR const H5O_class_t *const message_type_g[19];
+
+/* Declare external the free list for H5O_t's */
+H5FL_EXTERN(H5O_t);
+
+/* Declare external the free list for H5O_mesg_t sequences */
+H5FL_SEQ_EXTERN(H5O_mesg_t);
+
+/* Declare external the free list for H5O_chunk_t sequences */
+H5FL_SEQ_EXTERN(H5O_chunk_t);
+
+/* Declare external the free list for chunk_image blocks */
+H5FL_BLK_EXTERN(chunk_image);
+
/*
* Null Message. (0x0000)
*/
@@ -118,6 +137,11 @@ H5_DLLVAR const H5O_class_t H5O_NULL[1];
H5_DLLVAR const H5O_class_t H5O_SDSPACE[1];
/*
+ * Link Information Message. (0x0002)
+ */
+H5_DLLVAR const H5O_class_t H5O_LINFO[1];
+
+/*
* Datatype Message. (0x0003)
*/
H5_DLLVAR const H5O_class_t H5O_DTYPE[1];
@@ -137,6 +161,12 @@ H5_DLLVAR const H5O_class_t H5O_FILL[1];
H5_DLLVAR const H5O_class_t H5O_FILL_NEW[1];
/*
+ * Link Message. (0x0006)
+ *
+ */
+H5_DLLVAR const H5O_class_t H5O_LINK[1];
+
+/*
* External File List Message. (0x0007)
*/
H5_DLLVAR const H5O_class_t H5O_EFL[1];
@@ -154,6 +184,11 @@ H5_DLLVAR const H5O_class_t H5O_BOGUS[1];
#endif /* H5O_ENABLE_BOGUS */
/*
+ * Group Information Message. (0x000a)
+ */
+H5_DLLVAR const H5O_class_t H5O_GINFO[1];
+
+/*
* Filter pipeline message. (0x000b)
*/
H5_DLLVAR const H5O_class_t H5O_PLINE[1];
@@ -203,16 +238,18 @@ H5_DLLVAR const H5O_class_t H5O_STAB[1];
H5_DLLVAR const H5O_class_t H5O_MTIME_NEW[1];
/* Package-local function prototypes */
-H5_DLL void * H5O_read_real(const H5G_entry_t *ent, const H5O_class_t *type,
- int sequence, void *mesg, hid_t dxpl_id);
+H5_DLL void * H5O_read_real(const H5O_loc_t *loc, const H5O_class_t *type,
+ int sequence, void *mesg, hid_t dxpl_id);
+H5_DLL herr_t H5O_free_mesg(H5O_mesg_t *mesg);
H5_DLL void * H5O_free_real(const H5O_class_t *type, void *mesg);
+H5_DLL herr_t H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, int indent, int fwidth);
/* Shared object operators */
H5_DLL void * H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared,
const H5O_class_t *type, void *mesg);
-/* Symbol table operators */
-H5_DLL void *H5O_stab_fast(const H5G_cache_t *cache, const struct H5O_class_t *type,
- void *_mesg);
+/* Useful metadata cache callbacks */
+H5_DLL herr_t H5O_dest(H5F_t *f, H5O_t *oh);
#endif /* _H5Opkg_H */
+
diff --git a/src/H5Opline.c b/src/H5Opline.c
index 391c758..d7fec7e 100644
--- a/src/H5Opline.c
+++ b/src/H5Opline.c
@@ -31,7 +31,7 @@
#define H5O_PLINE_VERSION 1
static herr_t H5O_pline_encode (H5F_t *f, uint8_t *p, const void *mesg);
-static void *H5O_pline_decode (H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_pline_decode (H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static void *H5O_pline_copy (const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_pline_size (const H5F_t *f, const void *_mesg);
static herr_t H5O_pline_reset (void *_mesg);
@@ -81,8 +81,7 @@ H5FL_DEFINE(H5O_pline_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_pline_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p,
- H5O_shared_t UNUSED *sh)
+H5O_pline_decode(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
H5O_pline_t *pline = NULL;
void *ret_value;
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index d619806..b9c7511 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -35,8 +35,7 @@
#include "H5Spublic.h" /* Dataspace functions */
/* Private headers needed by this file */
-#include "H5FLprivate.h" /* Free Lists */
-#include "H5HGprivate.h" /* Global heap functions */
+#include "H5Fprivate.h" /* File access */
#include "H5Tprivate.h" /* Datatype functions */
#include "H5Zprivate.h" /* I/O pipeline filters */
@@ -45,6 +44,7 @@
#define H5O_MAX_SIZE 65536 /*max obj header data size */
#define H5O_NEW_MESG (-1) /*new message */
#define H5O_ALL (-1) /* Operate on all messages of type */
+#define H5O_FIRST (-2) /* Operate on first message of type */
/* Flags which are part of a message */
#define H5O_FLAG_CONSTANT 0x01u
@@ -55,18 +55,24 @@
#define H5O_UPDATE_TIME 0x01u
#define H5O_UPDATE_DATA_ONLY 0x02u
+/* The object location information for an object */
+typedef struct H5O_loc_t {
+ H5F_t *file; /* File that object header is located within */
+ haddr_t addr; /* File address of object header */
+} H5O_loc_t;
+
/* Header message IDs */
#define H5O_NULL_ID 0x0000 /* Null Message. */
#define H5O_SDSPACE_ID 0x0001 /* Simple Dataspace Message. */
-/* Complex dataspace is/was planned for message 0x0002 */
+#define H5O_LINFO_ID 0x0002 /* Link Info Message. */
#define H5O_DTYPE_ID 0x0003 /* Datatype Message. */
#define H5O_FILL_ID 0x0004 /* Fill Value Message. (Old) */
#define H5O_FILL_NEW_ID 0x0005 /* Fill Value Message. (New) */
-/* Compact data storage is/was planned for message 0x0006 */
+#define H5O_LINK_ID 0x0006 /* Link Message. */
#define H5O_EFL_ID 0x0007 /* External File List Message */
#define H5O_LAYOUT_ID 0x0008 /* Data Storage Layout Message. */
#define H5O_BOGUS_ID 0x0009 /* "Bogus" Message. */
-/* message 0x000a appears unused... */
+#define H5O_GINFO_ID 0x000a /* Group Info Message. */
#define H5O_PLINE_ID 0x000b /* Filter pipeline message. */
#define H5O_ATTR_ID 0x000c /* Attribute Message. */
#define H5O_NAME_ID 0x000d /* Object name message. */
@@ -77,6 +83,14 @@
#define H5O_MTIME_NEW_ID 0x0012 /* Modification time message. (New) */
/*
+ * Link Info Message.
+ * (Data structure in memory)
+ */
+typedef struct H5O_linfo_t {
+ hsize_t nlinks; /* Number of links in the group */
+} H5O_linfo_t;
+
+/*
* Fill Value Message. (Old)
* (Data structure in memory)
*/
@@ -102,6 +116,29 @@ typedef struct H5O_fill_new_t {
} H5O_fill_new_t;
/*
+ * Link message.
+ * (Data structure in memory)
+ */
+typedef struct H5O_link_hard_t {
+ haddr_t addr; /* Object header address */
+} H5O_link_hard_t;
+
+typedef struct H5O_link_soft_t {
+ char *name; /* Destination name */
+} H5O_link_soft_t;
+
+typedef struct H5O_link_t {
+ H5G_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 */
+ union {
+ H5O_link_hard_t hard; /* Information for hard links */
+ H5O_link_soft_t soft; /* Information for soft links */
+ } u;
+} H5O_link_t;
+
+/*
* External File List Message
* (Data structure in memory)
*/
@@ -209,11 +246,7 @@ typedef struct H5O_name_t {
*/
typedef struct H5O_shared_t {
- hbool_t in_gh; /*shared by global heap? */
- union {
- H5HG_t gh; /*global heap info */
- H5G_entry_t ent; /*symbol table entry info */
- } u;
+ H5O_loc_t oloc; /*object location info */
} H5O_shared_t;
/*
@@ -250,38 +283,45 @@ typedef struct H5O_stab_t {
typedef herr_t (*H5O_operator_t)(const void *mesg/*in*/, unsigned idx,
void *operator_data/*in,out*/);
+/* Depth of object location copy */
+typedef enum {
+ H5O_COPY_SHALLOW, /* Copy from source to destination, just copy field pointers */
+ H5O_COPY_DEEP /* Deep copy from source to destination, including duplicating fields pointed to */
+} H5O_copy_depth_t;
+
/* Forward declarations for prototype arguments */
struct H5SL_t;
/* General message operators */
+H5_DLL herr_t H5O_init(void);
H5_DLL herr_t H5O_create(H5F_t *f, hid_t dxpl_id, size_t size_hint,
- H5G_entry_t *ent/*out*/);
-H5_DLL herr_t H5O_open(const H5G_entry_t *ent);
-H5_DLL herr_t H5O_close(H5G_entry_t *ent);
-H5_DLL int H5O_link(const H5G_entry_t *ent, int adjust, hid_t dxpl_id);
-H5_DLL int H5O_count(H5G_entry_t *ent, unsigned type_id, hid_t dxpl_id);
-H5_DLL htri_t H5O_exists(H5G_entry_t *ent, unsigned type_id, int sequence,
+ H5O_loc_t *loc/*out*/);
+H5_DLL herr_t H5O_open(const H5O_loc_t *loc);
+H5_DLL herr_t H5O_close(H5O_loc_t *loc);
+H5_DLL int H5O_link(const H5O_loc_t *loc, int adjust, hid_t dxpl_id);
+H5_DLL int H5O_count(H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id);
+H5_DLL htri_t H5O_exists(H5O_loc_t *loc, unsigned type_id, int sequence,
hid_t dxpl_id);
-H5_DLL void *H5O_read(const H5G_entry_t *ent, unsigned type_id, int sequence,
+H5_DLL void *H5O_read(const H5O_loc_t *loc, unsigned type_id, int sequence,
void *mesg, hid_t dxpl_id);
-H5_DLL int H5O_modify(H5G_entry_t *ent, unsigned type_id,
+H5_DLL int H5O_modify(H5O_loc_t *loc, unsigned type_id,
int overwrite, unsigned flags, unsigned update_flags, const void *mesg, hid_t dxpl_id);
-H5_DLL struct H5O_t * H5O_protect(H5G_entry_t *ent, hid_t dxpl_id);
-H5_DLL herr_t H5O_unprotect(H5G_entry_t *ent, struct H5O_t *oh, hid_t dxpl_id,
- unsigned oh_flags);
+H5_DLL struct H5O_t *H5O_protect(H5O_loc_t *loc, hid_t dxpl_id);
+H5_DLL herr_t H5O_unprotect(H5O_loc_t *loc, struct H5O_t *oh, hid_t dxpl_id,
+ unsigned oh_flags);
H5_DLL int H5O_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh, unsigned type_id,
unsigned flags, const void *mesg, unsigned * oh_flags_ptr);
-H5_DLL herr_t H5O_touch(H5G_entry_t *ent, hbool_t force, hid_t dxpl_id);
-H5_DLL herr_t H5O_touch_oh(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh,
- hbool_t force, unsigned * oh_flags_ptr);
+H5_DLL herr_t H5O_touch(H5O_loc_t *loc, hbool_t force, hid_t dxpl_id);
+H5_DLL herr_t H5O_touch_oh(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh,
+ hbool_t force, unsigned *oh_flags_ptr);
#ifdef H5O_ENABLE_BOGUS
-H5_DLL herr_t H5O_bogus(H5G_entry_t *ent, hid_t dxpl_id);
+H5_DLL herr_t H5O_bogus(H5O_loc_t *loc, hid_t dxpl_id);
H5_DLL herr_t H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh,
- unsigned * oh_flags_ptr);
+ unsigned * oh_flags_ptr);
#endif /* H5O_ENABLE_BOGUS */
-H5_DLL herr_t H5O_remove(H5G_entry_t *ent, unsigned type_id, int sequence,
+H5_DLL herr_t H5O_remove(H5O_loc_t *loc, unsigned type_id, int sequence,
hbool_t adj_link, hid_t dxpl_id);
-H5_DLL herr_t H5O_remove_op(H5G_entry_t *ent, unsigned type_id,
+H5_DLL herr_t H5O_remove_op(const H5O_loc_t *loc, unsigned type_id, int sequence,
H5O_operator_t op, void *op_data, hbool_t adj_link, hid_t dxpl_id);
H5_DLL herr_t H5O_reset(unsigned type_id, void *native);
H5_DLL void *H5O_free(unsigned type_id, void *mesg);
@@ -292,17 +332,24 @@ H5_DLL size_t H5O_raw_size(unsigned type_id, const H5F_t *f, const void *mesg);
H5_DLL size_t H5O_mesg_size(unsigned type_id, const H5F_t *f, const void *mesg);
H5_DLL herr_t H5O_get_share(unsigned type_id, H5F_t *f, const void *mesg, H5O_shared_t *share);
H5_DLL herr_t H5O_delete(H5F_t *f, hid_t dxpl_id, haddr_t addr);
-H5_DLL herr_t H5O_get_info(H5G_entry_t *ent, H5O_stat_t *ostat, hid_t dxpl_id);
-H5_DLL herr_t H5O_iterate(const H5G_entry_t *ent, unsigned type_id, H5O_operator_t op,
+H5_DLL herr_t H5O_get_info(H5O_loc_t *loc, H5O_stat_t *ostat, hid_t dxpl_id);
+H5_DLL herr_t H5O_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t op,
void *op_data, hid_t dxpl_id);
-H5_DLL herr_t H5O_copy_header(const H5G_entry_t *ent_src,
- H5G_entry_t *ent_dst /*out */, hid_t dxpl_id);
-H5_DLL herr_t H5O_copy_header_map(const H5G_entry_t *ent_src,
- H5G_entry_t *ent_dst /*out */, hid_t dxpl_id, struct H5SL_t *obj_list);
+H5_DLL H5G_obj_t H5O_obj_type(H5O_loc_t *loc, hid_t dxpl_id);
+H5_DLL herr_t H5O_copy_header(const H5O_loc_t *oloc_src,
+ H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id);
+H5_DLL herr_t H5O_copy_header_map(const H5O_loc_t *oloc_src,
+ H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, struct H5SL_t *map_list);
H5_DLL herr_t H5O_debug_id(hid_t type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth);
H5_DLL herr_t H5O_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE * stream, int indent,
int fwidth);
+/*
+ * These functions operate on object locations
+ */
+H5_DLL herr_t H5O_loc_reset(H5O_loc_t *loc);
+H5_DLL herr_t H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5O_copy_depth_t depth);
+
/* Layout operators */
H5_DLL size_t H5O_layout_meta_size(const H5F_t *f, const void *_mesg);
diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c
index f4c5500..e09f029 100644
--- a/src/H5Osdspace.c
+++ b/src/H5Osdspace.c
@@ -25,7 +25,7 @@
/* PRIVATE PROTOTYPES */
-static void *H5O_sdspace_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_sdspace_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static herr_t H5O_sdspace_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_sdspace_copy(const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_sdspace_size(const H5F_t *f, const void *_mesg);
@@ -99,7 +99,7 @@ H5FL_ARR_EXTERN(hsize_t);
--------------------------------------------------------------------------*/
static void *
-H5O_sdspace_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *sh)
+H5O_sdspace_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
H5S_extent_t *sdim = NULL;/* New extent dimensionality structure */
void *ret_value;
@@ -111,7 +111,6 @@ H5O_sdspace_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_
/* check args */
assert(f);
assert(p);
- assert (!sh);
/* decode */
if ((sdim = H5FL_CALLOC(H5S_extent_t)) != NULL) {
@@ -147,8 +146,15 @@ H5O_sdspace_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_
if (sdim->rank > 0) {
if (NULL==(sdim->size=H5FL_ARR_MALLOC(hsize_t,sdim->rank)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- for (i = 0; i < sdim->rank; i++)
+ for (i = 0; i < sdim->rank; i++) {
H5F_DECODE_LENGTH (f, p, sdim->size[i]);
+#ifndef H5_HAVE_LARGE_HSIZET
+ /* Rudimentary check for overflow of the dimension size */
+ if(sdim->size[i] == 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_BADSIZE, NULL, "invalid size detected");
+#endif /* H5_HAVE_LARGE_HSIZET */
+ } /* end for */
+
if (flags & H5S_VALID_MAX) {
if (NULL==(sdim->max=H5FL_ARR_MALLOC(hsize_t,sdim->rank)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
@@ -463,3 +469,4 @@ H5O_sdspace_debug(H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *mesg,
FUNC_LEAVE_NOAPI(SUCCEED);
}
+
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index 09f273d..de58460 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -36,7 +36,7 @@
#include "H5MMprivate.h" /* Memory management */
#include "H5Opkg.h" /* Object headers */
-static void *H5O_shared_decode (H5F_t*, hid_t dxpl_id, const uint8_t*, H5O_shared_t *sh);
+static void *H5O_shared_decode (H5F_t*, hid_t dxpl_id, const uint8_t*);
static herr_t H5O_shared_encode (H5F_t*, uint8_t*, const void*);
static void *H5O_shared_copy(const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_shared_size (const H5F_t*, const void *_mesg);
@@ -99,39 +99,19 @@ H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared, const H5O_class_t
{
void *ret_value = NULL; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_shared_read);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_shared_read)
/* check args */
- assert(f);
- assert(shared);
- assert(type);
-
- /* Get the shared message */
- if (shared->in_gh) {
- void *tmp_buf, *tmp_mesg;
-
- if (NULL==(tmp_buf = H5HG_read (f, dxpl_id, &(shared->u.gh), NULL)))
- HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL, "unable to read shared message from global heap");
- tmp_mesg = (type->decode)(f, dxpl_id, tmp_buf, shared);
- tmp_buf = H5MM_xfree (tmp_buf);
- if (!tmp_mesg)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL, "unable to decode object header shared message");
- if (mesg) {
- HDmemcpy (mesg, tmp_mesg, type->native_size);
- H5MM_xfree (tmp_mesg);
- } /* end if */
- else
- ret_value = tmp_mesg;
- } /* end if */
- else {
- ret_value = H5O_read_real(&(shared->u.ent), type, 0, mesg, dxpl_id);
- if (type->set_share &&
- (type->set_share)(f, ret_value, shared)<0)
- HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information");
- } /* end else */
+ HDassert(f);
+ HDassert(shared);
+ HDassert(type);
+
+ ret_value = H5O_read_real(&(shared->oloc), type, 0, mesg, dxpl_id);
+ if(type->set_share && (type->set_share)(f, ret_value, shared) < 0)
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL, "unable to set sharing information")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_shared_read() */
@@ -158,35 +138,25 @@ H5O_shared_link_adj(H5F_t *f, hid_t dxpl_id, const H5O_shared_t *shared, int adj
{
int ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_shared_link_adj);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_shared_link_adj)
/* check args */
- assert(f);
- assert(shared);
-
- if (shared->in_gh) {
- /*
- * The shared message is stored in the global heap.
- * Adjust the reference count on the global heap message.
- */
- if ((ret_value = H5HG_link (f, dxpl_id, &(shared->u.gh), adjust))<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
- } /* end if */
- else {
- /*
- * The shared message is stored in some other object header.
- * The other object header must be in the same file as the
- * new object header. Adjust the reference count on that
- * object header.
- */
- if (shared->u.ent.file->shared != f->shared)
- HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed");
- if ((ret_value = H5O_link (&(shared->u.ent), adjust, dxpl_id))<0)
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count");
- } /* end else */
+ HDassert(f);
+ HDassert(shared);
+
+ /*
+ * The shared message is stored in some other object header.
+ * The other object header must be in the same file as the
+ * new object header. Adjust the reference count on that
+ * object header.
+ */
+ if(shared->oloc.file->shared != f->shared)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "interfile hard links are not allowed")
+ if((ret_value = H5O_link(&(shared->oloc), adjust, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_OHDR, H5E_LINK, FAIL, "unable to adjust shared object link count")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5O_shared_link_adj() */
@@ -208,53 +178,45 @@ done:
*-------------------------------------------------------------------------
*/
static void *
-H5O_shared_decode (H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *buf, H5O_shared_t UNUSED *sh)
+H5O_shared_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *buf)
{
- H5O_shared_t *mesg=NULL;
+ H5O_shared_t *mesg = NULL;
unsigned flags, version;
void *ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5O_shared_decode);
+ FUNC_ENTER_NOAPI_NOINIT(H5O_shared_decode)
/* Check args */
- assert (f);
- assert (buf);
- assert (!sh);
+ HDassert(f);
+ HDassert(buf);
/* Decode */
- if (NULL==(mesg = H5MM_calloc (sizeof(H5O_shared_t))))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ if(NULL == (mesg = H5MM_calloc (sizeof(H5O_shared_t))))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
/* Version */
version = *buf++;
- if (version!=H5O_SHARED_VERSION_1 && version!=H5O_SHARED_VERSION)
- HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for shared object message");
+ if(version != H5O_SHARED_VERSION_1 && version != H5O_SHARED_VERSION)
+ HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, NULL, "bad version number for shared object message")
/* Get the shared information flags */
- flags = *buf++;
- mesg->in_gh = (flags & 0x01);
+ flags = *buf++; /* Unused currently */
/* Skip reserved bytes (for version 1) */
- if(version==H5O_SHARED_VERSION_1)
+ if(version == H5O_SHARED_VERSION_1)
buf += 6;
/* Body */
- if (mesg->in_gh) {
- H5F_addr_decode (f, &buf, &(mesg->u.gh.addr));
- INT32DECODE (buf, mesg->u.gh.idx);
- } /* end if */
+ if(version == H5O_SHARED_VERSION_1)
+ H5G_obj_ent_decode(f, &buf, &(mesg->oloc));
else {
- if(version==H5O_SHARED_VERSION_1)
- H5G_ent_decode (f, &buf, &(mesg->u.ent));
- else {
- assert(version==H5O_SHARED_VERSION);
- H5F_addr_decode (f, &buf, &(mesg->u.ent.header));
- mesg->u.ent.file=f;
- } /* end else */
+ HDassert(version == H5O_SHARED_VERSION);
+ H5F_addr_decode(f, &buf, &(mesg->oloc.addr));
+ mesg->oloc.file = f;
} /* end else */
/* Set return value */
- ret_value=mesg;
+ ret_value = mesg;
done:
if(ret_value==NULL) {
@@ -262,8 +224,8 @@ done:
H5MM_xfree(mesg);
} /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5O_shared_decode() */
/*-------------------------------------------------------------------------
@@ -286,44 +248,21 @@ static herr_t
H5O_shared_encode (H5F_t *f, uint8_t *buf/*out*/, const void *_mesg)
{
const H5O_shared_t *mesg = (const H5O_shared_t *)_mesg;
- unsigned flags;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_shared_encode);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_shared_encode)
/* Check args */
- assert (f);
- assert (buf);
- assert (mesg);
+ HDassert(f);
+ HDassert(buf);
+ HDassert(mesg);
/* Encode */
*buf++ = H5O_SHARED_VERSION;
- flags = mesg->in_gh ? 0x01 : 0x00;
- *buf++ = flags;
-#ifdef OLD_WAY
- *buf++ = 0; /*reserved 1*/
- *buf++ = 0; /*reserved 2*/
- *buf++ = 0; /*reserved 3*/
- *buf++ = 0; /*reserved 4*/
- *buf++ = 0; /*reserved 5*/
- *buf++ = 0; /*reserved 6*/
-
- if (mesg->in_gh) {
- H5F_addr_encode (f, &buf, mesg->u.gh.addr);
- INT32ENCODE (buf, mesg->u.gh.idx);
- } /* end if */
- else
- H5G_ent_encode (f, &buf, &(mesg->u.ent));
-#else /* OLD_WAY */
- if (mesg->in_gh) {
- H5F_addr_encode (f, &buf, mesg->u.gh.addr);
- INT32ENCODE (buf, mesg->u.gh.idx);
- } /* end if */
- else
- H5F_addr_encode (f, &buf, mesg->u.ent.header);
-#endif /* OLD_WAY */
+ *buf++ = 0; /* No flags currently */
+ H5F_addr_encode(f, &buf, mesg->oloc.addr);
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_shared_encode() */
/*-------------------------------------------------------------------------
@@ -395,9 +334,7 @@ H5O_shared_size (const H5F_t *f, const void *_mesg)
ret_value = 1 + /*version */
1 + /*the flags field */
- (shared->in_gh ?
- (H5F_SIZEOF_ADDR(f)+4) : /*sharing via global heap */
- H5F_SIZEOF_ADDR(f)); /*sharing by another obj hdr */
+ H5F_SIZEOF_ADDR(f); /*sharing by another obj hdr */
FUNC_LEAVE_NOAPI(ret_value);
}
@@ -508,16 +445,12 @@ H5O_shared_copy_file(H5F_t UNUSED *file_src, void *native_src,
if(NULL == (shared_dst = H5MM_malloc(sizeof(H5O_shared_t))))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- /* Can't handle copying message in global heap currently */
- HDassert(!shared_src->in_gh);
- shared_dst->in_gh = FALSE;
-
/* Reset group entry for new object */
- H5G_ent_reset(&(shared_dst->u.ent));
- shared_dst->u.ent.file = file_dst;
+ H5O_loc_reset(&(shared_dst->oloc));
+ shared_dst->oloc.file = file_dst;
/* Copy the shared object from source to destination */
- if(H5O_copy_header_map(&(shared_src->u.ent), &(shared_dst->u.ent), dxpl_id, map_list) < 0)
+ if(H5O_copy_header_map(&(shared_src->oloc), &(shared_dst->oloc), dxpl_id, map_list) < 0)
HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, NULL, "unable to copy object")
/* Set return value */
@@ -547,37 +480,27 @@ done:
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_shared_debug (H5F_t UNUSED *f, hid_t dxpl_id, const void *_mesg,
+H5O_shared_debug (H5F_t UNUSED *f, hid_t UNUSED dxpl_id, const void *_mesg,
FILE *stream, int indent, int fwidth)
{
const H5O_shared_t *mesg = (const H5O_shared_t *)_mesg;
- FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_shared_debug);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_shared_debug)
/* Check args */
- assert (f);
- assert (mesg);
- assert (stream);
- assert (indent>=0);
- assert (fwidth>=0);
-
- if (mesg->in_gh) {
- HDfprintf (stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Sharing method",
- "Global heap");
- HDfprintf (stream, "%*s%-*s %a\n", indent, "", fwidth,
- "Collection address:",
- mesg->u.gh.addr);
- HDfprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
- "Object ID within collection:",
- mesg->u.gh.idx);
- } else {
- HDfprintf (stream, "%*s%-*s %s\n", indent, "", fwidth,
- "Sharing method",
- "Obj Hdr");
- H5G_ent_debug (f, dxpl_id, &(mesg->u.ent), stream, indent, fwidth,
- HADDR_UNDEF);
- }
-
- FUNC_LEAVE_NOAPI(SUCCEED);
-}
+ HDassert(f);
+ HDassert(mesg);
+ HDassert(stream);
+ HDassert(indent >= 0);
+ HDassert(fwidth >= 0);
+
+ HDfprintf(stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Sharing method",
+ "Obj Hdr");
+ HDfprintf(stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Object address:",
+ mesg->oloc.addr);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5O_shared_debug() */
+
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
index e03d6b1..b74fd8c 100644
--- a/src/H5Ostab.c
+++ b/src/H5Ostab.c
@@ -32,11 +32,12 @@
#include "H5Eprivate.h" /* Error handling */
#include "H5FLprivate.h" /* Free lists */
#include "H5Gpkg.h" /* Groups */
+#include "H5HLprivate.h" /* Local Heaps */
#include "H5Opkg.h" /* Object headers */
/* PRIVATE PROTOTYPES */
-static void *H5O_stab_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p, H5O_shared_t *sh);
+static void *H5O_stab_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p);
static herr_t H5O_stab_encode(H5F_t *f, uint8_t *p, const void *_mesg);
static void *H5O_stab_copy(const void *_mesg, void *_dest, unsigned update_flags);
static size_t H5O_stab_size(const H5F_t *f, const void *_mesg);
@@ -45,7 +46,7 @@ static herr_t H5O_stab_delete(H5F_t *f, hid_t dxpl_id, const void *_mesg, hbool_
static void *H5O_stab_copy_file(H5F_t *file_src, void *native_src,
H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata);
static herr_t H5O_stab_post_copy_file(H5F_t *file_src, const void *mesg_src,
- H5G_entry_t *loc_dst, hid_t dxpl_id, H5SL_t *map_list);
+ H5O_loc_t *dst_oloc, void *mesg_dst, hbool_t *modified, hid_t dxpl_id, H5SL_t *map_list);
static herr_t H5O_stab_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg,
FILE * stream, int indent, int fwidth);
@@ -92,7 +93,7 @@ H5FL_DEFINE_STATIC(H5O_stab_t);
*-------------------------------------------------------------------------
*/
static void *
-H5O_stab_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_t UNUSED *sh)
+H5O_stab_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p)
{
H5O_stab_t *stab=NULL;
void *ret_value; /* Return value */
@@ -102,7 +103,6 @@ H5O_stab_decode(H5F_t *f, hid_t UNUSED dxpl_id, const uint8_t *p, H5O_shared_t U
/* check args */
assert(f);
assert(p);
- assert(!sh);
/* decode */
if (NULL==(stab = H5FL_CALLOC(H5O_stab_t)))
@@ -159,53 +159,6 @@ H5O_stab_encode(H5F_t *f, uint8_t *p, const void *_mesg)
/*-------------------------------------------------------------------------
- * Function: H5O_stab_fast
- *
- * Purpose: Initializes a new message struct with info from the cache of
- * a symbol table entry.
- *
- * Return: Success: Ptr to message struct, allocated if none
- * supplied.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * matzke@llnl.gov
- * Aug 6 1997
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-void *
-H5O_stab_fast(const H5G_cache_t *cache, const H5O_class_t *type, void *_mesg)
-{
- H5O_stab_t *ret_value; /* Return value */
-
- FUNC_ENTER_NOAPI_NOINIT(H5O_stab_fast);
-
- /* check args */
- assert(cache);
- assert(type);
-
- if (H5O_STAB == type) {
- if (_mesg) {
- ret_value = (H5O_stab_t *) _mesg;
- } else if (NULL==(ret_value = H5FL_MALLOC(H5O_stab_t))) {
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
- }
- ret_value->btree_addr = cache->stab.btree_addr;
- ret_value->heap_addr = cache->stab.heap_addr;
- }
- else
- ret_value=NULL;
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5O_stab_copy
*
* Purpose: Copies a message from _MESG to _DEST, allocating _DEST if
@@ -357,12 +310,13 @@ done:
*-------------------------------------------------------------------------
*/
static void *
-H5O_stab_copy_file(H5F_t UNUSED *file_src, void *native_src,
+H5O_stab_copy_file(H5F_t *file_src, void *native_src,
H5F_t *file_dst, hid_t dxpl_id, H5SL_t UNUSED *map_list, void UNUSED *udata)
{
- H5O_stab_t *stab_src = (H5O_stab_t *) native_src;
- H5O_stab_t *stab_dst = NULL;
- void *ret_value; /* Return value */
+ H5O_stab_t *stab_src = (H5O_stab_t *) native_src;
+ H5O_stab_t *stab_dst = NULL;
+ size_t size_hint; /* Local heap initial size */
+ void *ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_stab_copy_file)
@@ -374,8 +328,13 @@ H5O_stab_copy_file(H5F_t UNUSED *file_src, void *native_src,
if(NULL == (stab_dst = H5FL_MALLOC(H5O_stab_t)))
HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- if(H5G_stab_copy_tmp(file_dst, stab_dst, dxpl_id) < 0)
- HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to copy group symbol table")
+ /* Get the old local heap's size and use that as the hint for the new heap */
+ if(H5HL_get_size(file_src, dxpl_id, stab_src->heap_addr, &size_hint) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTGETSIZE, NULL, "can't query local heap size")
+
+ /* Create components of symbol table message */
+ if(H5G_stab_create_components(file_dst, stab_dst, size_hint, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, NULL, "can't create symbol table components")
/* Set return value */
ret_value = stab_dst;
@@ -392,7 +351,7 @@ done:
/*-------------------------------------------------------------------------
* Function: H5O_stab_post_copy_file
*
- * Purpose: Copies entries of a symbol table message from _MESG to _DEST in file
+ * Purpose: Finish copying a message from between files
*
* Return: Non-negative on success/Negative on failure
*
@@ -403,10 +362,11 @@ done:
*/
static herr_t
H5O_stab_post_copy_file(H5F_t *file_src, const void *mesg_src,
- H5G_entry_t *loc_dst, hid_t dxpl_id, H5SL_t *map_list)
+ H5O_loc_t *dst_oloc, void *mesg_dst, hbool_t UNUSED *modified, hid_t dxpl_id, H5SL_t *map_list)
{
- H5G_bt_it_ud5_t udata; /* B-tree user data */
- const H5O_stab_t *stab_src = (const H5O_stab_t *) mesg_src;
+ H5G_bt_it_ud5_t udata; /* B-tree user data */
+ const H5O_stab_t *stab_src = (const H5O_stab_t *)mesg_src;
+ H5O_stab_t *stab_dst = (H5O_stab_t *)mesg_dst;
herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_NOAPI_NOINIT(H5O_stab_post_copy_file)
@@ -414,13 +374,16 @@ H5O_stab_post_copy_file(H5F_t *file_src, const void *mesg_src,
/* check args */
HDassert(file_src);
HDassert(stab_src);
- HDassert(loc_dst->file);
+ HDassert(H5F_addr_defined(dst_oloc->addr));
+ HDassert(dst_oloc->file);
+ HDassert(stab_dst);
HDassert(map_list);
/* Set up B-tree iteration user data */
udata.map_list = map_list;
- udata.heap_addr = stab_src->heap_addr;
- udata.loc_dst = loc_dst;
+ udata.src_heap_addr = stab_src->heap_addr;
+ udata.dst_file = dst_oloc->file;
+ udata.dst_stab = stab_dst;
/* Iterate over objects in group, copying them */
if((H5B_iterate(file_src, dxpl_id, H5B_SNODE, H5G_node_copy, stab_src->btree_addr, &udata)) < 0)
diff --git a/src/H5P.c b/src/H5P.c
index 637ab59..7ac272f 100644
--- a/src/H5P.c
+++ b/src/H5P.c
@@ -225,8 +225,18 @@ static herr_t
H5P_init_interface(void)
{
H5P_genclass_t *root_class; /* Pointer to root property list class created */
- H5P_genclass_t *ocrt_class; /* Pointer to object (dataset, group, or datatype) creation property list class created */
H5P_genclass_t *pclass; /* Pointer to property list class to create */
+ /* Group creation property class variables. In sequence, they are,
+ * - Creation property list class to modify
+ * - Default value for "group info"
+ */
+ H5P_genclass_t *gcrt_class; /* Pointer to group creation property list class created */
+ 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;
size_t nprops; /* Number of properties */
herr_t ret_value = SUCCEED;
@@ -276,11 +286,48 @@ H5P_init_interface(void)
HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
} /* end if */
+ /* Register the group creation and group access property classes */
+ /* (Register the group property classes before file property classes, so
+ * file creation property class can inherit from group creation property
+ * class, which is used to allow application to control the group creation
+ * properties of the root group of a file. -QAK)
+ */
+
+ /* Allocate the group creation class */
+ HDassert(H5P_CLS_GROUP_CREATE_g == (-1));
+ if(NULL == (gcrt_class = H5P_create_class(ocrt_class, "group create", 1, NULL, NULL, NULL, NULL, NULL, NULL)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
+
+ /* Register the group creation class */
+ if((H5P_CLS_GROUP_CREATE_g = H5I_register(H5I_GENPROP_CLS, gcrt_class)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class");
+
+ /* Get the number of properties in the class */
+ if(H5P_get_nprops_pclass(gcrt_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 group info */
+ if(H5P_register(gcrt_class, H5G_CRT_GROUP_INFO_NAME, H5G_CRT_GROUP_INFO_SIZE,
+ &ginfo, 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 group access class */
+ HDassert(H5P_CLS_GROUP_ACCESS_g == (-1));
+ if(NULL == (pclass = H5P_create_class(root_class, "group access", 1, NULL, NULL, NULL, NULL, NULL, NULL)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
+
+ /* Register the group access class */
+ if((H5P_CLS_GROUP_ACCESS_g = H5I_register(H5I_GENPROP_CLS, pclass)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class");
+
/* Register the file creation and file access property classes */
/* Allocate the file creation class */
assert(H5P_CLS_FILE_CREATE_g==(-1));
- if (NULL==(pclass = H5P_create_class (root_class,"file create",1,NULL,NULL,NULL,NULL,NULL,NULL)))
+ if (NULL==(pclass = H5P_create_class (gcrt_class,"file create",1,NULL,NULL,NULL,NULL,NULL,NULL)))
HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
/* Register the file creation class */
@@ -325,6 +372,8 @@ H5P_init_interface(void)
if ((H5P_CLS_DATASET_XFER_g = H5I_register (H5I_GENPROP_CLS, pclass))<0)
HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class");
+ /* Register the mount property classes */
+
/* Allocate the mount class */
assert(H5P_CLS_MOUNT_g==(-1));
if (NULL==(pclass = H5P_create_class (root_class,"file mount",1,NULL,NULL,NULL,NULL,NULL,NULL)))
@@ -334,24 +383,7 @@ H5P_init_interface(void)
if ((H5P_CLS_MOUNT_g = H5I_register (H5I_GENPROP_CLS, pclass))<0)
HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class");
-
- /* Allocate the group creation class */
- assert(H5P_CLS_GROUP_CREATE_g==(-1));
- if (NULL==(pclass = H5P_create_class (ocrt_class,"group create",1,NULL,NULL,NULL,NULL,NULL,NULL)))
- HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
-
- /* Register the group creation class */
- if ((H5P_CLS_GROUP_CREATE_g = H5I_register (H5I_GENPROP_CLS, pclass))<0)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class");
-
- /* Allocate the group access class */
- assert(H5P_CLS_GROUP_ACCESS_g==(-1));
- if (NULL==(pclass = H5P_create_class (root_class,"group access",1,NULL,NULL,NULL,NULL,NULL,NULL)))
- HGOTO_ERROR (H5E_PLIST, H5E_CANTINIT, FAIL, "class initialization failed");
-
- /* Register the group access class */
- if ((H5P_CLS_GROUP_ACCESS_g = H5I_register (H5I_GENPROP_CLS, pclass))<0)
- HGOTO_ERROR (H5E_PLIST, H5E_CANTREGISTER, FAIL, "can't register property list class");
+ /* Register the named datatype creation and named datatype access property classes */
/* Allocate the datatype creation class */
assert(H5P_CLS_DATATYPE_CREATE_g==(-1));
diff --git a/src/H5Pgcpl.c b/src/H5Pgcpl.c
index 8b22015..388d453 100644
--- a/src/H5Pgcpl.c
+++ b/src/H5Pgcpl.c
@@ -30,6 +30,8 @@
*
* Purpose: Set the "size hint" for creating local heaps for a group.
*
+ * Note: XXX: Add [meaningful] tests for this routine! -QAK
+ *
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
@@ -71,6 +73,8 @@ done:
* Purpose: Returns the local heap size hint, which is used for creating
* groups
*
+ * Note: XXX: Add [meaningful] tests for this routine! -QAK
+ *
* Return: Non-negative on success/Negative on failure
*
* Programmer: Quincey Koziol
@@ -104,3 +108,193 @@ done:
FUNC_LEAVE_API(ret_value)
} /* end H5Pget_local_heap_size_hint() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_link_phase_change
+ *
+ * Purpose: Set the maximum # of links to store "compactly" and the
+ * minimum # of links to store "densely". (These should
+ * overlap).
+ *
+ * Note: Currently both of these must be updated at the same time.
+ *
+ * Note: XXX: Add [meaningful] tests for this routine! -QAK
+ *
+ * Note: Come up with better name & description! -QAK
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * August 29, 2005
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_link_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_ginfo_t ginfo; /* Group information structure */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pset_link_phase_change, FAIL)
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_GROUP_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get group info */
+ if(H5P_get(plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info")
+
+ /* Update fields */
+ ginfo.max_compact = max_compact;
+ ginfo.min_dense = min_dense;
+
+ /* Set group info */
+ if(H5P_set(plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set group info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_link_phase_change() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_link_phase_change
+ *
+ * Purpose: Returns the max. # of compact links & the min. # of dense
+ * links, which are used for storing groups
+ *
+ * Note: XXX: Add [meaningful] tests for this routine! -QAK
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * August 29, 2005
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_link_phase_change(hid_t plist_id, unsigned *max_compact /*out*/, unsigned *min_dense /*out*/)
+{
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(H5Pget_link_phase_change, FAIL)
+
+ /* Get values */
+ if(max_compact || min_dense) {
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_ginfo_t ginfo; /* Group information structure */
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_GROUP_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get group info */
+ if(H5P_get(plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info")
+
+ if(max_compact)
+ *max_compact = ginfo.max_compact;
+ if(min_dense)
+ *min_dense = ginfo.min_dense;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_link_phase_change() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pset_est_link_info
+ *
+ * Purpose: Set the estimates for the number of entries and length of each
+ * entry name in a group.
+ *
+ * Note: Currently both of these must be updated at the same time.
+ *
+ * Note: EST_NUM_ENTRIES applies only when the number of entries than
+ * the MAX_COMPACT # of entries (from H5Pset_link_phase_change).
+ *
+ * Note: XXX: Add [meaningful] tests for this routine! -QAK
+ *
+ * Note: Come up with better name & description? -QAK
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * September 6, 2005
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pset_est_link_info(hid_t plist_id, unsigned est_num_entries, unsigned est_name_len)
+{
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_ginfo_t ginfo; /* Group information structure */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_API(H5Pset_est_link_info, FAIL)
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_GROUP_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get group info */
+ if(H5P_get(plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info")
+
+ /* Update fields */
+ ginfo.est_num_entries = est_num_entries;
+ ginfo.est_name_len = est_name_len;
+
+ /* Set group info */
+ if(H5P_set(plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set group info")
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pset_est_link_info() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Pget_est_link_info
+ *
+ * Purpose: Returns the est. # of links in a group & the est. length of
+ * the name of each link.
+ *
+ * Note: XXX: Add [meaningful] tests for this routine! -QAK
+ *
+ * Return: Non-negative on success/Negative on failure
+ *
+ * Programmer: Quincey Koziol
+ * September 6, 2005
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Pget_est_link_info(hid_t plist_id, unsigned *est_num_entries /*out*/, unsigned *est_name_len /*out*/)
+{
+ herr_t ret_value = SUCCEED; /* return value */
+
+ FUNC_ENTER_API(H5Pget_est_link_info, FAIL)
+
+ /* Get values */
+ if(est_num_entries || est_name_len) {
+ H5P_genplist_t *plist; /* Property list pointer */
+ H5O_ginfo_t ginfo; /* Group information structure */
+
+ /* Get the plist structure */
+ if(NULL == (plist = H5P_object_verify(plist_id, H5P_GROUP_CREATE)))
+ HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
+
+ /* Get group info */
+ if(H5P_get(plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get group info")
+
+ if(est_num_entries)
+ *est_num_entries = ginfo.est_num_entries;
+ if(est_name_len)
+ *est_name_len = ginfo.est_name_len;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Pget_est_link_info() */
+
diff --git a/src/H5Pocpl.c b/src/H5Pocpl.c
index 7132a93..8277ddc 100755
--- a/src/H5Pocpl.c
+++ b/src/H5Pocpl.c
@@ -31,6 +31,8 @@
* Purpose: set crt_intmd_group so that H5Gcreate(), H5Dcreate, 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
diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h
index 8d5e015..a470dfd 100644
--- a/src/H5Ppublic.h
+++ b/src/H5Ppublic.h
@@ -334,6 +334,10 @@ H5_DLL herr_t H5Pget_create_intermediate_group(hid_t plist_id, unsigned *crt_int
H5_DLL herr_t H5Pset_local_heap_size_hint(hid_t plist_id, size_t size_hint);
H5_DLL herr_t H5Pget_local_heap_size_hint(hid_t plist_id, size_t *size_hint /*out*/);
+H5_DLL herr_t H5Pset_link_phase_change(hid_t plist_id, unsigned max_compact, unsigned min_dense);
+H5_DLL herr_t H5Pget_link_phase_change(hid_t plist_id, unsigned *max_compact /*out*/, unsigned *min_dense /*out*/);
+H5_DLL herr_t H5Pset_est_link_info(hid_t plist_id, unsigned est_num_entries, unsigned est_name_len);
+H5_DLL herr_t H5Pget_est_link_info(hid_t plist_id, unsigned *est_num_entries /* out */, unsigned *est_name_len /* out */);
#ifdef __cplusplus
}
diff --git a/src/H5R.c b/src/H5R.c
index fce6c7a..fa5b97d 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -12,29 +12,30 @@
* access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-#define H5F_PACKAGE /*suppress error about including H5Fpkg */
-
/* Interface initialization */
#define H5_INTERFACE_INIT_FUNC H5R_init_interface
-#include "H5private.h" /* Generic Functions */
-#include "H5Iprivate.h" /* ID Functions */
-#include "H5Dprivate.h" /* Datasets */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5Fpkg.h" /* Files */
-#include "H5Gprivate.h" /* Groups */
-#include "H5HGprivate.h" /* Global Heaps */
-#include "H5MMprivate.h" /* Memory Management */
-#include "H5Rprivate.h" /* References */
-#include "H5Sprivate.h" /* Dataspace functions */
-#include "H5Tprivate.h" /* Datatypes */
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Fprivate.h" /* File access */
+#include "H5Gprivate.h" /* Groups */
+#include "H5HGprivate.h" /* Global Heaps */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Rprivate.h" /* References */
+#include "H5Sprivate.h" /* Dataspaces */
+
+/* Local macro definitions */
+
+/* Number of reserved IDs in ID group */
+#define H5R_RESERVED_ATOMS 0
/* Static functions */
-static herr_t H5R_create(void *ref, H5G_entry_t *loc, const char *name,
+static herr_t H5R_create(void *ref, H5G_loc_t *loc, const char *name,
H5R_type_t ref_type, H5S_t *space, hid_t dxpl_id);
static hid_t H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref);
-static H5S_t * H5R_get_region(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref);
+static H5S_t * H5R_get_region(H5F_t *file, hid_t dxpl_id, void *_ref);
static H5G_obj_t H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref);
@@ -60,7 +61,7 @@ H5R_init_interface(void)
/* Initialize the atom group for the file IDs */
if (H5I_register_type(H5I_REFERENCE, H5I_REFID_HASHSIZE, H5R_RESERVED_ATOMS,
(H5I_free_t)NULL)<0)
- HGOTO_ERROR (H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to initialize interface");
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to initialize interface");
done:
FUNC_LEAVE_NOAPI(ret_value);
@@ -113,7 +114,7 @@ H5R_term_interface(void)
USAGE
herr_t H5R_create(ref, loc, name, ref_type, space)
void *ref; OUT: Reference created
- H5G_entry_t *loc; IN: File location used to locate object pointed to
+ H5G_loc_t *loc; IN: File location used to locate object pointed to
const char *name; IN: Name of object at location LOC_ID of object
pointed to
H5R_type_t ref_type; IN: Type of reference to create
@@ -133,25 +134,25 @@ H5R_term_interface(void)
REVISION LOG
--------------------------------------------------------------------------*/
static herr_t
-H5R_create(void *_ref, H5G_entry_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space, hid_t dxpl_id)
+H5R_create(void *_ref, H5G_loc_t *loc, const char *name, H5R_type_t ref_type, H5S_t *space, hid_t dxpl_id)
{
- H5G_stat_t sb; /* Stat buffer for retrieving OID */
- herr_t ret_value=SUCCEED; /* Return value */
+ H5G_stat_t sb; /* Stat buffer for retrieving OID */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5R_create);
+ FUNC_ENTER_NOAPI_NOINIT(H5R_create)
- assert(_ref);
- assert(loc);
- assert(name);
- assert(ref_type>H5R_BADTYPE || ref_type<H5R_MAXTYPE);
+ HDassert(_ref);
+ HDassert(loc);
+ HDassert(name);
+ HDassert(ref_type > H5R_BADTYPE || ref_type < H5R_MAXTYPE);
- if (H5G_get_objinfo (loc, name, 0, &sb, dxpl_id)<0)
- HGOTO_ERROR (H5E_REFERENCE, H5E_NOTFOUND, FAIL, "unable to stat object");
+ if(H5G_get_objinfo(loc, name, 0, &sb, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_NOTFOUND, FAIL, "unable to stat object")
switch(ref_type) {
case H5R_OBJECT:
{
- hobj_ref_t *ref=(hobj_ref_t *)_ref; /* Get pointer to correct type of reference struct */
+ hobj_ref_t *ref = (hobj_ref_t *)_ref; /* Get pointer to correct type of reference struct */
*ref=sb.u.obj.objno;
break;
@@ -160,7 +161,7 @@ H5R_create(void *_ref, H5G_entry_t *loc, const char *name, H5R_type_t ref_type,
case H5R_DATASET_REGION:
{
H5HG_t hobjid; /* Heap object ID */
- hdset_reg_ref_t *ref=(hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
+ hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
hssize_t buf_size; /* Size of buffer needed to serialize selection */
uint8_t *p; /* Pointer to OID to store */
uint8_t *buf; /* Buffer to store serialized selection in */
@@ -170,51 +171,51 @@ H5R_create(void *_ref, H5G_entry_t *loc, const char *name, H5R_type_t ref_type,
/* Set up information for dataset region */
/* Return any previous heap block to the free list if we are garbage collecting */
- if(loc->file->shared->gc_ref) {
+ if(H5F_GC_REF(loc->oloc->file)) {
/* Check for an existing heap ID in the reference */
- for(u=0, heapid_found=0, p=(uint8_t *)ref; u<H5R_DSET_REG_REF_BUF_SIZE; u++)
- if(p[u]!=0) {
- heapid_found=1;
+ for(u = 0, heapid_found = 0, p = (uint8_t *)ref; u < H5R_DSET_REG_REF_BUF_SIZE; u++)
+ if(p[u] != 0) {
+ heapid_found = 1;
break;
} /* end if */
- if(heapid_found!=0) {
+ if(heapid_found != 0) {
/* Return heap block to free list */
} /* end if */
} /* end if */
/* Zero the heap ID out, may leak heap space if user is re-using reference and doesn't have garbage collection on */
- HDmemset(ref,H5R_DSET_REG_REF_BUF_SIZE,0);
+ HDmemset(ref, H5R_DSET_REG_REF_BUF_SIZE, 0);
/* Get the amount of space required to serialize the selection */
- if ((buf_size = H5S_SELECT_SERIAL_SIZE(space)) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection");
+ if((buf_size = H5S_SELECT_SERIAL_SIZE(space)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "Invalid amount of space for serializing selection")
/* Increase buffer size to allow for the dataset OID */
- buf_size+=sizeof(haddr_t);
+ buf_size += sizeof(haddr_t);
/* Allocate the space to store the serialized information */
- H5_CHECK_OVERFLOW(buf_size,hssize_t,size_t);
- if (NULL==(buf = H5MM_malloc((size_t)buf_size)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");
+ H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t);
+ if(NULL == (buf = H5MM_malloc((size_t)buf_size)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed")
/* Serialize information for dataset OID */
- p=(uint8_t *)buf;
- H5F_addr_encode(loc->file,&p,sb.u.obj.objno);
+ p = (uint8_t *)buf;
+ H5F_addr_encode(loc->oloc->file, &p, sb.u.obj.objno);
/* Serialize the selection */
- if (H5S_SELECT_SERIALIZE(space,p) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection");
+ if(H5S_SELECT_SERIALIZE(space, p) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCOPY, FAIL, "Unable to serialize selection")
/* Save the serialized buffer for later */
- H5_CHECK_OVERFLOW(buf_size,hssize_t,size_t);
- if(H5HG_insert(loc->file,dxpl_id,(size_t)buf_size,buf,&hobjid)<0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, "Unable to serialize selection");
+ H5_CHECK_OVERFLOW(buf_size, hssize_t, size_t);
+ if(H5HG_insert(loc->oloc->file, dxpl_id, (size_t)buf_size, buf, &hobjid) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_WRITEERROR, FAIL, "Unable to serialize selection")
/* Serialize the heap ID and index for storage in the file */
- p=(uint8_t *)ref;
- H5F_addr_encode(loc->file,&p,hobjid.addr);
- INT32ENCODE(p,hobjid.idx);
+ p = (uint8_t *)ref;
+ H5F_addr_encode(loc->oloc->file, &p, hobjid.addr);
+ INT32ENCODE(p, hobjid.idx);
/* Free the buffer we serialized data in */
H5MM_xfree(buf);
@@ -222,17 +223,17 @@ H5R_create(void *_ref, H5G_entry_t *loc, const char *name, H5R_type_t ref_type,
}
case H5R_INTERNAL:
- HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "Internal references are not yet supported");
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "Internal references are not yet supported")
case H5R_BADTYPE:
case H5R_MAXTYPE:
default:
assert("unknown reference type" && 0);
- HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)");
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
} /* end switch */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5R_create() */
@@ -266,33 +267,33 @@ done:
herr_t
H5Rcreate(void *ref, hid_t loc_id, const char *name, H5R_type_t ref_type, hid_t space_id)
{
- H5G_entry_t *loc = NULL; /* File location */
+ H5G_loc_t loc; /* File location */
H5S_t *space = NULL; /* Pointer to dataspace containing region */
- herr_t ret_value; /* Return value */
+ herr_t ret_value; /* Return value */
- FUNC_ENTER_API(H5Rcreate, FAIL);
+ FUNC_ENTER_API(H5Rcreate, FAIL)
H5TRACE5("e","xisRti",ref,loc_id,name,ref_type,space_id);
/* Check args */
- if(ref==NULL)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer");
- if (NULL==(loc=H5G_loc (loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if (!name || !*name)
- HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name given");
- if(ref_type<=H5R_BADTYPE || ref_type>=H5R_MAXTYPE)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type");
- if(ref_type!=H5R_OBJECT && ref_type!=H5R_DATASET_REGION)
- HGOTO_ERROR (H5E_ARGS, H5E_UNSUPPORTED, FAIL, "reference type not supported");
- if (space_id!=(-1) && (NULL==(space=H5I_object_verify(space_id,H5I_DATASPACE))))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace");
+ if(ref == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer")
+ 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")
+ if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type")
+ if(ref_type != H5R_OBJECT && ref_type != H5R_DATASET_REGION)
+ HGOTO_ERROR(H5E_ARGS, H5E_UNSUPPORTED, FAIL, "reference type not supported")
+ if(space_id != (-1) && (NULL == (space = H5I_object_verify(space_id, H5I_DATASPACE))))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataspace")
/* Create reference */
- if ((ret_value=H5R_create(ref,loc,name,ref_type,space, H5AC_dxpl_id))<0)
- HGOTO_ERROR (H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to create reference");
+ if((ret_value = H5R_create(ref, &loc, name, ref_type, space, H5AC_dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable to create reference")
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Rcreate() */
@@ -321,52 +322,50 @@ done:
static hid_t
H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref)
{
- H5D_t *dset; /* Pointer to dataset to open */
- H5T_t *type; /* Pointer to datatype to open */
- H5G_t *group; /* Pointer to group to open */
- H5G_entry_t ent; /* Symbol table entry */
+ H5O_loc_t oloc; /* Object location */
+ H5G_name_t path; /* Path of object */
+ H5G_loc_t loc; /* Group location */
uint8_t *p; /* Pointer to OID to store */
int oid_type; /* type of object being dereferenced */
hid_t ret_value;
- FUNC_ENTER_NOAPI_NOINIT(H5R_dereference);
+ FUNC_ENTER_NOAPI_NOINIT(H5R_dereference)
- assert(_ref);
- assert(ref_type>H5R_BADTYPE || ref_type<H5R_MAXTYPE);
- assert(file);
+ HDassert(_ref);
+ HDassert(ref_type > H5R_BADTYPE || ref_type < H5R_MAXTYPE);
+ HDassert(file);
- /* Initialize the symbol table entry */
- H5G_ent_reset(&ent);
- ent.type=H5G_NOTHING_CACHED;
- ent.file=file;
+ /* Initialize the object location */
+ H5O_loc_reset(&oloc);
+ oloc.file = file;
switch(ref_type) {
case H5R_OBJECT:
{
- hobj_ref_t *ref=(hobj_ref_t *)_ref; /* Only object references currently supported */
+ hobj_ref_t *ref = (hobj_ref_t *)_ref; /* Only object references currently supported */
- ent.header=*ref;
+ oloc.addr = *ref;
} /* end case */
break;
case H5R_DATASET_REGION:
{
- hdset_reg_ref_t *ref=(hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
+ hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
H5HG_t hobjid; /* Heap object ID */
uint8_t *buf; /* Buffer to store serialized selection in */
/* Get the heap ID for the dataset region */
- p=(uint8_t *)ref;
- H5F_addr_decode(ent.file,(const uint8_t **)&p,&(hobjid.addr));
- INT32DECODE(p,hobjid.idx);
+ p = (uint8_t *)ref;
+ H5F_addr_decode(oloc.file, (const uint8_t **)&p, &(hobjid.addr));
+ INT32DECODE(p, hobjid.idx);
/* Get the dataset region from the heap (allocate inside routine) */
- if((buf=H5HG_read(ent.file,dxpl_id,&hobjid,NULL))==NULL)
- HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information");
+ if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL)) == NULL)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, FAIL, "Unable to read dataset region information")
/* Get the object oid for the dataset */
- p=(uint8_t *)buf;
- H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header));
+ p = (uint8_t *)buf;
+ H5F_addr_decode(oloc.file, (const uint8_t **)&p, &(oloc.addr));
/* Free the buffer allocated in H5HG_read() */
H5MM_xfree(buf);
@@ -374,62 +373,79 @@ H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref)
break;
case H5R_INTERNAL:
- HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "Internal references are not yet supported");
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "Internal references are not yet supported")
case H5R_BADTYPE:
case H5R_MAXTYPE:
default:
- assert("unknown reference type" && 0);
- HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)");
+ HDassert("unknown reference type" && 0);
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, FAIL, "internal error (unknown reference type)")
} /* end switch */
/* Check to make certain that this object hasn't been deleted since the reference was created */
- if(H5O_link(&ent,0,dxpl_id)<=0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object");
+ if(H5O_link(&oloc, 0, dxpl_id) <= 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, FAIL, "dereferencing deleted object")
+
+ /* Construct a group location for opening the object */
+ H5G_name_reset(&path);
+ loc.oloc = &oloc;
+ loc.path = &path;
/* Open the object */
- oid_type=H5G_get_type(&ent,dxpl_id);
+ oid_type = H5O_obj_type(&oloc, dxpl_id);
switch(oid_type) {
case H5G_GROUP:
- if ((group=H5G_open(&ent,dxpl_id)) == NULL)
- HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found");
-
- /* Create an atom for the group */
- if ((ret_value = H5I_register(H5I_GROUP, group)) < 0) {
- H5G_close(group);
- HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, FAIL, "can't register group");
- }
+ {
+ H5G_t *group; /* Pointer to group to open */
+
+ if((group = H5G_open(&loc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "not found")
+
+ /* Create an atom for the group */
+ if((ret_value = H5I_register(H5I_GROUP, group)) < 0) {
+ H5G_close(group);
+ HGOTO_ERROR(H5E_SYM, H5E_CANTREGISTER, FAIL, "can't register group")
+ } /* end if */
+ } /* end case */
break;
case H5G_TYPE:
- if ((type=H5T_open(&ent, dxpl_id)) == NULL)
- HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found");
-
- /* Create an atom for the datatype */
- if ((ret_value = H5I_register(H5I_DATATYPE, type)) < 0) {
- H5T_close(type);
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "can't register datatype");
- }
+ {
+ H5T_t *type; /* Pointer to datatype to open */
+
+ if((type = H5T_open(&loc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found")
+
+ /* Create an atom for the datatype */
+ if((ret_value = H5I_register(H5I_DATATYPE, type)) < 0) {
+ H5T_close(type);
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "can't register datatype")
+ } /* end if */
+ } /* end case */
break;
case H5G_DATASET:
- /* Open the dataset */
- if ((dset=H5D_open(&ent,dxpl_id))==NULL)
- HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found");
-
- /* Create an atom for the dataset */
- if ((ret_value = H5I_register(H5I_DATASET, dset)) < 0) {
- H5D_close(dset);
- HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register dataset");
- }
+ {
+ H5D_t *dset; /* Pointer to dataset to open */
+
+ /* Open the dataset */
+ if((dset = H5D_open(&loc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found")
+
+ /* Create an atom for the dataset */
+ if((ret_value = H5I_register(H5I_DATASET, dset)) < 0) {
+ H5D_close(dset);
+ HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL, "can't register dataset")
+ } /* end if */
+ } /* end case */
break;
default:
- HGOTO_ERROR(H5E_REFERENCE, H5E_BADTYPE, FAIL, "can't identify type of object referenced");
+ HGOTO_ERROR(H5E_REFERENCE, H5E_BADTYPE, FAIL, "can't identify type of object referenced")
} /* end switch */
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5R_dereference() */
@@ -458,30 +474,30 @@ done:
hid_t
H5Rdereference(hid_t id, H5R_type_t ref_type, void *_ref)
{
- H5G_entry_t *loc = NULL; /* Symbol table entry */
- H5F_t *file=NULL; /* File object */
+ H5G_loc_t loc; /* Group location */
+ H5F_t *file = NULL; /* File object */
hid_t ret_value;
- FUNC_ENTER_API(H5Rdereference, FAIL);
+ FUNC_ENTER_API(H5Rdereference, FAIL)
H5TRACE3("i","iRtx",id,ref_type,_ref);
/* Check args */
- if (NULL == (loc = H5G_loc(id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if(ref_type<=H5R_BADTYPE || ref_type>=H5R_MAXTYPE)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type");
- if(_ref==NULL)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer");
+ if(H5G_loc(id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type")
+ if(_ref == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer")
/* Get the file pointer from the entry */
- file=loc->file;
+ file = loc.oloc->file;
/* Create reference */
- if ((ret_value=H5R_dereference(file, H5AC_dxpl_id, ref_type, _ref))<0)
- HGOTO_ERROR (H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable dereference object");
+ if((ret_value = H5R_dereference(file, H5AC_dxpl_id, ref_type, _ref)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, FAIL, "unable dereference object")
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Rdereference() */
@@ -493,7 +509,6 @@ done:
USAGE
H5S_t *H5R_get_region(file, ref_type, ref)
H5F_t *file; IN: File the object being dereferenced is within
- H5R_type_t ref_type; UNUSED
void *ref; IN: Reference to open.
RETURNS
@@ -508,52 +523,50 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
static H5S_t *
-H5R_get_region(H5F_t *file, hid_t dxpl_id, H5R_type_t UNUSED ref_type, void *_ref)
+H5R_get_region(H5F_t *file, hid_t dxpl_id, void *_ref)
{
- H5G_entry_t ent; /* Symbol table entry */
+ H5O_loc_t oloc; /* Object location */
uint8_t *p; /* Pointer to OID to store */
- hdset_reg_ref_t *ref=(hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
+ hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
H5HG_t hobjid; /* Heap object ID */
uint8_t *buf; /* Buffer to store serialized selection in */
H5S_t *ret_value;
- FUNC_ENTER_NOAPI_NOINIT(H5R_get_region);
+ FUNC_ENTER_NOAPI_NOINIT(H5R_get_region)
- assert(_ref);
- assert(ref_type==H5R_DATASET_REGION);
- assert(file);
+ HDassert(_ref);
+ HDassert(file);
- /* Initialize the symbol table entry */
- H5G_ent_reset(&ent);
- ent.type=H5G_NOTHING_CACHED;
- ent.file=file;
+ /* Initialize the object location */
+ H5O_loc_reset(&oloc);
+ oloc.file = file;
/* Get the heap ID for the dataset region */
- p=(uint8_t *)ref;
- H5F_addr_decode(ent.file,(const uint8_t **)&p,&(hobjid.addr));
+ p = (uint8_t *)ref;
+ H5F_addr_decode(oloc.file, (const uint8_t **)&p, &(hobjid.addr));
INT32DECODE(p,hobjid.idx);
/* Get the dataset region from the heap (allocate inside routine) */
- if((buf=H5HG_read(ent.file,dxpl_id,&hobjid,NULL))==NULL)
- HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, NULL, "Unable to read dataset region information");
+ if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL)) == NULL)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, NULL, "Unable to read dataset region information")
/* Get the object oid for the dataset */
- p=(uint8_t *)buf;
- H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header));
+ p = (uint8_t *)buf;
+ H5F_addr_decode(oloc.file, (const uint8_t **)&p, &(oloc.addr));
/* Open and copy the dataset's dataspace */
- if ((ret_value=H5S_read(&ent, dxpl_id)) == NULL)
- HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found");
+ if((ret_value = H5S_read(&oloc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_NOTFOUND, NULL, "not found")
/* Unserialize the selection */
- if (H5S_select_deserialize(ret_value,p) < 0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection");
+ if(H5S_select_deserialize(ret_value, p) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTDECODE, NULL, "can't deserialize selection")
/* Free the buffer allocated in H5HG_read() */
H5MM_xfree(buf);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5R_get_region() */
@@ -581,37 +594,33 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
hid_t
-H5Rget_region(hid_t id, H5R_type_t ref_type, void *_ref)
+H5Rget_region(hid_t id, H5R_type_t ref_type, void *ref)
{
- H5G_entry_t *loc = NULL; /* Symbol table entry */
- H5S_t *space = NULL; /* dataspace object */
- H5F_t *file=NULL; /* File object */
+ H5G_loc_t loc; /* Object's group location */
+ H5S_t *space = NULL; /* Dataspace object */
hid_t ret_value;
- FUNC_ENTER_API(H5Rget_region, FAIL);
- H5TRACE3("i","iRtx",id,ref_type,_ref);
+ FUNC_ENTER_API(H5Rget_region, FAIL)
+ H5TRACE3("i","iRtx",id,ref_type,ref);
/* Check args */
- if (NULL == (loc = H5G_loc(id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if(ref_type!=H5R_DATASET_REGION)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type");
- if(_ref==NULL)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer");
-
- /* Get the file pointer from the entry */
- file=loc->file;
+ if(H5G_loc(id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(ref_type != H5R_DATASET_REGION)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference type")
+ if(ref == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid reference pointer")
/* Get the dataspace with the correct region selected */
- if ((space=H5R_get_region(file,H5AC_ind_dxpl_id,ref_type,_ref))==NULL)
- HGOTO_ERROR (H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create dataspace");
+ if((space = H5R_get_region(loc.oloc->file, H5AC_ind_dxpl_id, ref)) == NULL)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTCREATE, FAIL, "unable to create dataspace")
/* Atomize */
- if ((ret_value=H5I_register (H5I_DATASPACE, space))<0)
- HGOTO_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom");
+ if((ret_value = H5I_register (H5I_DATASPACE, space)) < 0)
+ HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Rget_region() */
@@ -640,48 +649,47 @@ done:
static H5G_obj_t
H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref)
{
- H5G_entry_t ent; /* Symbol table entry */
+ H5O_loc_t oloc; /* Object location */
uint8_t *p; /* Pointer to OID to store */
H5G_obj_t ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5R_get_obj_type);
+ FUNC_ENTER_NOAPI_NOINIT(H5R_get_obj_type)
- assert(file);
- assert(_ref);
+ HDassert(file);
+ HDassert(_ref);
/* Initialize the symbol table entry */
- H5G_ent_reset(&ent);
- ent.type=H5G_NOTHING_CACHED;
- ent.file=file;
+ H5O_loc_reset(&oloc);
+ oloc.file = file;
switch(ref_type) {
case H5R_OBJECT:
{
- hobj_ref_t *ref=(hobj_ref_t *)_ref; /* Only object references currently supported */
+ hobj_ref_t *ref = (hobj_ref_t *)_ref; /* Only object references currently supported */
/* Get the object oid */
- ent.header=*ref;
+ oloc.addr = *ref;
} /* end case */
break;
case H5R_DATASET_REGION:
{
- hdset_reg_ref_t *ref=(hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
+ hdset_reg_ref_t *ref = (hdset_reg_ref_t *)_ref; /* Get pointer to correct type of reference struct */
H5HG_t hobjid; /* Heap object ID */
uint8_t *buf; /* Buffer to store serialized selection in */
/* Get the heap ID for the dataset region */
- p=(uint8_t *)ref;
- H5F_addr_decode(ent.file,(const uint8_t **)&p,&(hobjid.addr));
- INT32DECODE(p,hobjid.idx);
+ p = (uint8_t *)ref;
+ H5F_addr_decode(oloc.file, (const uint8_t **)&p, &(hobjid.addr));
+ INT32DECODE(p, hobjid.idx);
/* Get the dataset region from the heap (allocate inside routine) */
- if((buf=H5HG_read(ent.file,dxpl_id,&hobjid,NULL))==NULL)
- HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, H5G_UNKNOWN, "Unable to read dataset region information");
+ if((buf = H5HG_read(oloc.file, dxpl_id, &hobjid, NULL)) == NULL)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_READERROR, H5G_UNKNOWN, "Unable to read dataset region information")
/* Get the object oid for the dataset */
- p=(uint8_t *)buf;
- H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header));
+ p = (uint8_t *)buf;
+ H5F_addr_decode(oloc.file, (const uint8_t **)&p, &(oloc.addr));
/* Free the buffer allocated in H5HG_read() */
H5MM_xfree(buf);
@@ -689,24 +697,24 @@ H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref)
break;
case H5R_INTERNAL:
- HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5G_UNKNOWN, "Internal references are not yet supported");
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5G_UNKNOWN, "Internal references are not yet supported")
case H5R_BADTYPE:
case H5R_MAXTYPE:
default:
- assert("unknown reference type" && 0);
- HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5G_UNKNOWN, "internal error (unknown reference type)");
+ HDassert("unknown reference type" && 0);
+ HGOTO_ERROR(H5E_REFERENCE, H5E_UNSUPPORTED, H5G_UNKNOWN, "internal error (unknown reference type)")
} /* end switch */
/* Check to make certain that this object hasn't been deleted since the reference was created */
- if(H5O_link(&ent,0,dxpl_id)<=0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, H5G_UNKNOWN, "dereferencing deleted object");
+ if(H5O_link(&oloc, 0, dxpl_id) <= 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_LINKCOUNT, H5G_UNKNOWN, "dereferencing deleted object")
/* Get the OID type */
- ret_value=H5G_get_type(&ent,dxpl_id);
+ ret_value = H5O_obj_type(&oloc,dxpl_id);
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5R_get_obj_type() */
@@ -734,31 +742,27 @@ done:
REVISION LOG
--------------------------------------------------------------------------*/
H5G_obj_t
-H5Rget_obj_type(hid_t id, H5R_type_t ref_type, void *_ref)
+H5Rget_obj_type(hid_t id, H5R_type_t ref_type, void *ref)
{
- H5G_entry_t *loc = NULL; /* Symbol table entry */
- H5F_t *file=NULL; /* File object */
+ H5G_loc_t loc; /* Object location */
H5G_obj_t ret_value;
- FUNC_ENTER_API(H5Rget_obj_type, H5G_UNKNOWN);
- H5TRACE3("Go","iRtx",id,ref_type,_ref);
+ FUNC_ENTER_API(H5Rget_obj_type, H5G_UNKNOWN)
+ H5TRACE3("Go","iRtx",id,ref_type,ref);
/* Check args */
- if (NULL == (loc = H5G_loc(id)))
- HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a location");
- if(ref_type<=H5R_BADTYPE || ref_type>=H5R_MAXTYPE)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference type");
- if(_ref==NULL)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference pointer");
-
- /* Get the file pointer from the entry */
- file=loc->file;
+ if(H5G_loc(id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, H5G_UNKNOWN, "not a location")
+ if(ref_type <= H5R_BADTYPE || ref_type >= H5R_MAXTYPE)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference type")
+ if(ref == NULL)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, H5G_UNKNOWN, "invalid reference pointer")
/* Get the object information */
- if ((ret_value=H5R_get_obj_type(file,H5AC_ind_dxpl_id,ref_type,_ref))<0)
- HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type");
+ if((ret_value = H5R_get_obj_type(loc.oloc->file, H5AC_ind_dxpl_id, ref_type, ref)) < 0)
+ HGOTO_ERROR(H5E_REFERENCE, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type")
done:
- FUNC_LEAVE_API(ret_value);
+ FUNC_LEAVE_API(ret_value)
} /* end H5Rget_obj_type() */
diff --git a/src/H5RS.c b/src/H5RS.c
index 7d5bbfe..469ef4e 100644
--- a/src/H5RS.c
+++ b/src/H5RS.c
@@ -62,17 +62,17 @@ H5RS_xstrdup(const char *s)
{
char *ret_value; /* Return value */
- FUNC_ENTER_NOAPI_NOINIT(H5RS_xstrdup);
+ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5RS_xstrdup)
- if (s) {
- ret_value = H5FL_BLK_MALLOC(str_buf,HDstrlen(s) + 1);
- assert (ret_value);
+ if(s) {
+ ret_value = H5FL_BLK_MALLOC(str_buf, HDstrlen(s) + 1);
+ HDassert(ret_value);
HDstrcpy(ret_value, s);
} /* end if */
else
- ret_value=NULL;
+ ret_value = NULL;
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5RS_xstrdup() */
@@ -160,7 +160,7 @@ done:
NAME
H5RS_own
PURPOSE
- Transfer ownership of a regular string to a reference counted string
+ Transfer ownership of a regular string to a reference counted string
USAGE
H5RS_str_t *H5RS_own(s)
const char *s; IN: String to transfer ownership of
@@ -286,7 +286,7 @@ H5RS_incr(H5RS_str_t *rs)
PURPOSE
"Duplicate" a ref-counted string
USAGE
- H5RS_str_t H5RS_incr(rs)
+ H5RS_str_t H5RS_dup(rs)
H5RS_str_t *rs; IN/OUT: Ref-counted string to "duplicate"
RETURNS
@@ -315,6 +315,54 @@ H5RS_dup(H5RS_str_t *ret_value)
/*--------------------------------------------------------------------------
NAME
+ H5RS_dup
+ PURPOSE
+ "Duplicate" a regular string into a ref-counted string
+ USAGE
+ H5RS_str_t H5RS_dup_str(s)
+ const char *s; IN: Regular string to duplicate
+
+ RETURNS
+ Returns a pointer to ref-counted string on success, NULL on failure.
+ DESCRIPTION
+ Duplicate a regular string into a ref-counted string.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+H5RS_str_t *
+H5RS_dup_str(const char *s)
+{
+ char *new_str = NULL; /* Duplicate of string */
+ size_t path_len; /* Length of the path */
+ H5RS_str_t *ret_value;
+
+ FUNC_ENTER_NOAPI(H5RS_dup_str, FAIL)
+
+ /* Sanity check */
+ HDassert(s);
+
+ /* Get the length of the string */
+ path_len = HDstrlen(s);
+
+ /* Allocate space for the string */
+ if(NULL == (new_str = H5FL_BLK_MALLOC(str_buf, path_len + 1)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
+
+ /* Copy name for full path */
+ HDstrcpy(new_str, s);
+
+ /* Create reference counted string for path */
+ ret_value = H5RS_own(new_str);
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5RS_dup_str() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
H5RS_cmp
PURPOSE
Compare two ref-counted strings
diff --git a/src/H5RSprivate.h b/src/H5RSprivate.h
index a154d01..1ddbac7 100644
--- a/src/H5RSprivate.h
+++ b/src/H5RSprivate.h
@@ -50,6 +50,7 @@ H5_DLL H5RS_str_t *H5RS_own(char *s);
H5_DLL herr_t H5RS_decr(H5RS_str_t *rs);
H5_DLL herr_t H5RS_incr(H5RS_str_t *rs);
H5_DLL H5RS_str_t *H5RS_dup(H5RS_str_t *s);
+H5_DLL H5RS_str_t *H5RS_dup_str(const char *s);
H5_DLL int H5RS_cmp(const H5RS_str_t *rs1, const H5RS_str_t *rs2);
H5_DLL ssize_t H5RS_len(const H5RS_str_t *rs);
H5_DLL char *H5RS_get_str(const H5RS_str_t *rs);
diff --git a/src/H5Rprivate.h b/src/H5Rprivate.h
index 0e1fdb2..0f23992 100644
--- a/src/H5Rprivate.h
+++ b/src/H5Rprivate.h
@@ -13,7 +13,7 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
- * This file contains private information about the H5S module
+ * This file contains private information about the H5R module
*/
#ifndef _H5Rprivate_H
#define _H5Rprivate_H
@@ -21,13 +21,10 @@
#include "H5Rpublic.h"
/* Private headers needed by this file */
-#include "H5private.h"
-
-#define H5R_RESERVED_ATOMS 0
/* Internal data structures */
-
/* Private functions */
#endif /* _H5Rprivate_H */
+
diff --git a/src/H5S.c b/src/H5S.c
index 4190ca4..bc58fb8 100644
--- a/src/H5S.c
+++ b/src/H5S.c
@@ -30,6 +30,11 @@
#include "H5Spkg.h" /* Dataspaces */
/* Local macro definitions */
+
+/* Number of reserved IDs in ID group */
+#define H5S_RESERVED_ATOMS 2
+
+/* Version of datatype encoding */
#define H5S_ENCODE_VERSION 0
/* Local static function prototypes */
@@ -1042,39 +1047,37 @@ done:
* Programmer: Robb Matzke
* Tuesday, December 9, 1997
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
-H5S_modify(H5G_entry_t *ent, const H5S_t *ds, hbool_t update_time, hid_t dxpl_id)
+H5S_modify(H5O_loc_t *loc, const H5S_t *ds, hbool_t update_time, hid_t dxpl_id)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5S_modify, FAIL);
+ FUNC_ENTER_NOAPI(H5S_modify, FAIL)
- assert(ent);
- assert(ds);
+ HDassert(loc);
+ HDassert(ds);
- switch (H5S_GET_EXTENT_TYPE(ds)) {
+ switch(H5S_GET_EXTENT_TYPE(ds)) {
case H5S_NULL:
case H5S_SCALAR:
case H5S_SIMPLE:
- if (H5O_modify(ent, H5O_SDSPACE_ID, 0, 0, update_time, &(ds->extent), dxpl_id)<0)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update simple data space message");
+ if(H5O_modify(loc, H5O_SDSPACE_ID, 0, 0, update_time, &(ds->extent), dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, FAIL, "can't update simple dataspace message")
break;
case H5S_COMPLEX:
- HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "complex data spaces are not implemented yet");
+ HGOTO_ERROR(H5E_DATASPACE, H5E_UNSUPPORTED, FAIL, "complex dataspaces are not implemented yet")
default:
- assert("unknown data space class" && 0);
+ HDassert("unknown dataspace class" && 0);
break;
- }
+ } /* end switch */
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_modify() */
/*-------------------------------------------------------------------------
@@ -1143,44 +1146,40 @@ done:
* Programmer: Robb Matzke
* Tuesday, December 9, 1997
*
- * Modifications:
- * Robb Matzke, 9 Jun 1998
- * Removed the unused file argument since the file is now part of the
- * ENT argument.
*-------------------------------------------------------------------------
*/
H5S_t *
-H5S_read(const H5G_entry_t *ent, hid_t dxpl_id)
+H5S_read(const H5O_loc_t *loc, hid_t dxpl_id)
{
- H5S_t *ds = NULL; /* Dataspace to return */
- H5S_t *ret_value; /* Return value */
+ H5S_t *ds = NULL; /* Dataspace to return */
+ H5S_t *ret_value; /* Return value */
- FUNC_ENTER_NOAPI(H5S_read, NULL);
+ FUNC_ENTER_NOAPI(H5S_read, NULL)
/* check args */
- assert(ent);
+ HDassert(loc);
- if (NULL==(ds = H5FL_CALLOC(H5S_t)))
- HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed");
+ if(NULL == (ds = H5FL_CALLOC(H5S_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- if (H5O_read(ent, H5O_SDSPACE_ID, 0, &(ds->extent), dxpl_id) == NULL)
- HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to load dataspace info from dataset header");
+ if(H5O_read(loc, H5O_SDSPACE_ID, 0, &(ds->extent), dxpl_id) == NULL)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTINIT, NULL, "unable to load dataspace info from dataset header")
/* Default to entire dataspace being selected */
- if(H5S_select_all(ds,0)<0)
- HGOTO_ERROR (H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection");
+ if(H5S_select_all(ds, 0) < 0)
+ HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, NULL, "unable to set all selection")
/* Set the value for successful return */
- ret_value=ds;
+ ret_value = ds;
done:
- if(ret_value==NULL) {
- if(ds!=NULL)
- H5FL_FREE(H5S_t,ds);
+ if(ret_value == NULL) {
+ if(ds != NULL)
+ H5FL_FREE(H5S_t, ds);
} /* end if */
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5S_read() */
/*--------------------------------------------------------------------------
diff --git a/src/H5SL.c b/src/H5SL.c
index 0491aa4..610870f 100644
--- a/src/H5SL.c
+++ b/src/H5SL.c
@@ -466,6 +466,7 @@ H5SL_release_common(H5SL_t *slist, H5SL_operator_t op, void *op_data)
/* Call callback, if one is given */
if(op!=NULL)
+ /* Casting away const OK -QAK */
(void)(op)(node->item,(void *)node->key,op_data);
H5FL_ARR_FREE(H5SL_node_ptr_t,node);
diff --git a/src/H5Spkg.h b/src/H5Spkg.h
index 2cb8499..69330c5 100644
--- a/src/H5Spkg.h
+++ b/src/H5Spkg.h
@@ -29,9 +29,6 @@
#include "H5Sprivate.h"
-/* Number of reserved IDs in ID group */
-#define H5S_RESERVED_ATOMS 2
-
/* Flags to indicate special dataspace features are active */
#define H5S_VALID_MAX 0x01
#define H5S_VALID_PERM 0x02
diff --git a/src/H5Sprivate.h b/src/H5Sprivate.h
index a902918..bf9ff84 100644
--- a/src/H5Sprivate.h
+++ b/src/H5Sprivate.h
@@ -198,12 +198,12 @@ H5_DLL hbool_t H5S_has_extent(const H5S_t *ds);
H5_DLL int H5S_get_simple_extent_ndims(const H5S_t *ds);
H5_DLL int H5S_get_simple_extent_dims(const H5S_t *ds, hsize_t dims[]/*out*/,
hsize_t max_dims[]/*out*/);
-H5_DLL herr_t H5S_modify(struct H5G_entry_t *ent, const H5S_t *space,
- hbool_t update_time, hid_t dxpl_id);
+H5_DLL herr_t H5S_modify(struct H5O_loc_t *loc, const H5S_t *space,
+ hbool_t update_time, hid_t dxpl_id);
H5_DLL herr_t H5S_append(H5F_t *f, hid_t dxpl_id, struct H5O_t *oh,
const H5S_t *ds, unsigned * oh_flags_ptr);
H5_DLL size_t H5S_raw_size(const H5F_t *f, const H5S_t *space);
-H5_DLL H5S_t *H5S_read(const struct H5G_entry_t *ent, hid_t dxpl_id);
+H5_DLL H5S_t *H5S_read(const struct H5O_loc_t *loc, hid_t dxpl_id);
H5_DLL int H5S_extend(H5S_t *space, const hsize_t *size);
H5_DLL int H5S_set_extent(H5S_t *space, const hsize_t *size);
H5_DLL herr_t H5S_set_extent_real(H5S_t *space, const hsize_t *size);
diff --git a/src/H5Stest.c b/src/H5Stest.c
index 83fbd96..6df626c 100644
--- a/src/H5Stest.c
+++ b/src/H5Stest.c
@@ -22,10 +22,10 @@
#define H5S_TESTING /*suppress warning about H5S testing funcs*/
-#include "H5private.h" /* Generic Functions */
-#include "H5Eprivate.h" /* Error handling */
-#include "H5Iprivate.h" /* ID Functions */
-#include "H5Spkg.h" /* Dataspace functions */
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5Spkg.h" /* Dataspaces */
/*--------------------------------------------------------------------------
@@ -71,6 +71,7 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
} /* H5S_select_shape_same_test() */
+
/*--------------------------------------------------------------------------
NAME
H5S_inquiry_rebuild_status
diff --git a/src/H5T.c b/src/H5T.c
index f0800bb..10f8598 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -257,7 +257,6 @@ H5FL_DEFINE(H5T_shared_t);
H5FL_DEFINE(H5T_path_t);
/* Static local functions */
-static H5T_t *H5T_open_oid(H5G_entry_t *ent, hid_t dxpl_id);
static herr_t H5T_print_stats(H5T_path_t *path, int *nprint/*in,out*/);
static herr_t H5T_unregister(H5T_pers_t pers, const char *name, H5T_t *src,
H5T_t *dst, H5T_conv_t func, hid_t dxpl_id);
@@ -378,7 +377,7 @@ static H5T_t *H5T_decode(const unsigned char *buf);
/* Define a macro for common code for all newly allocate datatypes */
#define H5T_INIT_TYPE_ALLOC_COMMON(TYPE) { \
- dt->ent.header = HADDR_UNDEF; \
+ dt->oloc.addr = HADDR_UNDEF; \
dt->shared->type = TYPE; \
}
@@ -1568,75 +1567,6 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5Topen
- *
- * Purpose: Opens a named data type.
- *
- * Return: Success: Object ID of the named data type.
- *
- * Failure: Negative
- *
- * Programmer: Robb Matzke
- * Monday, June 1, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-hid_t
-H5Topen(hid_t loc_id, const char *name)
-{
- H5T_t *type = NULL;
- H5G_entry_t *loc = NULL;
- H5G_entry_t ent;
- hbool_t ent_found = FALSE; /* Entry at 'name' found */
- hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datatype */
- hid_t ret_value =FAIL;
-
- FUNC_ENTER_API(H5Topen, FAIL);
- H5TRACE2("i","is",loc_id,name);
-
- /* Check args */
- if (NULL==(loc=H5G_loc (loc_id)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- if (!name || !*name)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
-
- /*
- * Find the named data type object header and read the data type message
- * from it.
- */
- if (H5G_find (loc, name, &ent/*out*/, dxpl_id)<0)
- HGOTO_ERROR (H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found");
- ent_found = TRUE;
-
- /* Check that the object found is the correct type */
- if (H5G_get_type(&ent, dxpl_id) != H5G_TYPE)
- HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a named datatype")
-
- /* Open it */
- if ((type=H5T_open (&ent, dxpl_id)) ==NULL)
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open named data type");
-
- /* Register the type and return the ID */
- if ((ret_value=H5I_register (H5I_DATATYPE, type))<0)
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register named data type");
-
-done:
- if(ret_value<0) {
- if(type!=NULL)
- H5T_close(type);
- else {
- if(ent_found && ent.header)
- H5G_free_ent_name(&ent);
- } /* end else */
- } /* end if */
-
- FUNC_LEAVE_API(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5Tcopy
*
* Purpose: Copies a data type. The resulting data type is not locked.
@@ -3037,7 +2967,7 @@ done:
* Function: H5T_isa
*
* Purpose: Determines if an object has the requisite messages for being
- * a data type.
+ * a datatype.
*
* Return: Success: TRUE if the required data type messages are
* present; FALSE otherwise.
@@ -3048,166 +2978,23 @@ done:
* Programmer: Robb Matzke
* Monday, November 2, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
htri_t
-H5T_isa(H5G_entry_t *ent, hid_t dxpl_id)
+H5T_isa(H5O_loc_t *loc, hid_t dxpl_id)
{
htri_t ret_value;
- FUNC_ENTER_NOAPI(H5T_isa, FAIL);
- assert(ent);
-
- if ((ret_value=H5O_exists(ent, H5O_DTYPE_ID, 0, dxpl_id))<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to read object header");
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5T_open
- *
- * Purpose: Open a named data type.
- *
- * Return: Success: Ptr to a new data type.
- *
- * Failure: NULL
- *
- * Programmer: Robb Matzke
- * Monday, June 1, 1998
- *
- * Modifications:
- * Changed to use H5T_open_oid - QAK - 3/17/99
- *
- *-------------------------------------------------------------------------
- */
-H5T_t*
-H5T_open (H5G_entry_t *ent, hid_t dxpl_id)
-{
- H5T_shared_t *shared_fo=NULL;
- H5T_t *dt=NULL;
- H5T_t *ret_value;
-
- FUNC_ENTER_NOAPI(H5T_open, NULL);
-
- assert (ent);
-
- /* Check if datatype was already open */
- if((shared_fo=H5FO_opened(ent->file,ent->header))==NULL) {
- /* Clear any errors from H5FO_opened() */
- H5E_clear_stack(NULL);
-
- /* Open the datatype object */
- if ((dt=H5T_open_oid(ent, dxpl_id)) ==NULL)
- 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->ent.file, dt->ent.header, dt->shared)<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 */
- if(H5FO_top_incr(dt->ent.file, dt->ent.header) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
-
- /* Mark any datatypes as being in memory now */
- if (H5T_set_loc(dt, NULL, H5T_LOC_MEMORY)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location")
-
- dt->shared->fo_count=1;
- }
- else
- {
- if(NULL == (dt = H5FL_MALLOC(H5T_t)))
- HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for datatype")
-
- /* Shallow copy (take ownership) of the group entry object */
- if(H5G_ent_copy(&(dt->ent),ent,H5G_COPY_SHALLOW)<0)
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy group entry")
-
- dt->shared=shared_fo;
-
- shared_fo->fo_count++;
-
- /* Check if the object has been opened through the top file yet */
- if(H5FO_top_count(dt->ent.file, dt->ent.header) == 0) {
- /* Open the object through this top file */
- if(H5O_open(&(dt->ent)) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open object header")
- } /* end if */
-
- /* Increment object count for the object in the top file */
- if(H5FO_top_incr(dt->ent.file, dt->ent.header) < 0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
- }
-
- ret_value = dt;
-
-done:
- if(ret_value==NULL) {
- if(dt) {
- if(shared_fo==NULL) /* Need to free shared fo */
- H5FL_FREE(H5T_shared_t, dt->shared);
- H5FL_FREE(H5T_t, dt);
- }
- if(shared_fo)
- shared_fo->fo_count--;
- }
- FUNC_LEAVE_NOAPI(ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5T_open_oid
- *
- * Purpose: Open a named data type.
- *
- * Return: Success: Ptr to a new data type.
- *
- * Failure: NULL
- *
- * Programmer: Quincey Koziol
- * Wednesday, March 17, 1999
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-H5T_t *
-H5T_open_oid (H5G_entry_t *ent, hid_t dxpl_id)
-{
- H5T_t *dt=NULL;
- H5T_t *ret_value;
-
- FUNC_ENTER_NOAPI(H5T_open_oid, NULL);
-
- assert (ent);
+ FUNC_ENTER_NOAPI(H5T_isa, FAIL)
- if (H5O_open (ent)<0)
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open named data type");
- if (NULL==(dt=H5O_read (ent, H5O_DTYPE_ID, 0, NULL, dxpl_id)))
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to load type message from object header");
+ HDassert(loc);
- /* Mark the type as named and open */
- dt->shared->state = H5T_STATE_OPEN;
-
- /* Shallow copy (take ownership) of the group entry object */
- H5G_ent_copy(&(dt->ent),ent,H5G_COPY_SHALLOW);
-
- /* Set return value */
- ret_value=dt;
+ if((ret_value = H5O_exists(loc, H5O_DTYPE_ID, 0, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to read object header")
done:
- if(ret_value==NULL) {
- if(dt==NULL)
- H5O_close(ent);
- } /* end if */
-
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_isa() */
/*-------------------------------------------------------------------------
@@ -3299,22 +3086,22 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
* Return a transient type (locked or unlocked) or an opened named
* type. Immutable transient types are degraded to read-only.
*/
- if (H5F_addr_defined(old_dt->ent.header)) {
+ if(H5F_addr_defined(old_dt->oloc.addr)) {
/* Check if the object is already open */
- if((reopened_fo=H5FO_opened(old_dt->ent.file, old_dt->ent.header))==NULL) {
+ if((reopened_fo=H5FO_opened(old_dt->oloc.file, old_dt->oloc.addr))==NULL) {
/* Clear any errors from H5FO_opened() */
H5E_clear_stack(NULL);
/* Open named datatype again */
- if (H5O_open (&(old_dt->ent))<0)
+ if(H5O_open(&(old_dt->oloc)) < 0)
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->ent.file, old_dt->ent.header, new_dt->shared)<0)
+ if(H5FO_insert(old_dt->oloc.file, old_dt->oloc.addr, new_dt->shared)<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 */
- if(H5FO_top_incr(old_dt->ent.file, old_dt->ent.header) < 0)
+ if(H5FO_top_incr(old_dt->oloc.file, old_dt->oloc.addr) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
new_dt->shared->fo_count=1;
@@ -3328,14 +3115,14 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
reopened_fo->fo_count++;
/* Check if the object has been opened through the top file yet */
- if(H5FO_top_count(old_dt->ent.file, old_dt->ent.header) == 0) {
+ if(H5FO_top_count(old_dt->oloc.file, old_dt->oloc.addr) == 0) {
/* Open the object through this top file */
- if(H5O_open(&(old_dt->ent)) < 0)
+ if(H5O_open(&(old_dt->oloc)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open object header")
} /* end if */
/* Increment object count for the object in the top file */
- if(H5FO_top_incr(old_dt->ent.file, old_dt->ent.header) < 0)
+ if(H5FO_top_incr(old_dt->oloc.file, old_dt->oloc.addr) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
}
new_dt->shared->state = H5T_STATE_OPEN;
@@ -3452,14 +3239,17 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
} /* end switch */
/* Deep copy of the symbol table entry, if there was one */
- if ( new_dt->shared->state == H5T_STATE_NAMED || new_dt->shared->state == H5T_STATE_OPEN) {
- if (!H5F_addr_defined(old_dt->ent.header))
- HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "named dataype with invalid address");
- if (H5G_ent_copy(&(new_dt->ent), &(old_dt->ent),H5G_COPY_DEEP)<0)
- HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to copy entry");
+ if(new_dt->shared->state == H5T_STATE_NAMED || new_dt->shared->state == H5T_STATE_OPEN) {
+ if(!H5F_addr_defined(old_dt->oloc.addr))
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "named dataype with invalid address")
+ if(H5O_loc_copy(&(new_dt->oloc), &(old_dt->oloc), H5O_COPY_DEEP) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to copy entry")
+ if(H5G_name_copy(&(new_dt->path), &(old_dt->path), H5G_COPY_DEEP) < 0)
+ HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, NULL, "unable to copy path")
} /* end if */
else {
- H5G_ent_reset(&(new_dt->ent));
+ H5O_loc_reset(&(new_dt->oloc));
+ H5G_name_reset(&(new_dt->path));
} /* end else */
/* Set return value */
@@ -3540,7 +3330,7 @@ done:
H5T_t *
H5T_alloc(void)
{
- H5T_t *dt; /* Pointer to datatype allocated */
+ H5T_t *dt = NULL; /* Pointer to datatype allocated */
H5T_t *ret_value; /* Return value */
FUNC_ENTER_NOAPI(H5T_alloc, NULL)
@@ -3548,7 +3338,8 @@ H5T_alloc(void)
/* Allocate & initialize new datatype info */
if(NULL == (dt = H5FL_CALLOC(H5T_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
- H5G_ent_reset(&(dt->ent));
+ H5O_loc_reset(&(dt->oloc));
+ H5G_name_reset(&(dt->path));
if(NULL == (dt->shared = H5FL_CALLOC(H5T_shared_t)))
HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed")
@@ -3580,54 +3371,56 @@ done:
* Programmer: Quincey Koziol
* Monday, January 6, 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5T_free(H5T_t *dt)
{
unsigned i;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_free, FAIL);
+ FUNC_ENTER_NOAPI(H5T_free, FAIL)
- assert(dt && dt->shared);
+ HDassert(dt && dt->shared);
/*
* If a named type is being closed then close the object header and
* remove from the list of open objects in the file.
*/
- if (H5T_STATE_OPEN==dt->shared->state) {
- assert (H5F_addr_defined(dt->ent.header));
+ if(H5T_STATE_OPEN == dt->shared->state) {
+ HDassert(H5F_addr_defined(dt->oloc.addr));
+
/* Remove the datatype from the list of opened objects in the file */
- if(H5FO_top_decr(dt->ent.file, dt->ent.header) < 0)
+ if(H5FO_top_decr(dt->oloc.file, dt->oloc.addr) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "can't decrement count for object")
- if(H5FO_delete(dt->ent.file, H5AC_dxpl_id, dt->ent.header)<0)
+ if(H5FO_delete(dt->oloc.file, H5AC_dxpl_id, dt->oloc.addr) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "can't remove datatype from list of open objects")
- if (H5O_close(&(dt->ent))<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to close data type object header");
+ if(H5O_close(&(dt->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to close data type object header")
dt->shared->state = H5T_STATE_NAMED;
- }
+ } /* end if */
+
+ /* Free the ID to name info */
+ H5G_name_free(&(dt->path));
/*
* Don't free locked datatypes.
*/
- if (H5T_STATE_IMMUTABLE==dt->shared->state)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to close immutable datatype");
+ if(H5T_STATE_IMMUTABLE==dt->shared->state)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to close immutable datatype")
/* Close the datatype */
- switch (dt->shared->type) {
+ switch(dt->shared->type) {
case H5T_COMPOUND:
- for (i=0; i<dt->shared->u.compnd.nmembs; i++) {
+ for(i = 0; i < dt->shared->u.compnd.nmembs; i++) {
H5MM_xfree(dt->shared->u.compnd.memb[i].name);
H5T_close(dt->shared->u.compnd.memb[i].type);
- }
+ } /* end for */
H5MM_xfree(dt->shared->u.compnd.memb);
break;
case H5T_ENUM:
- for (i=0; i<dt->shared->u.enumer.nmembs; i++)
+ for(i = 0; i < dt->shared->u.enumer.nmembs; i++)
H5MM_xfree(dt->shared->u.enumer.name[i]);
H5MM_xfree(dt->shared->u.enumer.name);
H5MM_xfree(dt->shared->u.enumer.value);
@@ -3639,17 +3432,14 @@ H5T_free(H5T_t *dt)
default:
break;
- }
-
- /* Free the ID to name info */
- H5G_free_ent_name(&(dt->ent));
+ } /* end switch */
/* Close the parent */
- if (dt->shared->parent && H5T_close(dt->shared->parent)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close parent data type");
+ if(dt->shared->parent && H5T_close(dt->shared->parent) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCLOSEOBJ, FAIL, "unable to close parent data type")
done:
- FUNC_LEAVE_NOAPI(ret_value);
+ FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_free() */
@@ -3682,17 +3472,16 @@ done:
herr_t
H5T_close(H5T_t *dt)
{
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
- FUNC_ENTER_NOAPI(H5T_close, FAIL);
+ FUNC_ENTER_NOAPI(H5T_close, FAIL)
- assert(dt && dt->shared);
+ HDassert(dt && dt->shared);
dt->shared->fo_count--;
- if(dt->shared->state != H5T_STATE_OPEN || dt->shared->fo_count == 0)
- {
- if(H5T_free(dt)<0)
+ if(dt->shared->state != H5T_STATE_OPEN || dt->shared->fo_count == 0) {
+ if(H5T_free(dt) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTFREE, FAIL, "unable to free datatype");
H5FL_FREE(H5T_shared_t, dt->shared);
@@ -3701,27 +3490,27 @@ H5T_close(H5T_t *dt)
* If a named type is being closed then close the object header and
* remove from the list of open objects in the file.
*/
- if(H5T_STATE_OPEN==dt->shared->state) {
+ if(H5T_STATE_OPEN == dt->shared->state) {
/* Decrement the ref. count for this object in the top file */
- if(H5FO_top_decr(dt->ent.file, dt->ent.header) < 0)
+ if(H5FO_top_decr(dt->oloc.file, dt->oloc.addr) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTRELEASE, FAIL, "can't decrement count for object")
/* Check reference count for this object in the top file */
- if(H5FO_top_count(dt->ent.file, dt->ent.header) == 0)
- if(H5O_close(&(dt->ent)) < 0)
+ if(H5FO_top_count(dt->oloc.file, dt->oloc.addr) == 0)
+ if(H5O_close(&(dt->oloc)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to close")
} /* end if */
- /* Free the ID to name info since we're not calling H5T_free*/
- H5G_free_ent_name(&(dt->ent));
- }
+ /* Free the group hier. path since we're not calling H5T_free*/
+ H5G_name_free(&(dt->path));
+ } /* end else */
/* Free the datatype struct */
H5FL_FREE(H5T_t,dt);
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_close() */
/*-------------------------------------------------------------------------
@@ -4807,44 +4596,79 @@ done:
/*-------------------------------------------------------------------------
- * Function: H5T_entof
+ * Function: H5T_oloc
*
- * Purpose: Returns a pointer to the entry for a named data type.
- *
- * Return: Success: Ptr directly into named data type
+ * Purpose: Returns a pointer to the object location for a named datatype.
*
+ * Return: Success: Ptr directly into named datatype
* Failure: NULL
*
* Programmer: Robb Matzke
* Friday, June 5, 1998
*
- * Modifications:
+ *-------------------------------------------------------------------------
+ */
+H5O_loc_t *
+H5T_oloc(H5T_t *dt)
+{
+ H5O_loc_t *ret_value = NULL;
+
+ FUNC_ENTER_NOAPI(H5T_oloc, NULL)
+
+ HDassert(dt);
+
+ switch(dt->shared->state) {
+ case H5T_STATE_TRANSIENT:
+ case H5T_STATE_RDONLY:
+ case H5T_STATE_IMMUTABLE:
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "not a named datatype")
+ case H5T_STATE_NAMED:
+ case H5T_STATE_OPEN:
+ ret_value = &(dt->oloc);
+ break;
+ } /* end switch */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_oloc() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_nameof
+ *
+ * Purpose: Returns a pointer to the path for a named datatype.
+ *
+ * Return: Success: Ptr directly into named datatype
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Monday, September 12, 2005
*
*-------------------------------------------------------------------------
*/
-H5G_entry_t *
-H5T_entof (H5T_t *dt)
+H5G_name_t *
+H5T_nameof(H5T_t *dt)
{
- H5G_entry_t *ret_value = NULL;
+ H5G_name_t *ret_value = NULL;
- FUNC_ENTER_NOAPI(H5T_entof, NULL);
+ FUNC_ENTER_NOAPI(H5T_nameof, NULL)
- assert (dt);
+ HDassert(dt);
- switch (dt->shared->state) {
+ switch(dt->shared->state) {
case H5T_STATE_TRANSIENT:
case H5T_STATE_RDONLY:
case H5T_STATE_IMMUTABLE:
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL, "not a named data type");
+ HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL, "not a named datatype")
case H5T_STATE_NAMED:
case H5T_STATE_OPEN:
- ret_value = &(dt->ent);
+ ret_value = &(dt->path);
break;
- }
+ } /* end switch */
done:
- FUNC_LEAVE_NOAPI(ret_value);
-}
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_nameof() */
/*-------------------------------------------------------------------------
@@ -5430,16 +5254,6 @@ H5T_debug(const H5T_t *dt, FILE *stream)
fprintf(stream, "\n\"%s\" @%lu",
dt->shared->u.compnd.memb[i].name,
(unsigned long) (dt->shared->u.compnd.memb[i].offset));
-#ifdef OLD_WAY
- if (dt->shared->u.compnd.memb[i].ndims) {
- fprintf(stream, "[");
- for (j = 0; j < dt->shared->u.compnd.memb[i].ndims; j++) {
- fprintf(stream, "%s%lu", j ? ", " : "",
- (unsigned long)(dt->shared->u.compnd.memb[i].dim[j]));
- }
- fprintf(stream, "]");
- }
-#endif /* OLD_WAY */
fprintf(stream, " ");
H5T_debug(dt->shared->u.compnd.memb[i].type, stream);
}
diff --git a/src/H5Tarray.c b/src/H5Tarray.c
index 5a63011..71c80b8 100644
--- a/src/H5Tarray.c
+++ b/src/H5Tarray.c
@@ -25,14 +25,9 @@
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
-#include "H5FLprivate.h" /* Free Lists */
#include "H5Iprivate.h" /* IDs */
#include "H5Tpkg.h" /* Datatypes */
-/* Declare extern the free list for H5T_t's */
-H5FL_EXTERN(H5T_t);
-H5FL_EXTERN(H5T_shared_t);
-
/*--------------------------------------------------------------------------
NAME
diff --git a/src/H5Tbit.c b/src/H5Tbit.c
index e3769fe..d298d4c 100644
--- a/src/H5Tbit.c
+++ b/src/H5Tbit.c
@@ -240,12 +240,12 @@ done:
*
*-------------------------------------------------------------------------
*/
-hsize_t
+uint64_t
H5T_bit_get_d (uint8_t *buf, size_t offset, size_t size)
{
- hsize_t val=0;
+ uint64_t val=0;
size_t i, hs;
- hsize_t ret_value; /* Return value */
+ uint64_t ret_value; /* Return value */
FUNC_ENTER_NOAPI_NOFUNC(H5T_bit_get_d);
@@ -290,7 +290,7 @@ H5T_bit_get_d (uint8_t *buf, size_t offset, size_t size)
*-------------------------------------------------------------------------
*/
void
-H5T_bit_set_d (uint8_t *buf, size_t offset, size_t size, hsize_t val)
+H5T_bit_set_d (uint8_t *buf, size_t offset, size_t size, uint64_t val)
{
size_t i, hs;
diff --git a/src/H5Tcommit.c b/src/H5Tcommit.c
index 098450d..c42b9dd 100644
--- a/src/H5Tcommit.c
+++ b/src/H5Tcommit.c
@@ -25,6 +25,7 @@
#include "H5private.h" /* Generic Functions */
#include "H5Eprivate.h" /* Error handling */
+#include "H5FLprivate.h" /* Free Lists */
#include "H5FOprivate.h" /* File objects */
#include "H5Iprivate.h" /* IDs */
#include "H5Oprivate.h" /* Object headers */
@@ -32,8 +33,9 @@
#include "H5Tpkg.h" /* Datatypes */
/* Static local functions */
-static herr_t H5T_commit(H5G_entry_t *loc, const char *name, H5T_t *type,
+static herr_t H5T_commit(H5G_loc_t *loc, const char *name, 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);
/*--------------------------------------------------------------------------
@@ -69,36 +71,33 @@ H5T_init_commit_interface(void)
* Programmer: Robb Matzke
* Monday, June 1, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Tcommit(hid_t loc_id, const char *name, hid_t type_id)
{
- H5G_entry_t *loc = NULL;
+ H5G_loc_t loc;
H5T_t *type = NULL;
- herr_t ret_value=SUCCEED; /* Return value */
+ herr_t ret_value = SUCCEED; /* Return value */
FUNC_ENTER_API(H5Tcommit, FAIL)
H5TRACE3("e","isi",loc_id,name,type_id);
/* Check arguments */
- if (NULL==(loc=H5G_loc (loc_id)))
- 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")
+ 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")
/* Commit the type */
- if (H5T_commit(loc, name, type, H5AC_dxpl_id, H5P_DATATYPE_CREATE_DEFAULT,
- H5P_DEFAULT)<0)
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype")
+ if(H5T_commit(&loc, name, type, H5AC_dxpl_id, H5P_DATATYPE_CREATE_DEFAULT, H5P_DEFAULT) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Tcommit() */
/*-------------------------------------------------------------------------
@@ -113,26 +112,24 @@ done:
* Programmer: Peter Cao
* May 17, 2005
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
herr_t
H5Tcommit_expand(hid_t loc_id, const char *name, hid_t type_id, hid_t tcpl_id, hid_t tapl_id)
{
- H5G_entry_t *loc = NULL;
+ H5G_loc_t loc;
H5T_t *type = NULL;
herr_t ret_value=SUCCEED; /* Return value */
FUNC_ENTER_API(H5Tcommit_expand, FAIL)
/* Check arguments */
- if (NULL==(loc=H5G_loc (loc_id)))
- 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")
+ 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")
/* Get correct property list */
if(H5P_DEFAULT == tcpl_id)
@@ -151,12 +148,12 @@ 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, name, type, H5AC_dxpl_id, tcpl_id, tapl_id) < 0)
HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to commit datatype")
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Tcommit_expand() */
/*-------------------------------------------------------------------------
@@ -170,29 +167,25 @@ done:
* Programmer: Robb Matzke
* Monday, June 1, 1998
*
- * Modifications:
- * Added datatype creation & access property lists
- * Peter Cao
- * May 17, 2005
- *
*-------------------------------------------------------------------------
*/
static herr_t
-H5T_commit(H5G_entry_t *loc, const char *name, H5T_t *type, hid_t dxpl_id,
+H5T_commit(H5G_loc_t *loc, const char *name, H5T_t *type, hid_t dxpl_id,
hid_t tcpl_id, hid_t UNUSED tapl_id)
{
H5F_t *file = NULL;
H5P_genplist_t *tc_plist; /* Property list created */
- herr_t ret_value=SUCCEED; /* Return value */
+ 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 (type);
- HDassert (tcpl_id != H5P_DEFAULT);
+ HDassert(loc);
+ HDassert(name && *name);
+ HDassert(type);
+ HDassert(tcpl_id != H5P_DEFAULT);
#ifdef LATER
- HDassert (tapl_id != H5P_DEFAULT);
+ HDassert(tapl_id != H5P_DEFAULT);
#endif /* LATER */
/*
@@ -200,51 +193,56 @@ H5T_commit(H5G_entry_t *loc, const char *name, H5T_t *type, hid_t dxpl_id,
* normally fails on such types (try H5Tclose(H5T_NATIVE_INT)) but closing
* a named type should always succeed.
*/
- if (H5T_STATE_NAMED==type->shared->state || H5T_STATE_OPEN==type->shared->state)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is already committed")
- if (H5T_STATE_IMMUTABLE==type->shared->state)
- HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is immutable")
+ if(H5T_STATE_NAMED == type->shared->state || H5T_STATE_OPEN == type->shared->state)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "datatype is already committed")
+ 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)))
+ 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)
+ if(H5T_is_sensible(type) <= 0)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "datatype is not sensible")
/* Mark datatype as being on disk now. This step changes the size of datatype as
* stored on disk. */
- if(H5T_set_loc(type, file, H5T_LOC_DISK)<0)
+ if(H5T_set_loc(type, file, H5T_LOC_DISK) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk")
+ /* Set up & reset datatype location */
+ type_loc.oloc = &(type->oloc);
+ type_loc.path = &(type->path);
+ H5G_loc_reset(&type_loc);
+
/*
* Create the object header and open it for write access. Insert the data
* type message and then give the object header a name.
*/
- if (H5O_create (file, dxpl_id, 64, &(type->ent))<0)
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create datatype object header")
- if (H5O_modify (&(type->ent), H5O_DTYPE_ID, 0, H5O_FLAG_CONSTANT, H5O_UPDATE_TIME, type, dxpl_id)<0)
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to update type header message")
+ if(H5O_create(file, dxpl_id, 64, &(type->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to create datatype object header")
+ if(H5O_modify(&(type->oloc), H5O_DTYPE_ID, 0, H5O_FLAG_CONSTANT, H5O_UPDATE_TIME, type, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to update type header message")
/* Get the property list */
- if (NULL == (tc_plist = H5I_object(tcpl_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->ent), dxpl_id, tc_plist)<0)
- HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to name datatype")
+ 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->ent.file, type->ent.header)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't incr object ref. count")
- if(H5FO_insert(type->ent.file, type->ent.header, type->shared)<0)
+ 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)
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
@@ -253,18 +251,18 @@ H5T_commit(H5G_entry_t *loc, const char *name, H5T_t *type, hid_t dxpl_id,
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype in memory")
done:
- if (ret_value<0) {
- if ((type->shared->state==H5T_STATE_TRANSIENT || type->shared->state==H5T_STATE_RDONLY) && H5F_addr_defined(type->ent.header)) {
- if(H5O_close(&(type->ent))<0)
+ if(ret_value < 0) {
+ if((type->shared->state == H5T_STATE_TRANSIENT || type->shared->state == H5T_STATE_RDONLY) && H5F_addr_defined(type->oloc.addr)) {
+ if(H5O_close(&(type->oloc)) < 0)
HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, FAIL, "unable to release object header")
- if(H5O_delete(file, dxpl_id,type->ent.header)<0)
+ if(H5O_delete(file, dxpl_id, type->oloc.addr) < 0)
HDONE_ERROR(H5E_DATATYPE, H5E_CANTDELETE, FAIL, "unable to delete object header")
- type->ent.header = HADDR_UNDEF;
- }
- }
+ type->oloc.addr = HADDR_UNDEF;
+ } /* end if */
+ } /* end if */
FUNC_LEAVE_NOAPI(ret_value)
-}
+} /* H5T_commit() */
/*-------------------------------------------------------------------------
@@ -279,8 +277,6 @@ done:
* Programmer: Robb Matzke
* Thursday, June 4, 1998
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
htri_t
@@ -293,15 +289,15 @@ H5Tcommitted(hid_t type_id)
H5TRACE1("t","i",type_id);
/* Check arguments */
- if (NULL==(type=H5I_object_verify(type_id,H5I_DATATYPE)))
- HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
+ if(NULL == (type = H5I_object_verify(type_id,H5I_DATATYPE)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype")
/* Set return value */
- ret_value= H5T_committed(type);
+ ret_value = H5T_committed(type);
done:
FUNC_LEAVE_API(ret_value)
-}
+} /* end H5Tcommitted() */
/*-------------------------------------------------------------------------
@@ -314,8 +310,6 @@ done:
* Programmer: Quincey Koziol
* Wednesday, September 24, 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
htri_t
@@ -324,9 +318,9 @@ H5T_committed(const H5T_t *type)
/* Use no-init for efficiency */
FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_committed)
- assert (type);
+ HDassert(type);
- FUNC_LEAVE_NOAPI(H5T_STATE_OPEN==type->shared->state || H5T_STATE_NAMED==type->shared->state)
+ FUNC_LEAVE_NOAPI(H5T_STATE_OPEN == type->shared->state || H5T_STATE_NAMED == type->shared->state)
} /* end H5T_committed() */
@@ -343,8 +337,6 @@ H5T_committed(const H5T_t *type)
* Programmer: Quincey Koziol
* Friday, September 26, 2003
*
- * Modifications:
- *
*-------------------------------------------------------------------------
*/
int
@@ -355,13 +347,234 @@ H5T_link(const H5T_t *type, int adjust, hid_t dxpl_id)
/* Use no-init for efficiency */
FUNC_ENTER_NOAPI(H5T_link,FAIL)
- assert (type);
+ HDassert(type);
/* Adjust the link count on the named datatype */
- if((ret_value=H5O_link(&(type->ent),adjust,dxpl_id))<0)
- HGOTO_ERROR (H5E_DATATYPE, H5E_LINK, FAIL, "unable to adjust named datatype link count")
+ if((ret_value = H5O_link(&(type->oloc), adjust, dxpl_id)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_LINK, FAIL, "unable to adjust named datatype link count")
done:
FUNC_LEAVE_NOAPI(ret_value)
} /* end H5T_link() */
+
+/*-------------------------------------------------------------------------
+ * Function: H5Topen
+ *
+ * Purpose: Opens a named datatype.
+ *
+ * Return: Success: Object ID of the named datatype.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Monday, June 1, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Topen(hid_t loc_id, const char *name)
+{
+ H5T_t *type = NULL;
+ H5G_loc_t loc;
+ H5G_name_t path; /* Datatype group hier. path */
+ H5O_loc_t oloc; /* Datatype object location */
+ H5G_loc_t type_loc; /* Group object for datatype */
+ hbool_t obj_found = FALSE; /* Object at 'name' found */
+ hid_t dxpl_id = H5AC_dxpl_id; /* dxpl to use to open datatype */
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER_API(H5Topen, FAIL)
+ H5TRACE2("i","is",loc_id,name);
+
+ /* Check args */
+ if(H5G_loc(loc_id, &loc) < 0)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
+ if(!name || !*name)
+ HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
+
+ /* Set up datatype location to fill in */
+ type_loc.oloc = &oloc;
+ type_loc.path = &path;
+ H5G_loc_reset(&type_loc);
+
+ /*
+ * Find the named datatype object header and read the datatype message
+ * from it.
+ */
+ if(H5G_loc_find(&loc, name, &type_loc/*out*/, dxpl_id) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_NOTFOUND, FAIL, "not found")
+ obj_found = TRUE;
+
+ /* Check that the object found is the correct type */
+ if(H5O_obj_type(&oloc, dxpl_id) != H5G_TYPE)
+ HGOTO_ERROR(H5E_DATASET, H5E_BADTYPE, FAIL, "not a named datatype")
+
+ /* Open it */
+ if((type = H5T_open(&type_loc, dxpl_id)) == NULL)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL, "unable to open named datatype")
+
+ /* Register the type and return the ID */
+ if((ret_value = H5I_register(H5I_DATATYPE, type)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register named datatype")
+
+done:
+ if(ret_value < 0) {
+ if(type != NULL)
+ H5T_close(type);
+ else {
+ if(obj_found && H5F_addr_defined(type_loc.oloc->addr))
+ H5G_name_free(type_loc.path);
+ } /* end else */
+ } /* end if */
+
+ FUNC_LEAVE_API(ret_value)
+} /* end H5Topen() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_open
+ *
+ * Purpose: Open a named datatype.
+ *
+ * Return: Success: Ptr to a new datatype.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Monday, June 1, 1998
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_t *
+H5T_open(H5G_loc_t *loc, hid_t dxpl_id)
+{
+ H5T_shared_t *shared_fo = NULL;
+ H5T_t *dt = NULL;
+ H5T_t *ret_value;
+
+ FUNC_ENTER_NOAPI(H5T_open, NULL)
+
+ HDassert(loc);
+
+ /* Check if datatype was already open */
+ if((shared_fo = H5FO_opened(loc->oloc->file, loc->oloc->addr)) == NULL) {
+ /* Clear any errors from H5FO_opened() */
+ H5E_clear_stack(NULL);
+
+ /* Open the datatype object */
+ if((dt = H5T_open_oid(loc, dxpl_id)) == NULL)
+ 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)
+ 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 */
+ if(H5FO_top_incr(dt->oloc.file, dt->oloc.addr) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
+
+ /* Mark any datatypes as being in memory now */
+ if(H5T_set_loc(dt, NULL, H5T_LOC_MEMORY) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location")
+
+ dt->shared->fo_count = 1;
+ } /* end if */
+ else {
+ if(NULL == (dt = H5FL_MALLOC(H5T_t)))
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "can't allocate space for datatype")
+
+ /* Shallow copy (take ownership) of the object location object */
+ if(H5O_loc_copy(&(dt->oloc), loc->oloc, H5O_COPY_SHALLOW) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy object location")
+
+ /* Shallow copy (take ownership) of the group hier. path */
+ if(H5G_name_copy(&(dt->path), loc->path, H5G_COPY_SHALLOW) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy path")
+
+ dt->shared = shared_fo;
+
+ shared_fo->fo_count++;
+
+ /* Check if the object has been opened through the top file yet */
+ if(H5FO_top_count(dt->oloc.file, dt->oloc.addr) == 0) {
+ /* Open the object through this top file */
+ if(H5O_open(&(dt->oloc)) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open object header")
+ } /* end if */
+
+ /* Increment object count for the object in the top file */
+ if(H5FO_top_incr(dt->oloc.file, dt->oloc.addr) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINC, NULL, "can't increment object count")
+ } /* end else */
+
+ ret_value = dt;
+
+done:
+ if(ret_value == NULL) {
+ if(dt) {
+ if(shared_fo == NULL) /* Need to free shared fo */
+ H5FL_FREE(H5T_shared_t, dt->shared);
+ H5FL_FREE(H5T_t, dt);
+ } /* end if */
+
+ if(shared_fo)
+ shared_fo->fo_count--;
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_open() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5T_open_oid
+ *
+ * Purpose: Open a named datatype.
+ *
+ * Return: Success: Ptr to a new datatype.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, March 17, 1999
+ *
+ *-------------------------------------------------------------------------
+ */
+static H5T_t *
+H5T_open_oid(H5G_loc_t *loc, hid_t dxpl_id)
+{
+ H5T_t *dt = NULL;
+ H5T_t *ret_value;
+
+ FUNC_ENTER_NOAPI(H5T_open_oid, NULL)
+
+ HDassert(loc);
+
+ if(H5O_open(loc->oloc) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTOPENOBJ, NULL, "unable to open named datatype")
+ if(NULL == (dt = H5O_read(loc->oloc, H5O_DTYPE_ID, 0, NULL, dxpl_id)))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "unable to load type message from object header")
+
+ /* Mark the type as named and open */
+ dt->shared->state = H5T_STATE_OPEN;
+
+ /* Shallow copy (take ownership) of the object location object */
+ if(H5O_loc_copy(&(dt->oloc), loc->oloc, H5O_COPY_SHALLOW) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy object location")
+
+ /* Shallow copy (take ownership) of the group hier. path */
+ if(H5G_name_copy(&(dt->path), loc->path, H5G_COPY_SHALLOW) < 0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy path")
+
+ /* Set return value */
+ ret_value = dt;
+
+done:
+ if(ret_value == NULL) {
+ if(dt == NULL)
+ H5O_close(loc->oloc);
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5T_open_oid() */
+
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 5cfdfba..32f647e 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -21,6 +21,7 @@
#include "H5private.h" /*generic functions */
#include "H5Eprivate.h" /*error handling */
#include "H5FLprivate.h" /*Free Lists */
+#include "H5HGprivate.h" /* Global Heaps */
#include "H5Iprivate.h" /*ID functions */
#include "H5MMprivate.h" /*memory management */
#include "H5Pprivate.h" /* Property Lists */
@@ -3555,7 +3556,7 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
size_t elmtno; /*element number */
size_t half_size; /*half the type size */
size_t olap; /*num overlapping elements */
- ssize_t bitno; /*bit number */
+ ssize_t bitno = 0; /*bit number */
uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/
uint8_t *src_rev=NULL; /*order-reversed source buffer */
uint8_t dbuf[64]; /*temp destination buffer */
@@ -4200,7 +4201,8 @@ H5T_conv_s_s (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts,
while (nchars>0 && ' '==s[nchars-1])
--nchars;
nchars = MIN(dst->shared->size, nchars);
- HDmemcpy(d, s, nchars);
+ if(d != s)
+ HDmemcpy(d, s, nchars);
break;
case H5T_STR_RESERVED_3:
diff --git a/src/H5Tenum.c b/src/H5Tenum.c
index be80563..6d45e57 100644
--- a/src/H5Tenum.c
+++ b/src/H5Tenum.c
@@ -25,15 +25,10 @@
#include "H5private.h" /*generic functions */
#include "H5Eprivate.h" /*error handling */
-#include "H5FLprivate.h" /*Free Lists */
#include "H5Iprivate.h" /*ID functions */
#include "H5MMprivate.h" /*memory management */
#include "H5Tpkg.h" /*data-type functions */
-/* Declare extern the free lists for H5T_t's and H5T_shared_t's */
-H5FL_EXTERN(H5T_t);
-H5FL_EXTERN(H5T_shared_t);
-
/* Static local functions */
static char *H5T_enum_nameof(const H5T_t *dt, const void *value, char *name/*out*/,
size_t size);
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 35c3781..522329b 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -39,6 +39,8 @@
/* Other private headers needed by this file */
#include "H5Fprivate.h" /* Files */
+#include "H5FLprivate.h" /* Free Lists */
+#include "H5Oprivate.h" /* Object headers */
/* Other public headers needed by this file */
#include "H5Spublic.h" /* Dataspace functions */
@@ -150,6 +152,8 @@
#if (H5_WANT_DATA_ACCURACY && H5_FP_TO_ULLONG_ACCURATE && H5_FP_TO_ULLONG_RIGHT_MAXIMUM) || \
(!H5_WANT_DATA_ACCURACY)
#define H5T_CONV_INTERNAL_FP_ULLONG 1
+#else
+#define H5T_CONV_INTERNAL_FP_ULLONG 0
#endif
/* Define an internal macro for converting long double to all integers. SGI compilers give some incorrect
@@ -158,6 +162,8 @@
H5_FP_TO_ULLONG_ACCURATE && H5_FP_TO_ULLONG_RIGHT_MAXIMUM) || \
(!H5_WANT_DATA_ACCURACY && H5_LDOUBLE_TO_INTEGER_WORKS)
#define H5T_CONV_INTERNAL_LDOUBLE_ULLONG 1
+#else
+#define H5T_CONV_INTERNAL_LDOUBLE_ULLONG 0
#endif
/* Statistics about a conversion function */
@@ -311,8 +317,9 @@ typedef struct H5T_shared_t {
} H5T_shared_t;
struct H5T_t {
- H5G_entry_t ent; /* entry information if the type is a named type */
H5T_shared_t *shared; /* all other information */
+ H5O_loc_t oloc; /* object location information if the type is a named type */
+ H5G_name_t path; /* group hier. path if the type is a named type */
};
/* A compound datatype member */
@@ -425,6 +432,10 @@ H5_DLLVAR double H5T_NATIVE_LDOUBLE_POS_INF_g;
H5_DLLVAR double H5T_NATIVE_LDOUBLE_NEG_INF_g;
#endif
+/* Declare extern the free lists for H5T_t's and H5T_shared_t's */
+H5FL_EXTERN(H5T_t);
+H5FL_EXTERN(H5T_shared_t);
+
/* Common functions */
H5_DLL H5T_t *H5T_create(H5T_class_t type, size_t size);
H5_DLL H5T_t *H5T_alloc(void);
@@ -1288,9 +1299,9 @@ H5_DLL void H5T_bit_copy(uint8_t *dst, size_t dst_offset, const uint8_t *src,
H5_DLL void H5T_bit_shift(uint8_t *buf, ssize_t shift_dist, size_t offset, size_t size);
H5_DLL void H5T_bit_set(uint8_t *buf, size_t offset, size_t size,
hbool_t value);
-H5_DLL hsize_t H5T_bit_get_d(uint8_t *buf, size_t offset, size_t size);
+H5_DLL uint64_t H5T_bit_get_d(uint8_t *buf, size_t offset, size_t size);
H5_DLL void H5T_bit_set_d(uint8_t *buf, size_t offset, size_t size,
- hsize_t val);
+ uint64_t val);
H5_DLL ssize_t H5T_bit_find(uint8_t *buf, size_t offset, size_t size,
H5T_sdir_t direction, hbool_t value);
H5_DLL htri_t H5T_bit_inc(uint8_t *buf, size_t start, size_t size);
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 0ec08a7..62a4e13 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -66,17 +66,17 @@ typedef struct H5T_conv_cb_t {
/* Private functions */
H5_DLL herr_t H5TN_init_interface(void);
H5_DLL herr_t H5T_init(void);
-H5_DLL htri_t H5T_isa(H5G_entry_t *ent, hid_t dxpl_id);
-H5_DLL H5T_t *H5T_open(H5G_entry_t *ent, hid_t dxpl_id);
+H5_DLL htri_t H5T_isa(struct H5O_loc_t *loc, hid_t dxpl_id);
H5_DLL H5T_t *H5T_copy(const H5T_t *old_dt, H5T_copy_t method);
H5_DLL herr_t H5T_lock(H5T_t *dt, hbool_t immutable);
H5_DLL herr_t H5T_close(H5T_t *dt);
H5_DLL H5T_class_t H5T_get_class(const H5T_t *dt, htri_t internal);
-H5_DLL htri_t H5T_detect_class (const H5T_t *dt, H5T_class_t cls);
+H5_DLL htri_t H5T_detect_class(const H5T_t *dt, H5T_class_t cls);
H5_DLL size_t H5T_get_size(const H5T_t *dt);
H5_DLL int H5T_cmp(const H5T_t *dt1, const H5T_t *dt2, hbool_t superset);
H5_DLL herr_t H5T_debug(const H5T_t *dt, FILE * stream);
-H5_DLL H5G_entry_t *H5T_entof(H5T_t *dt);
+H5_DLL struct H5O_loc_t *H5T_oloc(H5T_t *dt);
+H5_DLL H5G_name_t *H5T_nameof(H5T_t *dt);
H5_DLL htri_t H5T_is_immutable(const H5T_t *dt);
H5_DLL htri_t H5T_is_named(const H5T_t *dt);
H5_DLL htri_t H5T_is_relocatable(const H5T_t *dt);
@@ -91,10 +91,13 @@ H5_DLL herr_t H5T_vlen_reclaim(void *elem, hid_t type_id, unsigned ndim, const h
H5_DLL herr_t H5T_vlen_get_alloc_info(hid_t dxpl_id, H5T_vlen_alloc_info_t **vl_alloc_info);
H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc);
H5_DLL htri_t H5T_is_sensible(const H5T_t *dt);
-H5_DLL htri_t H5T_committed(const H5T_t *type);
-H5_DLL int H5T_link(const H5T_t *type, int adjust, hid_t dxpl_id);
/* Reference specific functions */
H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt);
+/* Operations on named datatypes */
+H5_DLL H5T_t *H5T_open(H5G_loc_t *loc, hid_t dxpl_id);
+H5_DLL htri_t H5T_committed(const H5T_t *type);
+H5_DLL int H5T_link(const H5T_t *type, int adjust, hid_t dxpl_id);
+
#endif
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c
index 081d896..e4b40f9 100644
--- a/src/H5Tvlen.c
+++ b/src/H5Tvlen.c
@@ -26,7 +26,6 @@
#include "H5private.h" /* Generic Functions */
#include "H5Dprivate.h" /* Dataset functions */
#include "H5Eprivate.h" /* Error handling */
-#include "H5FLprivate.h" /* Free Lists */
#include "H5HGprivate.h" /* Global Heaps */
#include "H5Iprivate.h" /* IDs */
#include "H5MMprivate.h" /* Memory management */
@@ -64,10 +63,6 @@ static H5T_vlen_alloc_info_t H5T_vlen_def_vl_alloc_info ={
H5D_XFER_VLEN_FREE_INFO_DEF
};
-/* Declare extern the free lists for H5T_t's and H5T_shared_t's */
-H5FL_EXTERN(H5T_t);
-H5FL_EXTERN(H5T_shared_t);
-
/*--------------------------------------------------------------------------
NAME
diff --git a/src/H5err.txt b/src/H5err.txt
index 76a9de0..65c4e1f 100644
--- a/src/H5err.txt
+++ b/src/H5err.txt
@@ -176,6 +176,7 @@ MINOR, OHDR, H5E_ALIGNMENT, Alignment error
MINOR, OHDR, H5E_BADMESG, Unrecognized message
MINOR, OHDR, H5E_CANTDELETE, Can't delete message
MINOR, OHDR, H5E_BADITER, Iteration failed
+MINOR, OHDR, H5E_CANTPACK, Can't pack messages
# Group related errors
MINOR, GROUP, H5E_CANTOPENOBJ, Can't open object
diff --git a/src/H5private.h b/src/H5private.h
index 9b45463..28ec832 100644
--- a/src/H5private.h
+++ b/src/H5private.h
@@ -1392,6 +1392,7 @@ H5_DLL int H5E_term_interface(void);
H5_DLL int H5F_term_interface(void);
H5_DLL int H5G_term_interface(void);
H5_DLL int H5I_term_interface(void);
+H5_DLL int H5O_term_interface(void);
H5_DLL int H5P_term_interface(void);
H5_DLL int H5R_term_interface(void);
H5_DLL int H5S_term_interface(void);
diff --git a/src/Makefile.am b/src/Makefile.am
index b4307a0..cf9ebd1 100755
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -49,12 +49,18 @@ libhdf5_la_SOURCES= H5.c H5A.c H5AC.c H5B.c H5Bcache.c H5B2.c H5B2cache.c \
H5FDfamily.c H5FDfphdf5.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDstdio.c \
H5FDstream.c H5FL.c H5FO.c H5FP.c H5FPclient.c H5FPserver.c H5FS.c \
- H5G.c H5Gent.c H5Gnode.c H5Gstab.c \
+ H5G.c H5Gent.c H5Glink.c H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c \
+ H5Gstab.c \
+ H5Gtest.c \
+ H5Gtraverse.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 \
- H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Olayout.c H5Omtime.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 \
H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c H5Oshared.c H5Ostab.c \
H5P.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pgcpl.c H5Pocpl.c \
H5Ptest.c \
diff --git a/src/Makefile.in b/src/Makefile.in
index 516859b..2ae474f 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -92,10 +92,12 @@ am_libhdf5_la_OBJECTS = H5.lo H5A.lo H5AC.lo H5B.lo H5Bcache.lo \
H5FDfphdf5.lo H5FDlog.lo H5FDmpi.lo H5FDmpio.lo \
H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo H5FDstdio.lo \
H5FDstream.lo H5FL.lo H5FO.lo H5FP.lo H5FPclient.lo \
- H5FPserver.lo H5FS.lo H5G.lo H5Gent.lo H5Gnode.lo H5Gstab.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 \
- H5Ocont.lo H5Odtype.lo H5Oefl.lo H5Ofill.lo H5Olayout.lo \
+ H5FPserver.lo H5FS.lo H5G.lo H5Gent.lo H5Glink.lo H5Gloc.lo \
+ H5Gname.lo H5Gnode.lo H5Gobj.lo H5Gstab.lo H5Gtest.lo \
+ H5Gtraverse.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 H5Pdcpl.lo H5Pdxpl.lo \
H5Pfapl.lo H5Pfcpl.lo H5Pgcpl.lo H5Pocpl.lo H5Ptest.lo H5R.lo \
@@ -396,12 +398,18 @@ libhdf5_la_SOURCES = H5.c H5A.c H5AC.c H5B.c H5Bcache.c H5B2.c H5B2cache.c \
H5FDfamily.c H5FDfphdf5.c H5FDlog.c H5FDmpi.c H5FDmpio.c \
H5FDmpiposix.c H5FDmulti.c H5FDsec2.c H5FDstdio.c \
H5FDstream.c H5FL.c H5FO.c H5FP.c H5FPclient.c H5FPserver.c H5FS.c \
- H5G.c H5Gent.c H5Gnode.c H5Gstab.c \
+ H5G.c H5Gent.c H5Glink.c H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c \
+ H5Gstab.c \
+ H5Gtest.c \
+ H5Gtraverse.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 \
- H5Ocont.c H5Odtype.c H5Oefl.c H5Ofill.c H5Olayout.c H5Omtime.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 \
H5Oname.c H5Onull.c H5Opline.c H5Osdspace.c H5Oshared.c H5Ostab.c \
H5P.c H5Pdcpl.c H5Pdxpl.c H5Pfapl.c H5Pfcpl.c H5Pgcpl.c H5Pocpl.c \
H5Ptest.c \
@@ -601,8 +609,14 @@ distclean-compile:
@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)/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@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gname.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gnode.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gobj.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gstab.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gtest.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Gtraverse.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HG.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HGdbg.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5HL.Plo@am__quote@
@@ -616,11 +630,15 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5O.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Oattr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Obogus.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ocache.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ocont.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Odtype.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Oefl.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ofill.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Oginfo.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Olayout.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Olinfo.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Olink.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Omtime.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Oname.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Onull.Plo@am__quote@