From 8d344f96bcd012742c55e668d6a6b3d81d1c39ee Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Sat, 3 Dec 2005 21:27:37 -0500 Subject: [svn-r11758] Purpose: New feature Description: Add in a combination of Peter's & my code to support copying variable-length data from one file to another, although currently only supported with contiguous data storage. Platforms tested: FreeBSD 4.11 (sleipnir) h5committest --- MANIFEST | 3 + fortran/src/H5Rff.f90 | 16 +- fortran/src/H5_f.c | 8 +- fortran/src/H5f90global.f90 | 10 +- fortran/test/tH5R.f90 | 4 +- src/H5.c | 3 - src/H5D.c | 159 +++--- src/H5Dcontig.c | 213 +++++++- src/H5Doh.c | 176 +++++++ src/H5Dpkg.h | 5 +- src/H5Dprivate.h | 1 - src/H5G.c | 41 -- src/H5Goh.c | 102 ++++ src/H5Gprivate.h | 4 +- src/H5Gpublic.h | 2 +- src/H5O.c | 1068 ++++++++++++++++++--------------------- src/H5Oattr.c | 29 +- src/H5Obogus.c | 5 +- src/H5Ocache.c | 146 +++--- src/H5Ocont.c | 5 +- src/H5Odtype.c | 62 ++- src/H5Oefl.c | 5 +- src/H5Ofill.c | 10 +- src/H5Oginfo.c | 5 +- src/H5Olayout.c | 49 +- src/H5Olinfo.c | 5 +- src/H5Olink.c | 5 +- src/H5Omtime.c | 10 +- src/H5Oname.c | 5 +- src/H5Onull.c | 5 +- src/H5Opkg.h | 180 +++---- src/H5Opline.c | 5 +- src/H5Oprivate.h | 8 +- src/H5Osdspace.c | 7 +- src/H5Oshared.c | 7 +- src/H5Ostab.c | 5 +- src/H5T.c | 34 -- src/H5Toh.c | 95 ++++ src/H5Tprivate.h | 4 +- src/H5Tvlen.c | 1 + src/H5private.h | 2 +- src/Makefile.am | 9 +- src/Makefile.in | 63 +-- test/objcopy.c | 1169 +++++++++++++++++++++++++++++++++++++++---- 44 files changed, 2649 insertions(+), 1101 deletions(-) create mode 100644 src/H5Doh.c create mode 100644 src/H5Goh.c create mode 100644 src/H5Toh.c diff --git a/MANIFEST b/MANIFEST index 226e61d..1ccf7da 100644 --- a/MANIFEST +++ b/MANIFEST @@ -435,6 +435,7 @@ ./src/H5Dio.c ./src/H5Distore.c ./src/H5Dmpio.c +./src/H5Doh.c ./src/H5Dpkg.h ./src/H5Dprivate.h ./src/H5Dpublic.h @@ -498,6 +499,7 @@ ./src/H5Gname.c ./src/H5Gnode.c ./src/H5Gobj.c +./src/H5Goh.c ./src/H5Gpkg.h ./src/H5Gprivate.h ./src/H5Gpublic.h @@ -605,6 +607,7 @@ ./src/H5Toffset.c ./src/H5Topaque.c ./src/H5Torder.c +./src/H5Toh.c ./src/H5Tpad.c ./src/H5Tpkg.h ./src/H5Tprecis.c diff --git a/fortran/src/H5Rff.f90 b/fortran/src/H5Rff.f90 index 08c85df..a41f8dc 100644 --- a/fortran/src/H5Rff.f90 +++ b/fortran/src/H5Rff.f90 @@ -410,10 +410,10 @@ ! Outputs: ! obj_type - object_type, possible values: ! H5G_UNKNOWN_F (-1) -! H5G_LINK_F 0 -! H5G_GROUP_F 1 -! H5G_DATASET_F 2 -! H5G_TYPE_F 3 +! H5G_GROUP_F 0 +! H5G_DATASET_F 1 +! H5G_TYPE_F 2 +! H5G_LINK_F 3 ! ! hdferr: - error code ! Success: 0 @@ -445,10 +445,10 @@ TYPE(hobj_ref_t_f), INTENT(IN) :: ref ! Object reference INTEGER, INTENT(OUT) :: obj_type ! Object type ! H5G_UNKNOWN_F (-1) - ! H5G_LINK_F 0 - ! H5G_GROUP_F 1 - ! H5G_DATASET_F 2 - ! H5G_TYPE_F 3 + ! H5G_GROUP_F 0 + ! H5G_DATASET_F 1 + ! H5G_TYPE_F 2 + ! H5G_LINK_F 3 INTEGER, INTENT(OUT) :: hdferr ! Error code INTEGER(HADDR_T) :: ref_f ! Local buffer to pass reference diff --git a/fortran/src/H5_f.c b/fortran/src/H5_f.c index 0e5c4cb..1543e18 100644 --- a/fortran/src/H5_f.c +++ b/fortran/src/H5_f.c @@ -298,10 +298,10 @@ nh5init_flags_c( int_f *h5d_flags, int_f *h5f_flags, */ h5g_flags[0] = H5G_UNKNOWN; - h5g_flags[1] = H5G_LINK; - h5g_flags[2] = H5G_GROUP; - h5g_flags[3] = H5G_DATASET; - h5g_flags[4] = H5G_TYPE; + h5g_flags[1] = H5G_GROUP; + h5g_flags[2] = H5G_DATASET; + h5g_flags[3] = H5G_TYPE; + h5g_flags[4] = H5G_LINK; h5g_flags[5] = H5G_LINK_ERROR; h5g_flags[6] = H5G_LINK_HARD; h5g_flags[7] = H5G_LINK_SOFT; diff --git a/fortran/src/H5f90global.f90 b/fortran/src/H5f90global.f90 index ebd3c93..9503e97 100644 --- a/fortran/src/H5f90global.f90 +++ b/fortran/src/H5f90global.f90 @@ -201,19 +201,19 @@ COMMON /H5G_FLAGS/ H5G_flags INTEGER :: H5G_UNKNOWN_F - INTEGER :: H5G_LINK_F INTEGER :: H5G_GROUP_F INTEGER :: H5G_DATASET_F INTEGER :: H5G_TYPE_F + INTEGER :: H5G_LINK_F INTEGER :: H5G_LINK_ERROR_F INTEGER :: H5G_LINK_HARD_F INTEGER :: H5G_LINK_SOFT_F EQUIVALENCE(H5G_flags(1), H5G_UNKNOWN_F) - EQUIVALENCE(H5G_flags(2), H5G_LINK_F) - EQUIVALENCE(H5G_flags(3), H5G_GROUP_F) - EQUIVALENCE(H5G_flags(4), H5G_DATASET_F) - EQUIVALENCE(H5G_flags(5), H5G_TYPE_F) + EQUIVALENCE(H5G_flags(2), H5G_GROUP_F) + EQUIVALENCE(H5G_flags(3), H5G_DATASET_F) + EQUIVALENCE(H5G_flags(4), H5G_TYPE_F) + EQUIVALENCE(H5G_flags(5), H5G_LINK_F) EQUIVALENCE(H5G_flags(6), H5G_LINK_ERROR_F) EQUIVALENCE(H5G_flags(7), H5G_LINK_HARD_F) EQUIVALENCE(H5G_flags(8), H5G_LINK_SOFT_F) diff --git a/fortran/test/tH5R.f90 b/fortran/test/tH5R.f90 index d4f2911..7daabc6 100644 --- a/fortran/test/tH5R.f90 +++ b/fortran/test/tH5R.f90 @@ -158,7 +158,7 @@ ! CALL h5rget_object_type_f(dsetr_id, ref(3), obj_type, error) CALL check("h5rget_object_type_f",error,total_error) - if (obj_type == 2) then + if (obj_type == H5G_DATASET_F) then CALL h5rdereference_f(dsetr_id, ref(3), dset1_id, error) CALL check("h5rdereference_f",error,total_error) @@ -172,7 +172,7 @@ ! CALL h5rget_object_type_f(dsetr_id, ref(4), obj_type, error) CALL check("h5rget_object_type_f",error,total_error) - if (obj_type == 3) then + if (obj_type == H5G_TYPE_F) then CALL h5rdereference_f(dsetr_id, ref(4), type_id, error) CALL check("h5rdereference_f",error,total_error) end if diff --git a/src/H5.c b/src/H5.c index 00bcc38..0476dbb 100644 --- a/src/H5.c +++ b/src/H5.c @@ -221,9 +221,6 @@ 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/H5D.c b/src/H5D.c index df24bab..2eeba41 100644 --- a/src/H5D.c +++ b/src/H5D.c @@ -68,6 +68,8 @@ 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); +static herr_t H5D_iterate(void *buf, hid_t type_id, H5S_t *space, + H5D_operator_t op, void *operator_data); static herr_t H5D_extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id); static herr_t H5D_set_extent(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id); static herr_t H5D_init_type(H5F_t *file, const H5D_t *dset, hid_t type_id, const H5T_t *type); @@ -2350,50 +2352,6 @@ done: } /* end H5D_create() */ -/*------------------------------------------------------------------------- - * Function: H5D_isa - * - * Purpose: Determines if an object has the requisite messages for being - * a dataset. - * - * Return: Success: TRUE if the required dataset messages are - * present; FALSE otherwise. - * - * Failure: FAIL if the existence of certain messages - * cannot be determined. - * - * Programmer: Robb Matzke - * Monday, November 2, 1998 - * - *------------------------------------------------------------------------- - */ -htri_t -H5D_isa(H5O_loc_t *loc, hid_t dxpl_id) -{ - htri_t exists; - htri_t ret_value = TRUE; /* Return value */ - - FUNC_ENTER_NOAPI(H5D_isa, FAIL) - - HDassert(loc); - - /* 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) - HGOTO_DONE(FALSE) - - /* Layout */ - 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) - HGOTO_DONE(FALSE) - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5D_isa() */ - - /* *------------------------------------------------------------------------- * Function: H5D_open @@ -3548,7 +3506,7 @@ H5Diterate(void *buf, hid_t type_id, hid_t space_id, H5D_operator_t op, 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 = H5D_iterate(buf, type_id, space, op, operator_data); done: FUNC_LEAVE_API(ret_value) @@ -3556,6 +3514,41 @@ done: /*------------------------------------------------------------------------- + * Function: H5D_iterate + * + * Purpose: Internal version of H5Diterate() + * + * Return: Returns the return value of the last operator if it was non-zero, + * or zero if all elements were processed. Otherwise returns a + * negative value. + * + * Programmer: Quincey Koziol + * Tuesday, November 22, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5D_iterate(void *buf, hid_t type_id, H5S_t *space, H5D_operator_t op, + void *operator_data) +{ + herr_t ret_value; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5D_iterate) + + /* Check args */ + HDassert(buf); + HDassert(H5I_DATATYPE == H5I_get_type(type_id)); + HDassert(space); + HDassert(H5S_has_extent(space)); + HDassert(op); + + ret_value = H5S_select_iterate(buf, type_id, space, op, operator_data); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_iterate() */ + + +/*------------------------------------------------------------------------- * Function: H5Dvlen_reclaim * * Purpose: Frees the buffers allocated for storing variable-length data @@ -3573,35 +3566,75 @@ done: herr_t H5Dvlen_reclaim(hid_t type_id, hid_t space_id, hid_t plist_id, void *buf) { - H5T_vlen_alloc_info_t _vl_alloc_info; /* VL allocation info buffer */ - H5T_vlen_alloc_info_t *vl_alloc_info=&_vl_alloc_info; /* VL allocation info */ + H5S_t *space = NULL; herr_t ret_value; FUNC_ENTER_API(H5Dvlen_reclaim, FAIL) H5TRACE4("e","iiix",type_id,space_id,plist_id,buf); /* Check args */ - if (H5I_DATATYPE!=H5I_get_type(type_id) || H5I_DATASPACE!=H5I_get_type(space_id) || - buf==NULL) + if (H5I_DATATYPE != H5I_get_type(type_id) || buf == NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") + if(NULL == (space = H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace") + if(!(H5S_has_extent(space))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set") /* Get the default dataset transfer property list if the user didn't provide one */ - if (H5P_DEFAULT == plist_id) - plist_id= H5P_DATASET_XFER_DEFAULT; + 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") + /* Call internal routine */ + ret_value = H5D_vlen_reclaim(type_id, space, plist_id, buf); + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Dvlen_reclaim() */ + + +/*------------------------------------------------------------------------- + * Function: H5D_vlen_reclaim + * + * Purpose: Frees the buffers allocated for storing variable-length data + * in memory. Only frees the VL data in the selection defined in the + * dataspace. The dataset transfer property list is required to find the + * correct allocation/free methods for the VL data in the buffer. + * + * Return: Non-negative on success, negative on failure + * + * Programmer: Quincey Koziol + * Tuesday, November 22, 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id, void *buf) +{ + H5T_vlen_alloc_info_t _vl_alloc_info; /* VL allocation info buffer */ + H5T_vlen_alloc_info_t *vl_alloc_info = &_vl_alloc_info; /* VL allocation info */ + herr_t ret_value; + + FUNC_ENTER_NOAPI(H5D_vlen_reclaim, FAIL) + + /* Check args */ + HDassert(H5I_DATATYPE == H5I_get_type(type_id)); + HDassert(space); + HDassert(H5P_isa_class(plist_id, H5P_DATASET_XFER)); + HDassert(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") - /* Call H5Diterate with args, etc. */ - ret_value=H5Diterate(buf,type_id,space_id,H5T_vlen_reclaim,vl_alloc_info); + /* Call H5D_iterate with args, etc. */ + ret_value = H5D_iterate(buf, type_id, space ,H5T_vlen_reclaim, vl_alloc_info); done: - FUNC_LEAVE_API(ret_value) -} /* end H5Dvlen_reclaim() */ + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_vlen_reclaim() */ /*------------------------------------------------------------------------- @@ -3728,6 +3761,7 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, { H5D_vlen_bufsize_t vlen_bufsize = {0, 0, 0, 0, 0, 0, 0}; char bogus; /* bogus value to pass to H5Diterate() */ + H5S_t *space = NULL; H5P_genclass_t *pclass; /* Property class */ H5P_genplist_t *plist; /* Property list */ herr_t ret_value=FAIL; @@ -3736,10 +3770,13 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, H5TRACE4("e","iii*h",dataset_id,type_id,space_id,size); /* Check args */ - if (H5I_DATASET!=H5I_get_type(dataset_id) || - H5I_DATATYPE!=H5I_get_type(type_id) || - H5I_DATASPACE!=H5I_get_type(space_id) || size==NULL) + if(H5I_DATASET!=H5I_get_type(dataset_id) || + H5I_DATATYPE!=H5I_get_type(type_id) || size==NULL) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument") + if(NULL == (space = H5I_object_verify(space_id, H5I_DATASPACE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace") + if(!(H5S_has_extent(space))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set") /* Save the dataset ID */ vlen_bufsize.dataset_id=dataset_id; @@ -3777,8 +3814,8 @@ H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id, /* Set the initial number of bytes required */ vlen_bufsize.size=0; - /* Call H5Diterate with args, etc. */ - ret_value=H5Diterate(&bogus,type_id,space_id,H5D_vlen_get_buf_size,&vlen_bufsize); + /* Call H5D_iterate with args, etc. */ + ret_value = H5D_iterate(&bogus, type_id, space, H5D_vlen_get_buf_size, &vlen_bufsize); /* Get the size if we succeeded */ if(ret_value>=0) diff --git a/src/H5Dcontig.c b/src/H5Dcontig.c index fd05e8c..bed70d7 100644 --- a/src/H5Dcontig.c +++ b/src/H5Dcontig.c @@ -38,6 +38,7 @@ #include "H5Fprivate.h" /* Files */ #include "H5FDprivate.h" /* File drivers */ #include "H5FLprivate.h" /* Free Lists */ +#include "H5Iprivate.h" /* IDs */ #include "H5MFprivate.h" /* File memory management */ #include "H5Oprivate.h" /* Object headers */ #include "H5Pprivate.h" /* Property lists */ @@ -75,6 +76,9 @@ H5FL_BLK_DEFINE_STATIC(non_zero_fill); /* Declare the free list to manage blocks of zero fill-value data */ H5FL_BLK_DEFINE_STATIC(zero_fill); +/* Declare extern the free list to manage blocks of type conversion data */ +H5FL_BLK_EXTERN(type_conv); + /*------------------------------------------------------------------------- * Function: H5D_contig_create @@ -130,7 +134,7 @@ H5D_contig_fill(H5D_t *dset, hid_t dxpl_id) size_t npoints; /* Number of points in space */ size_t ptsperbuf; /* Maximum # of points which fit in the buffer */ size_t elmt_size; /* Size of each element */ - size_t bufsize=64*1024; /* Size of buffer to write */ + size_t bufsize=H5D_XFER_MAX_TEMP_BUF_DEF; /* Size of buffer to write */ size_t size; /* Current # of points to write */ hsize_t offset; /* Offset of dataset */ void *buf = NULL; /* Buffer for fill value writing */ @@ -976,3 +980,210 @@ done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5D_contig_writevv() */ + +/*------------------------------------------------------------------------- + * Function: H5D_contig_copy + * + * Purpose: Copy contiguous storage raw data from SRC file to DST file. + * + * Return: Non-negative on success, negative on failure. + * + * Programmer: Quincey Koziol + * Monday, November 21, 2005 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, + H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *dt_src, hid_t dxpl_id) +{ + haddr_t addr_src; /* File offset in source dataset */ + haddr_t addr_dst; /* File offset in destination dataset */ + H5T_path_t *tpath_src_mem = NULL, *tpath_mem_dst = NULL; /* Datatype conversion paths */ + H5T_t *dt_dst = NULL; /* Destination datatype */ + H5T_t *dt_mem = NULL; /* Memory datatype */ + hid_t tid_src = -1; /* Datatype ID for source datatype */ + hid_t tid_dst = -1; /* Datatype ID for destination datatype */ + hid_t tid_mem = -1; /* Datatype ID for memory datatype */ + size_t max_dt_size; /* Max. datatype size */ + size_t nelmts = 0; /* Number of elements in buffer */ + hsize_t total_nbytes; /* Total number of bytes to copy */ + size_t buf_size; /* Size of copy buffer */ + void *buf = NULL; /* Buffer for copying data */ + void *reclaim_buf = NULL; /* Buffer for reclaiming data */ + H5S_t *buf_space = NULL; /* Dataspace describing buffer */ + hid_t buf_sid = -1; /* ID for buffer dataspace */ + hsize_t buf_dim; /* Dimension for buffer */ + hbool_t do_conv; /* Flag to indicate that type conversion should occur */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5D_contig_copy, FAIL) + + /* Check args */ + HDassert(f_src); + HDassert(f_dst); + HDassert(layout_src && H5D_CONTIGUOUS == layout_src->type); + HDassert(layout_dst && H5D_CONTIGUOUS == layout_dst->type); + + /* Allocate space for destination raw data */ + if(H5D_contig_create(f_dst, dxpl_id, layout_dst) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTINIT, FAIL, "unable to allocate contiguous storage") + + /* Set up number of bytes to copy, and initial buffer size */ + total_nbytes = layout_src->u.contig.size; + buf_size = MIN(H5D_XFER_MAX_TEMP_BUF_DEF, total_nbytes); + + /* If there's a source datatype, set up type conversion information */ + if(dt_src) { + size_t tmp_dt_size; /* Temp. atatype size */ + + /* Create datatype ID for src datatype */ + if((tid_src = H5I_register(H5I_DATATYPE, dt_src)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register source file datatype") + + /* create a memory copy of the variable-length datatype */ + if(NULL == (dt_mem = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") + if((tid_mem = H5I_register(H5I_DATATYPE, dt_mem)) < 0) + HGOTO_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register memory datatype") + + /* create variable-length datatype at the destinaton file */ + if(NULL == (dt_dst = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") + if(H5T_set_loc(dt_dst, f_dst, H5T_LOC_DISK) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk") + if((tid_dst = H5I_register(H5I_DATATYPE, dt_dst)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register destination file datatype") + + /* Set up the conversion functions */ + if(NULL == (tpath_src_mem = H5T_path_find(dt_src, dt_mem, NULL, NULL, dxpl_id, FALSE))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and mem datatypes") + if(NULL == (tpath_mem_dst = H5T_path_find(dt_mem, dt_dst, NULL, NULL, dxpl_id, FALSE))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between mem and dst datatypes") + + /* Determine largest datatype size */ + if(0 == (max_dt_size = H5T_get_size(dt_src))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size") + if(0 == (tmp_dt_size = H5T_get_size(dt_mem))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size") + max_dt_size = MAX(max_dt_size, tmp_dt_size); + if(0 == (tmp_dt_size = H5T_get_size(dt_dst))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to determine datatype size") + max_dt_size = MAX(max_dt_size, tmp_dt_size); + + /* Set number of whole elements that fit in buffer */ + if(0 == (nelmts = buf_size / max_dt_size)) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "element size too large") + + /* Adjust buffer size to be multiple of elements */ + buf_size = nelmts * max_dt_size; + + /* Create dataspace for number of elements in buffer */ + buf_dim = nelmts; + + /* Create the space and set the initial extent */ + if(NULL == (buf_space = H5S_create_simple((unsigned)1, &buf_dim, NULL))) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create simple dataspace") + + /* Atomize */ + if((buf_sid = H5I_register(H5I_DATASPACE, buf_space)) < 0) { + H5S_close(buf_space); + HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace ID") + } /* end if */ + + /* Set flag to do type conversion */ + do_conv = TRUE; + } /* end if */ + else + /* Type conversion not necessary */ + do_conv = FALSE; + + /* Allocate space for copy buffer */ + HDassert(buf_size); + if(NULL == (buf = H5FL_BLK_MALLOC(type_conv, buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer") + + /* Need extra buffer for datatype conversions, to prevent stranding/leaking memory */ + if(do_conv) { + if(NULL == (reclaim_buf = H5FL_BLK_MALLOC(type_conv, buf_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for copy buffer") + } /* end if */ + + /* Loop over copying data */ + addr_src = layout_src->u.contig.addr; + addr_dst = layout_dst->u.contig.addr; + while(total_nbytes > 0) { + size_t nbytes; /* Number of bytes to copy each time */ + + /* Compute number of bytes to copy for this pass */ + if(total_nbytes >= buf_size) + nbytes = buf_size; + else { + nbytes = (size_t)total_nbytes; + + /* Adjust dataspace describing buffer */ + if(do_conv) { + /* Adjust size of buffer's dataspace dimension */ + buf_dim = nelmts = nbytes / max_dt_size; + + /* Adjust size of buffer's dataspace */ + if(H5S_set_extent_real(buf_space, &buf_dim) < 0) + HGOTO_ERROR(H5E_DATASPACE, H5E_CANTSET, FAIL, "unable to change buffer dataspace size") + } /* end if */ + } /* end else */ + + /* Read raw data from source file */ + if(H5F_block_read(f_src, H5FD_MEM_DRAW, addr_src, nbytes, H5P_DATASET_XFER_DEFAULT, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_READERROR, FAIL, "unable to read raw data") + + /* Perform datatype conversion, if necessary */ + if(do_conv) { + /* Convert from source file to memory */ + if(H5T_convert(tpath_src_mem, tid_src, tid_mem, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed") + + /* Copy into another buffer, to reclaim memory later */ + HDmemcpy(reclaim_buf, buf, nbytes); + + /* Convert from memory to destination file */ + if(H5T_convert(tpath_mem_dst, tid_mem, tid_dst, nelmts, (size_t)0, (size_t)0, buf, NULL, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "datatype conversion failed") + } /* end if */ + + /* Write raw data to destination file */ + if(H5F_block_write(f_dst, H5FD_MEM_DRAW, addr_dst, nbytes, H5P_DATASET_XFER_DEFAULT, buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_WRITEERROR, FAIL, "unable to write raw data") + + /* Reclaim any space from variable length data */ + if(do_conv) { + if(H5D_vlen_reclaim(tid_mem, buf_space, H5P_DATASET_XFER_DEFAULT, reclaim_buf) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_BADITER, FAIL, "unable to reclaim variable-length data") + } /* end if */ + + /* Adjust loop variables */ + addr_src += nbytes; + addr_dst += nbytes; + total_nbytes -= nbytes; + } /* end while */ + +done: + if(buf_sid > 0) + if(H5I_dec_ref(buf_sid) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary dataspace ID") + if(tid_src > 0) + if(H5I_dec_ref(tid_src) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID") + if(tid_dst > 0) + if(H5I_dec_ref(tid_dst) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID") + if(tid_mem > 0) + if(H5I_dec_ref(tid_mem) < 0) + HDONE_ERROR(H5E_DATASET, H5E_CANTFREE, FAIL, "Can't decrement temporary datatype ID") + if(buf) + H5FL_BLK_FREE(type_conv, buf); + if(reclaim_buf) + H5FL_BLK_FREE(type_conv, reclaim_buf); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_contig_copy() */ + diff --git a/src/H5Doh.c b/src/H5Doh.c new file mode 100644 index 0000000..f9f9249 --- /dev/null +++ b/src/H5Doh.c @@ -0,0 +1,176 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5O_PACKAGE /*suppress error about including H5Opkg */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5FLprivate.h" /* Free lists */ +#include "H5Opkg.h" /* Object headers */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ + +/********************/ +/* Local Prototypes */ +/********************/ +static htri_t H5O_dset_isa(H5O_t *loc); +static void *H5O_dset_get_copy_file_udata(void); +static void H5O_dset_free_copy_file_udata(void *); + +/*********************/ +/* Package Variables */ +/*********************/ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/*******************/ +/* Local Variables */ +/*******************/ + +/* This message derives from H5O object class */ +const H5O_obj_class_t H5O_OBJ_DATASET[1] = {{ + H5G_DATASET, /* object type */ + "dataset", /* object name, for debugging */ + H5O_dset_get_copy_file_udata, /* get 'copy file' user data */ + H5O_dset_free_copy_file_udata, /* free 'copy file' user data */ + H5O_dset_isa /* "isa" message */ +}}; + +/* Declare a free list to manage the H5D_copy_file_ud_t struct */ +H5FL_DEFINE(H5D_copy_file_ud_t); + + +/*------------------------------------------------------------------------- + * Function: H5O_dset_isa + * + * Purpose: Determines if an object has the requisite messages for being + * a dataset. + * + * Return: Success: TRUE if the required dataset messages are + * present; FALSE otherwise. + * + * Failure: FAIL if the existence of certain messages + * cannot be determined. + * + * Programmer: Robb Matzke + * Monday, November 2, 1998 + * + *------------------------------------------------------------------------- + */ +htri_t +H5O_dset_isa(H5O_t *oh) +{ + htri_t exists; /* Flag if header message of interest exists */ + htri_t ret_value = TRUE; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_dset_isa, FAIL) + + HDassert(oh); + + /* Datatype */ + if((exists = H5O_exists_oh(oh, H5O_DTYPE_ID, 0)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read object header") + else if(!exists) + HGOTO_DONE(FALSE) + + /* Layout */ + if((exists = H5O_exists_oh(oh, H5O_SDSPACE_ID, 0)) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to read object header") + else if(!exists) + HGOTO_DONE(FALSE) + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_dset_isa() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_dset_get_copy_file_udata + * + * Purpose: Allocates the user data needed for copying a dataset's + * object header from file to file. + * + * Return: Success: Non-NULL pointer to user data + * + * Failure: NULL + * + * Programmer: Quincey Koziol + * Monday, November 21, 2005 + * + *------------------------------------------------------------------------- + */ +static void * +H5O_dset_get_copy_file_udata(void) +{ + void *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_dset_get_copy_file_udata) + + /* Allocate space for the 'copy file' user data for copying datasets */ + if(NULL == (ret_value = H5FL_CALLOC(H5D_copy_file_ud_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_dset_get_copy_file_udata() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_dset_free_copy_file_udata + * + * Purpose: Release the user data needed for copying a dataset's + * object header from file to file. + * + * Return: + * + * Programmer: Quincey Koziol + * Monday, November 21, 2005 + * + *------------------------------------------------------------------------- + */ +static void +H5O_dset_free_copy_file_udata(void *_udata) +{ + H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_dset_free_copy_file_udata) + + /* Sanity check */ + HDassert(udata); + + /* Release copy of dataset's datatype, if it was set */ + if(udata->src_dtype) + H5T_close(udata->src_dtype); + + /* Release space for 'copy file' user data */ + H5FL_FREE(H5D_copy_file_ud_t, udata); + + FUNC_LEAVE_NOAPI_VOID +} /* end H5O_dset_free_copy_file_udata() */ + diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 5ce0bbd..9b73d86 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -198,6 +198,8 @@ extern H5D_dxpl_cache_t H5D_def_dxpl_cache; H5_DLL herr_t H5D_alloc_storage (H5F_t *f, hid_t dxpl_id, H5D_t *dset, H5D_time_alloc_t time_alloc, hbool_t update_time, hbool_t full_overwrite); +H5_DLL herr_t H5D_vlen_reclaim(hid_t type_id, H5S_t *space, hid_t plist_id, + void *buf); /* Functions that perform serial I/O operations */ H5_DLL herr_t H5D_select_fscat (H5D_io_info_t *io_info, @@ -233,6 +235,8 @@ H5_DLL ssize_t H5D_contig_writevv(const H5D_io_info_t *io_info, size_t dset_max_nseq, size_t *dset_curr_seq, size_t dset_len_arr[], hsize_t dset_offset_arr[], size_t mem_max_nseq, size_t *mem_curr_seq, size_t mem_len_arr[], hsize_t mem_offset_arr[], const void *buf); +H5_DLL herr_t H5D_contig_copy(H5F_t *f_src, H5O_layout_t *layout_src, + H5F_t *f_dst, H5O_layout_t *layout_dst, H5T_t *src_dtype, hid_t dxpl_id); /* Functions that operate on compact dataset storage */ H5_DLL ssize_t H5D_compact_readvv(const H5D_io_info_t *io_info, @@ -300,7 +304,6 @@ H5_DLL herr_t H5D_mpio_select_write(H5D_io_info_t *io_info, const struct H5S_t *file_space, const struct H5S_t *mem_space, const void *buf); - /* MPI-IO function to read directly from app buffer to file rky980813 */ H5_DLL herr_t H5D_mpio_spaces_read(H5D_io_info_t *io_info, size_t nelmts, size_t elmt_size, diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h index a9367dc..d762abc 100644 --- a/src/H5Dprivate.h +++ b/src/H5Dprivate.h @@ -223,7 +223,6 @@ typedef struct H5D_dcpl_cache_t { H5_DLL herr_t H5D_init(void); 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(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); diff --git a/src/H5G.c b/src/H5G.c index 76e44e0..fdba6e6 100644 --- a/src/H5G.c +++ b/src/H5G.c @@ -1526,47 +1526,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5G_isa - * - * Purpose: Determines if an object has the requisite messages for being - * a group. - * - * Return: Success: TRUE if the required group messages are - * present; FALSE otherwise. - * - * Failure: FAIL if the existence of certain messages - * cannot be determined. - * - * Programmer: Robb Matzke - * Monday, November 2, 1998 - * - *------------------------------------------------------------------------- - */ -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) - - HDassert(loc); - - /* 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") - - ret_value = (stab_exists > 0 || linfo_exists > 0); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5G_isa() */ - - -/*------------------------------------------------------------------------- * Function: H5G_open * * Purpose: Opens an existing group. The group should eventually be diff --git a/src/H5Goh.c b/src/H5Goh.c new file mode 100644 index 0000000..c51a493 --- /dev/null +++ b/src/H5Goh.c @@ -0,0 +1,102 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5O_PACKAGE /*suppress error about including H5Opkg */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Opkg.h" /* Object headers */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ + +/********************/ +/* Local Prototypes */ +/********************/ +static htri_t H5O_group_isa(H5O_t *loc); + +/*********************/ +/* Package Variables */ +/*********************/ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/*******************/ +/* Local Variables */ +/*******************/ + +/* This message derives from H5O object class */ +const H5O_obj_class_t H5O_OBJ_GROUP[1] = {{ + H5G_GROUP, /* object type */ + "group", /* object name, for debugging */ + NULL, /* get 'copy file' user data */ + NULL, /* free 'copy file' user data */ + H5O_group_isa /* "isa" message */ +}}; + + +/*------------------------------------------------------------------------- + * Function: H5O_group_isa + * + * Purpose: Determines if an object has the requisite messages for being + * a group. + * + * Return: Success: TRUE if the required group messages are + * present; FALSE otherwise. + * + * Failure: FAIL if the existence of certain messages + * cannot be determined. + * + * Programmer: Robb Matzke + * Monday, November 2, 1998 + * + *------------------------------------------------------------------------- + */ +htri_t +H5O_group_isa(struct H5O_t *oh) +{ + htri_t stab_exists; /* Whether the 'stab' message is in the object header */ + htri_t linfo_exists; /* Whether the 'linfo' message is in the object header */ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_group_isa) + + HDassert(oh); + + /* Check for any of the messages that indicate a group */ + if((stab_exists = H5O_exists_oh(oh, H5O_STAB_ID, 0)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") + if((linfo_exists = H5O_exists_oh(oh, H5O_LINFO_ID, 0)) < 0) + HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header") + + ret_value = (stab_exists > 0 || linfo_exists > 0); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_group_isa() */ + diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h index b902f98..fdec753 100644 --- a/src/H5Gprivate.h +++ b/src/H5Gprivate.h @@ -94,9 +94,10 @@ typedef struct { unsigned user_path_hidden; /* Whether the user's path is valid */ } H5G_name_t; -/* Forward declarations */ +/* Forward declarations (for prototypes & struct definitions) */ struct H5P_genplist_t; struct H5O_loc_t; +struct H5O_t; /* * The "location" of an object in a group hierarchy. This points to an object @@ -122,7 +123,6 @@ typedef enum { * Library prototypes... These are the ones that other packages routinely * call. */ -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); diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h index f906a84..801b7c3 100644 --- a/src/H5Gpublic.h +++ b/src/H5Gpublic.h @@ -54,10 +54,10 @@ typedef enum H5G_link_t { */ typedef enum H5G_obj_t { H5G_UNKNOWN = -1, /* Unknown object type */ - H5G_LINK, /* Object is a symbolic link */ H5G_GROUP, /* Object is a group */ H5G_DATASET, /* Object is a dataset */ H5G_TYPE, /* Object is a named data type */ + H5G_LINK, /* Object is a symbolic link */ H5G_RESERVED_4, /* Reserved for future use */ H5G_RESERVED_5, /* Reserved for future use */ H5G_RESERVED_6, /* Reserved for future use */ diff --git a/src/H5O.c b/src/H5O.c index 0f2ae87..b047bdd 100644 --- a/src/H5O.c +++ b/src/H5O.c @@ -26,9 +26,6 @@ #define H5F_PACKAGE /*suppress error about including H5Fpkg */ #define H5O_PACKAGE /*suppress error about including H5Opkg */ -/* Interface initialization */ -#define H5_INTERFACE_INIT_FUNC H5O_init_interface - #include "H5private.h" /* Generic Functions */ #include "H5Dprivate.h" /* Datasets */ @@ -47,20 +44,20 @@ /* 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) \ +#define LOAD_NATIVE(F, DXPL, MSG, ERR) \ if(NULL == (MSG)->native) { \ - const H5O_class_t *decode_type; \ + const H5O_msg_class_t *decode_type; \ \ /* Check for shared message */ \ if ((MSG)->flags & H5O_FLAG_SHARED) \ - decode_type = H5O_SHARED; \ + decode_type = H5O_MSG_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") \ + HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, ERR, "unable to decode message") \ } /* end if */ /* Private typedefs */ @@ -87,7 +84,7 @@ typedef herr_t (*H5O_operator_int_t)(H5O_mesg_t *mesg/*in,out*/, unsigned idx, */ 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 */ + htri_t (*isa)(H5O_t*); /*function to determine type */ char *desc; /*description of object type */ } H5O_typeinfo_t; @@ -101,31 +98,43 @@ typedef struct 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 */ +/* Header message ID to class mapping */ +const H5O_msg_class_t *const H5O_msg_class_g[] = { + H5O_MSG_NULL, /*0x0000 Null */ + H5O_MSG_SDSPACE, /*0x0001 Simple Dimensionality */ + H5O_MSG_LINFO, /*0x0002 Link information */ + H5O_MSG_DTYPE, /*0x0003 Data Type */ + H5O_MSG_FILL, /*0x0004 Old data storage -- fill value */ + H5O_MSG_FILL_NEW, /*0x0005 New Data storage -- fill value */ + H5O_MSG_LINK, /*0x0006 Link */ + H5O_MSG_EFL, /*0x0007 Data storage -- external data files */ + H5O_MSG_LAYOUT, /*0x0008 Data Layout */ #ifdef H5O_ENABLE_BOGUS - H5O_BOGUS, /*0x0009 "Bogus" */ + H5O_MSG_BOGUS, /*0x0009 "Bogus" */ #else /* H5O_ENABLE_BOGUS */ - NULL, /*0x0009 "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 */ + H5O_MSG_GINFO, /*0x000A Group Information */ + H5O_MSG_PLINE, /*0x000B Data storage -- filter pipeline */ + H5O_MSG_ATTR, /*0x000C Attribute list */ + H5O_MSG_NAME, /*0x000D Object name */ + H5O_MSG_MTIME, /*0x000E Object modification date and time */ + H5O_MSG_SHARED, /*0x000F Shared header message */ + H5O_MSG_CONT, /*0x0010 Object header continuation */ + H5O_MSG_STAB, /*0x0011 Symbol table */ + H5O_MSG_MTIME_NEW, /*0x0012 New Object modification date and time */ +}; + +/* Header object ID to class mapping */ +/* + * Initialize the object class info table. Begin with the most general types + * and end with the most specific. For instance, any object that has a + * datatype message is a datatype but only some of them are datasets. + */ +const H5O_obj_class_t *const H5O_obj_class_g[] = { + H5O_OBJ_DATATYPE, /* Datatype object (H5G_TYPE - 2) */ + H5O_OBJ_DATASET, /* Dataset object (H5G_DATASET - 1) */ + H5O_OBJ_GROUP, /* Group object (H5G_GROUP - 0) */ }; /* Declare a free list to manage the H5O_t struct */ @@ -143,9 +152,6 @@ 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); @@ -157,33 +163,30 @@ H5FL_EXTERN(H5O_cont_t); H5FL_DEFINE_STATIC(H5O_addr_map_t); /* PRIVATE PROTOTYPES */ -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 void * H5O_copy_real(const H5O_class_t *type, const void *mesg, +static herr_t H5O_reset_real(const H5O_msg_class_t *type, void *native); +static void * H5O_copy_real(const H5O_msg_class_t *type, const void *mesg, void *dst); -static int H5O_count_real(H5O_loc_t *loc, const H5O_class_t *type, +static int H5O_count_real(H5O_loc_t *loc, const H5O_msg_class_t *type, 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, +static herr_t H5O_share(H5F_t *f, hid_t dxpl_id, const H5O_msg_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(H5O_loc_t *loc, const H5O_class_t *type, + const H5O_msg_class_t **type_p, int sequence); +static int H5O_modify_real(H5O_loc_t *loc, const H5O_msg_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, + const H5O_msg_class_t *type, unsigned flags, const void *mesg, unsigned * oh_flags_ptr); -static herr_t H5O_remove_real(const H5O_loc_t *loc, const H5O_class_t *type, +static herr_t H5O_remove_real(const H5O_loc_t *loc, const H5O_msg_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); + const H5O_msg_class_t *type, size_t size, hbool_t * oh_dirtied_ptr); +static herr_t H5O_alloc_msgs(H5O_t *oh, size_t min_alloc); 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); @@ -196,15 +199,17 @@ static herr_t H5O_delete_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh); static herr_t H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link); static unsigned H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, - const H5O_class_t *orig_type, const void *orig_mesg, H5O_shared_t *sh_mesg, - const H5O_class_t **new_type, const void **new_mesg, hid_t dxpl_id, + const H5O_msg_class_t *orig_type, const void *orig_mesg, H5O_shared_t *sh_mesg, + const H5O_msg_class_t **new_type, const void **new_mesg, hid_t dxpl_id, unsigned * oh_flags_ptr); -static herr_t H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type, +static herr_t H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_msg_class_t *type, const void *mesg, unsigned flags, unsigned update_flags, unsigned * oh_flags_ptr); -static herr_t H5O_iterate_real(const H5O_loc_t *loc, const H5O_class_t *type, +static herr_t H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_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, +static H5G_obj_t H5O_obj_type_real(H5O_t *oh); +static const H5O_obj_class_t *H5O_obj_class(H5O_t *oh); +static void * H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src, void *mesg_src, H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata); static herr_t H5O_copy_header_real(const H5O_loc_t *oloc_src, H5O_loc_t *oloc_dst /*out */, hid_t dxpl_id, H5SL_t *map_list); @@ -212,178 +217,6 @@ static herr_t H5O_copy_free_addrmap_cb(void *item, void *key, void *op_data); /*------------------------------------------------------------------------- - * 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 */ - - FUNC_ENTER_NOAPI(H5O_init, FAIL) - /* FUNC_ENTER() does all the work */ - -done: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_init() */ - - -/*------------------------------------------------------------------------- - * 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 herr_t -H5O_init_interface(void) -{ - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_init_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. - */ - H5O_register_type(H5G_TYPE, H5T_isa, "datatype"); - H5O_register_type(H5G_GROUP, H5G_isa, "group"); - H5O_register_type(H5G_DATASET, H5D_isa, "dataset"); - - FUNC_LEAVE_NOAPI(SUCCEED) -} /* end H5O_init_interface() */ - - -/*------------------------------------------------------------------------- - * 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; - - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_term_interface) - - if(H5_interface_initialize_g) { - size_t u; - - /* 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); - - /* Mark closed */ - H5_interface_initialize_g = 0; - n = 1; /*H5O*/ - } /* end if */ - - FUNC_LEAVE_NOAPI(n) -} /* H5O_term_interface() */ - - -/*------------------------------------------------------------------------- - * Function: H5O_register_type - * - * 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: Success: Non-negative - * - * Failure: Negative - * - * Programmer: Quincey Koziol - * Monday, September 19, 2005 - * - *------------------------------------------------------------------------- - */ -static herr_t -H5O_register_type(H5G_obj_t type, htri_t(*isa)(H5O_loc_t *, hid_t), const char *_desc) -{ - 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") - - /* - * If the type is already registered then just update its entry without - * moving it to the end - */ - 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 */ - - /* 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() */ - - -/*------------------------------------------------------------------------- * Function: H5O_create * * Purpose: Creates a new object header. Allocates space for it and @@ -495,7 +328,7 @@ H5O_new(H5F_t *f, hid_t dxpl_id, size_t size_hint, H5O_loc_t *loc/*out*/, haddr_ 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].type = H5O_MSG_NULL; oh->mesg[0].dirty = TRUE; oh->mesg[0].native = NULL; oh->mesg[0].raw = oh->chunk[0].image + H5O_SIZEOF_MSGHDR(f); @@ -536,9 +369,7 @@ done: herr_t H5O_open(const H5O_loc_t *loc) { - herr_t ret_value = SUCCEED; /* Return value */ - - FUNC_ENTER_NOAPI(H5O_open, FAIL) + FUNC_ENTER_NOAPI_NOFUNC(H5O_open) /* Check args */ HDassert(loc); @@ -552,8 +383,7 @@ H5O_open(const H5O_loc_t *loc) /* Increment open-lock counters */ loc->file->nopen_objs++; -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5O_open() */ @@ -635,14 +465,14 @@ done: herr_t H5O_reset(unsigned type_id, void *native) { - const H5O_class_t *type; /* Actual H5O class type for the ID */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ herr_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_reset,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_id < NELMTS(H5O_msg_class_g)); + type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ assert(type); /* Call the "real" reset routine */ @@ -667,12 +497,10 @@ done: * matzke@llnl.gov * Aug 12 1997 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t -H5O_reset_real(const H5O_class_t *type, void *native) +H5O_reset_real(const H5O_msg_class_t *type, void *native) { herr_t ret_value=SUCCEED; /* Return value */ @@ -715,21 +543,20 @@ done: void * H5O_free (unsigned type_id, void *mesg) { - const H5O_class_t *type; /* Actual H5O class type for the ID */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ void * ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5O_free, NULL); + FUNC_ENTER_NOAPI_NOFUNC(H5O_free) /* 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); + HDassert(type_id < NELMTS(H5O_msg_class_g)); + type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ + HDassert(type); /* Call the "real" free routine */ - ret_value=H5O_free_real(type, mesg); + ret_value = H5O_free_real(type, mesg); -done: - FUNC_LEAVE_NOAPI(ret_value); + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_free() */ @@ -755,7 +582,7 @@ H5O_free_mesg(H5O_mesg_t *mesg) /* Free any native information */ if(mesg->flags & H5O_FLAG_SHARED) - mesg->native = H5O_free_real(H5O_SHARED, mesg->native); + mesg->native = H5O_free_real(H5O_MSG_SHARED, mesg->native); else mesg->native = H5O_free_real(mesg->type, mesg->native); @@ -779,7 +606,7 @@ H5O_free_mesg(H5O_mesg_t *mesg) *------------------------------------------------------------------------- */ void * -H5O_free_real(const H5O_class_t *type, void *msg_native) +H5O_free_real(const H5O_msg_class_t *type, void *msg_native) { FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_free_real) @@ -822,14 +649,14 @@ H5O_free_real(const H5O_class_t *type, void *msg_native) void * H5O_copy (unsigned type_id, const void *mesg, void *dst) { - const H5O_class_t *type; /* Actual H5O class type for the ID */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ void *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_copy, NULL); /* 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_id < NELMTS(H5O_msg_class_g)); + type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ assert(type); /* Call the "real" copy routine */ @@ -859,7 +686,7 @@ done: *------------------------------------------------------------------------- */ static void * -H5O_copy_real (const H5O_class_t *type, const void *mesg, void *dst) +H5O_copy_real (const H5O_msg_class_t *type, const void *mesg, void *dst) { void *ret_value = NULL; @@ -988,7 +815,7 @@ done: int 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 */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ int ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_count, FAIL) @@ -997,8 +824,8 @@ H5O_count(H5O_loc_t *loc, unsigned type_id, hid_t dxpl_id) 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_id < NELMTS(H5O_msg_class_g)); + type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); /* Call the "real" count routine */ @@ -1026,7 +853,7 @@ done: *------------------------------------------------------------------------- */ static int -H5O_count_real(H5O_loc_t *loc, const H5O_class_t *type, hid_t dxpl_id) +H5O_count_real(H5O_loc_t *loc, const H5O_msg_class_t *type, hid_t dxpl_id) { H5O_t *oh = NULL; int acc; @@ -1082,29 +909,34 @@ done: htri_t 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 */ + H5O_t *oh = NULL; /* Object header for location */ htri_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_exists, FAIL) 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(type_id < NELMTS(H5O_msg_class_g)); HDassert(sequence >= 0); + /* Load the object header */ + if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL, "unable to load object header") + /* Call the "real" exists routine */ - if((ret_value = H5O_exists_real(loc, type, sequence, dxpl_id)) < 0) + if((ret_value = H5O_exists_oh(oh, type_id, sequence)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_READERROR, FAIL, "unable to verify object header message") done: + if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) != SUCCEED) + HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_exists() */ /*------------------------------------------------------------------------- - * Function: H5O_exists_real + * Function: H5O_exists_oh * * Purpose: Determines if a particular message exists in an object * header without trying to decode the message. @@ -1121,24 +953,21 @@ done: * *------------------------------------------------------------------------- */ -static htri_t -H5O_exists_real(H5O_loc_t *loc, const H5O_class_t *type, int sequence, hid_t dxpl_id) +htri_t +H5O_exists_oh(H5O_t *oh, unsigned type_id, int sequence) { - H5O_t *oh = NULL; - unsigned u; - htri_t ret_value; /* Return value */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ + unsigned u; /* Local index variable */ + htri_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI_NOINIT(H5O_exists_real) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_exists_oh) - HDassert(loc); - HDassert(loc->file); + HDassert(oh); + HDassert(type_id < NELMTS(H5O_msg_class_g)); + type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); HDassert(sequence >= 0); - /* Load the object header */ - if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) - HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, 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) @@ -1150,12 +979,8 @@ H5O_exists_real(H5O_loc_t *loc, const H5O_class_t *type, int sequence, hid_t dxp /* Set return value */ ret_value = (sequence < 0); -done: - if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) != SUCCEED) - HDONE_ERROR(H5E_OHDR, H5E_PROTECT, FAIL, "unable to release object header") - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_exists_real() */ +} /* end H5O_exists_oh() */ /*------------------------------------------------------------------------- @@ -1184,7 +1009,7 @@ done: void * 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 */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ void *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_read, NULL) @@ -1193,8 +1018,8 @@ H5O_read(const H5O_loc_t *loc, unsigned type_id, int sequence, void *mesg, hid_t 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_id < NELMTS(H5O_msg_class_g)); + type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); HDassert(sequence >= 0); @@ -1231,7 +1056,7 @@ done: *------------------------------------------------------------------------- */ void * -H5O_read_real(const H5O_loc_t *loc, const H5O_class_t *type, int sequence, void *mesg, hid_t dxpl_id) +H5O_read_real(const H5O_loc_t *loc, const H5O_msg_class_t *type, int sequence, void *mesg, hid_t dxpl_id) { H5O_t *oh = NULL; int idx; @@ -1257,7 +1082,7 @@ H5O_read_real(const H5O_loc_t *loc, const H5O_class_t *type, int sequence, void 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 + * H5O_MSG_SHARED message. We use that information to look up the real * message in the global heap or some other object header. */ H5O_shared_t *shared; @@ -1306,7 +1131,7 @@ done: *------------------------------------------------------------------------- */ static unsigned -H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t **type_p, int sequence) +H5O_find_in_ohdr(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t **type_p, int sequence) { unsigned u; unsigned ret_value; @@ -1333,7 +1158,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. */ - LOAD_NATIVE(f, dxpl_id, &(oh->mesg[u])) + LOAD_NATIVE(f, dxpl_id, &(oh->mesg[u]), UFAIL) /* * Return the message type. If this is a shared message then return the @@ -1387,7 +1212,7 @@ int 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 */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ int ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_modify, FAIL) @@ -1396,8 +1221,8 @@ H5O_modify(H5O_loc_t *loc, unsigned type_id, int overwrite, 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_id < NELMTS(H5O_msg_class_g)); + type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); HDassert(mesg); HDassert(0 == (flags & ~H5O_FLAG_BITS)); @@ -1446,7 +1271,7 @@ done: *------------------------------------------------------------------------- */ static int -H5O_modify_real(H5O_loc_t *loc, const H5O_class_t *type, int overwrite, +H5O_modify_real(H5O_loc_t *loc, const H5O_msg_class_t *type, int overwrite, unsigned flags, unsigned update_flags, const void *mesg, hid_t dxpl_id) { H5O_t *oh = NULL; @@ -1618,24 +1443,13 @@ done: * koziol@ncsa.uiuc.edu * Dec 31 2002 * - * Modifications: - * Changed to use IDs for types, instead of type objects, then - * call "real" routine. - * Quincey Koziol - * Feb 14 2003 - * - * 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. - * *------------------------------------------------------------------------- */ int H5O_append(H5F_t *f, hid_t dxpl_id, H5O_t *oh, unsigned type_id, unsigned flags, const void *mesg, unsigned * oh_flags_ptr) { - const H5O_class_t *type; /* Actual H5O class type for the ID */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ int ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_append,FAIL); @@ -1643,8 +1457,8 @@ 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)); - type=message_type_g[type_id]; /* map the type ID to the actual type object */ + assert(type_id < NELMTS(H5O_msg_class_g)); + type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ assert(type); assert(0==(flags & ~H5O_FLAG_BITS)); assert(mesg); @@ -1677,7 +1491,7 @@ done: *------------------------------------------------------------------------- */ static int -H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_class_t *type, +H5O_append_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, const H5O_msg_class_t *type, unsigned flags, const void *mesg, unsigned * oh_flags_ptr) { unsigned idx; /* Index of message to modify */ @@ -1724,8 +1538,8 @@ done: *------------------------------------------------------------------------- */ static unsigned -H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_class_t *orig_type, - const void *orig_mesg, H5O_shared_t *sh_mesg, const H5O_class_t **new_type, +H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_msg_class_t *orig_type, + const void *orig_mesg, H5O_shared_t *sh_mesg, const H5O_msg_class_t **new_type, const void **new_mesg, hid_t dxpl_id, unsigned * oh_flags_ptr) { size_t size; /* Size of space allocated for object header */ @@ -1759,7 +1573,7 @@ H5O_new_mesg(H5F_t *f, H5O_t *oh, unsigned *flags, const H5O_class_t *orig_type, *flags &= ~H5O_FLAG_SHARED; } else { /* Change type & message to use shared information */ - *new_type=H5O_SHARED; + *new_type=H5O_MSG_SHARED; *new_mesg=sh_mesg; } /* end else */ } /* end if */ @@ -1795,18 +1609,10 @@ done: * Programmer: Quincey Koziol * Friday, September 3, 2003 * - * 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. - * *------------------------------------------------------------------------- */ static herr_t -H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_class_t *type, +H5O_write_mesg(H5O_t *oh, unsigned idx, const H5O_msg_class_t *type, const void *mesg, unsigned flags, unsigned update_flags, unsigned * oh_flags_ptr) { @@ -1874,7 +1680,7 @@ H5O_touch_oh(H5F_t *f, /* Look for existing message */ for (idx=0; idx < oh->nmesgs; idx++) { - if (H5O_MTIME==oh->mesg[idx].type || H5O_MTIME_NEW==oh->mesg[idx].type) + if (H5O_MSG_MTIME==oh->mesg[idx].type || H5O_MSG_MTIME_NEW==oh->mesg[idx].type) break; } @@ -1893,10 +1699,9 @@ H5O_touch_oh(H5F_t *f, if (idx==oh->nmesgs) { if (!force) HGOTO_DONE(SUCCEED); /*nothing to do*/ - size = (H5O_MTIME_NEW->raw_size)(f, &now); + size = (H5O_MSG_MTIME_NEW->raw_size)(f, &now); - if ((idx=H5O_alloc(f, dxpl_id, oh, H5O_MTIME_NEW, - size, oh_flags_ptr))==UFAIL) + if ((idx=H5O_alloc(f, dxpl_id, oh, H5O_MSG_MTIME_NEW, size, oh_flags_ptr))==UFAIL) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to allocate space for modification time message"); } @@ -1927,12 +1732,6 @@ done: * Programmer: Robb Matzke * Monday, July 27, 1998 * - * 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 @@ -1995,14 +1794,14 @@ H5O_bogus_oh(H5F_t *f, hid_t dxpl_id, H5O_t *oh, hbool_t * oh_flags_ptr) /* Look for existing message */ for(idx = 0; idx < oh->nmesgs; idx++) - if(H5O_BOGUS == oh->mesg[idx].type) + if(H5O_MSG_BOGUS == oh->mesg[idx].type) break; /* Create a new message */ if(idx == oh->nmesgs) { - size_t size = (H5O_BOGUS->raw_size)(f, NULL); + size_t size = (H5O_MSG_BOGUS->raw_size)(f, NULL); - if((idx = H5O_alloc(f, dxpl_id, oh, H5O_BOGUS, size, oh_flags_ptr)) < 0) + if((idx = H5O_alloc(f, dxpl_id, oh, H5O_MSG_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 */ @@ -2104,7 +1903,7 @@ done: herr_t 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 */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ herr_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_remove, FAIL) @@ -2113,8 +1912,8 @@ H5O_remove(H5O_loc_t *loc, unsigned type_id, int sequence, hbool_t adj_link, hid 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_id < NELMTS(H5O_msg_class_g)); + type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); /* Call the "real" remove routine */ @@ -2147,7 +1946,7 @@ 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) { - const H5O_class_t *type; /* Actual H5O class type for the ID */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ herr_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_remove_op, FAIL) @@ -2156,8 +1955,8 @@ H5O_remove_op(const H5O_loc_t *loc, unsigned type_id, int sequence, 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_id < NELMTS(H5O_msg_class_g)); + type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); /* Call the "real" remove routine */ @@ -2227,7 +2026,7 @@ H5O_remove_cb(H5O_mesg_t *mesg/*in,out*/, unsigned idx, unsigned * oh_flags_ptr, H5O_free_mesg(mesg); /* Change message type to nil and zero it */ - mesg->type = H5O_NULL; + mesg->type = H5O_MSG_NULL; HDmemset(mesg->raw, 0, mesg->raw_size); /* Indicate that the message was modified */ @@ -2268,7 +2067,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_remove_real(const H5O_loc_t *loc, const H5O_class_t *type, int sequence, +H5O_remove_real(const H5O_loc_t *loc, const H5O_msg_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 */ @@ -2308,6 +2107,53 @@ done: /*------------------------------------------------------------------------- * + * Function: H5O_alloc_msgs + * + * Purpose: Allocate more messages for a header + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Quincey Koziol + * koziol@ncsa.uiuc.edu + * Nov 21 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_alloc_msgs(H5O_t *oh, size_t min_alloc) +{ + size_t old_alloc; /* Old number of messages allocated */ + size_t na; /* New number of messages allocated */ + H5O_mesg_t *new_mesg; /* Pointer to new message array */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_alloc_msgs) + + /* check args */ + HDassert(oh); + + /* Initialize number of messages information */ + old_alloc = oh->alloc_nmesgs; + na = oh->alloc_nmesgs + MAX (H5O_NMESGS, min_alloc); + + /* Attempt to allocate more memory */ + if(NULL == (new_mesg = H5FL_SEQ_REALLOC(H5O_mesg_t, oh->mesg, na))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + + /* Update ohdr information */ + oh->alloc_nmesgs = na; + oh->mesg = new_mesg; + + /* Set new object header info to zeros */ + HDmemset(&oh->mesg[old_alloc], 0, (oh->alloc_nmesgs - old_alloc) * sizeof(H5O_mesg_t)); + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* H5O_alloc_msgs() */ + + +/*------------------------------------------------------------------------- + * * Function: H5O_move_msgs_forward * * Purpose: Move messages toward first chunk @@ -2330,7 +2176,7 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) FUNC_ENTER_NOAPI_NOINIT(H5O_move_msgs_forward) /* check args */ - HDassert(oh != NULL); + HDassert(oh); /* Loop until no messages packed */ /* (Double loop is not very efficient, but it would be some extra work to add @@ -2364,7 +2210,7 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) 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) + LOAD_NATIVE(f, dxpl_id, nonnull_msg, FAIL) /* Adjust non-null message's offset in chunk */ nonnull_msg->raw = curr_msg->raw; @@ -2411,7 +2257,7 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_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, curr_msg) + LOAD_NATIVE(f, dxpl_id, curr_msg, FAIL) /* Change information for non-null message */ if(curr_msg->raw_size == null_msg->raw_size) { @@ -2449,20 +2295,15 @@ H5O_move_msgs_forward(H5F_t *f, H5O_t *oh, hid_t dxpl_id) /* 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; + if(H5O_alloc_msgs(oh, (size_t)0) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages") } /* 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].type = H5O_MSG_NULL; oh->mesg[new_null_msg].dirty = TRUE; oh->mesg[new_null_msg].native = NULL; oh->mesg[new_null_msg].raw = old_raw; @@ -2661,8 +2502,8 @@ H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id) 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); + HDassert(H5O_MSG_CONT->decode); + cont_msg->native = (H5O_MSG_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 */ @@ -2692,7 +2533,7 @@ H5O_remove_empty_chunks(H5F_t *f, H5O_t *oh, hid_t dxpl_id) H5O_free_mesg(cont_msg); /* Change message type to nil and zero it */ - cont_msg->type = H5O_NULL; + cont_msg->type = H5O_MSG_NULL; HDmemset(cont_msg->raw, 0, cont_msg->raw_size); /* Indicate that the continuation message was modified */ @@ -2916,20 +2757,15 @@ H5O_alloc_extend_chunk(H5F_t *f, else { /* Create a new 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; + if(H5O_alloc_msgs(oh, (size_t)0) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "can't allocate more space for messages") } /* end if */ /* Set extension message */ extend_msg = oh->nmesgs++; /* Initialize new null message */ - oh->mesg[extend_msg].type = H5O_NULL; + oh->mesg[extend_msg].type = H5O_MSG_NULL; oh->mesg[extend_msg].dirty = TRUE; oh->mesg[extend_msg].native = NULL; oh->mesg[extend_msg].raw = oh->chunk[chunkno].image + @@ -3128,18 +2964,8 @@ H5O_alloc_new_chunk(H5F_t *f, * that could be generated below. */ 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") - 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)); + if(H5O_alloc_msgs(oh, (size_t)3) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "can't allocate more space for messages") } /* end if */ /* @@ -3147,7 +2973,7 @@ H5O_alloc_new_chunk(H5F_t *f, */ if(found_null < 0) { found_null = u = oh->nmesgs++; - oh->mesg[u].type = H5O_NULL; + oh->mesg[u].type = H5O_MSG_NULL; oh->mesg[u].dirty = TRUE; oh->mesg[u].native = NULL; oh->mesg[u].raw = oh->mesg[found_other].raw; @@ -3165,7 +2991,7 @@ H5O_alloc_new_chunk(H5F_t *f, 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].type = H5O_MSG_NULL; oh->mesg[idx].dirty = TRUE; oh->mesg[idx].native = NULL; oh->mesg[idx].raw = p + H5O_SIZEOF_MSGHDR(f); @@ -3179,7 +3005,7 @@ H5O_alloc_new_chunk(H5F_t *f, */ if(oh->mesg[found_null].raw_size > cont_size) { u = oh->nmesgs++; - oh->mesg[u].type = H5O_NULL; + oh->mesg[u].type = H5O_MSG_NULL; oh->mesg[u].dirty = TRUE; oh->mesg[u].native = NULL; oh->mesg[u].raw = oh->mesg[found_null].raw + @@ -3196,7 +3022,7 @@ H5O_alloc_new_chunk(H5F_t *f, /* * Initialize the continuation message. */ - oh->mesg[found_null].type = H5O_CONT; + oh->mesg[found_null].type = H5O_MSG_CONT; oh->mesg[found_null].dirty = TRUE; if (NULL==(cont = H5FL_MALLOC(H5O_cont_t))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "memory allocation failed") @@ -3232,7 +3058,7 @@ static unsigned H5O_alloc(H5F_t *f, hid_t dxpl_id, H5O_t *oh, - const H5O_class_t *type, + const H5O_msg_class_t *type, size_t size, unsigned * oh_flags_ptr) { @@ -3309,24 +3135,14 @@ H5O_alloc(H5F_t *f, /* 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; - - /* Set new object header info to zeros */ - HDmemset(&oh->mesg[old_alloc], 0, - (oh->alloc_nmesgs-old_alloc)*sizeof(H5O_mesg_t)); + if(H5O_alloc_msgs(oh, (size_t)0) < 0) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, UFAIL, "can't allocate more space for messages") /* "Retarget" local 'msg' pointer into newly allocated array of messages */ msg = &oh->mesg[idx]; } /* end if */ null_msg = &(oh->mesg[oh->nmesgs++]); - null_msg->type = H5O_NULL; + null_msg->type = H5O_MSG_NULL; null_msg->dirty = TRUE; null_msg->native = NULL; null_msg->raw = msg->raw + mesg_size; @@ -3369,7 +3185,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_share (H5F_t *f, hid_t dxpl_id, const H5O_class_t *type, const void *mesg, +H5O_share (H5F_t *f, hid_t dxpl_id, const H5O_msg_class_t *type, const void *mesg, H5HG_t *hobj/*out*/) { size_t size; @@ -3420,14 +3236,14 @@ done: size_t H5O_raw_size(unsigned type_id, const H5F_t *f, const void *mesg) { - const H5O_class_t *type; /* Actual H5O class type for the ID */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ size_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_raw_size,0) /* Check args */ - HDassert(type_id < NELMTS(message_type_g)); - type=message_type_g[type_id]; /* map the type ID to the actual type object */ + HDassert(type_id < NELMTS(H5O_msg_class_g)); + type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); HDassert(type->raw_size); HDassert(f); @@ -3459,14 +3275,14 @@ done: size_t H5O_mesg_size(unsigned type_id, const H5F_t *f, const void *mesg) { - const H5O_class_t *type; /* Actual H5O class type for the ID */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ size_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_mesg_size,0) /* Check args */ - HDassert(type_id < NELMTS(message_type_g)); - type=message_type_g[type_id]; /* map the type ID to the actual type object */ + HDassert(type_id < NELMTS(H5O_msg_class_g)); + type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); HDassert(type->raw_size); HDassert(f); @@ -3509,14 +3325,14 @@ done: herr_t 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 */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ herr_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_get_share,FAIL) /* Check args */ - HDassert(type_id < NELMTS(message_type_g)); - type = message_type_g[type_id]; /* map the type ID to the actual type object */ + HDassert(type_id < NELMTS(H5O_msg_class_g)); + type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); HDassert(type->get_share); HDassert(f); @@ -3642,7 +3458,7 @@ done: static herr_t 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 */ + const H5O_msg_class_t *type; /* Type of object to free */ herr_t ret_value=SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_delete_mesg) @@ -3653,7 +3469,7 @@ H5O_delete_mesg(H5F_t *f, hid_t dxpl_id, H5O_mesg_t *mesg, hbool_t adj_link) /* Get the message to free's type */ if(mesg->flags & H5O_FLAG_SHARED) - type = H5O_SHARED; + type = H5O_MSG_SHARED; else type = mesg->type; @@ -3758,14 +3574,14 @@ done: herr_t H5O_encode(H5F_t *f, unsigned char *buf, void *obj, unsigned type_id) { - const H5O_class_t *type; /* Actual H5O class type for the ID */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5O_encode,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_id < NELMTS(H5O_msg_class_g)); + type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ assert(type); /* Encode */ @@ -3798,14 +3614,14 @@ done: void* H5O_decode(H5F_t *f, const unsigned char *buf, unsigned type_id) { - const H5O_class_t *type; /* Actual H5O class type for the ID */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ void *ret_value=NULL; /* Return value */ FUNC_ENTER_NOAPI(H5O_decode,NULL); /* 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_id < NELMTS(H5O_msg_class_g)); + type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ assert(type); /* decode */ @@ -3846,19 +3662,13 @@ done: * C. Negative causes the iterator to immediately return that value, * indicating failure. * - * 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_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 */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ herr_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5O_iterate, FAIL) @@ -3867,8 +3677,8 @@ H5O_iterate(const H5O_loc_t *loc, unsigned type_id, H5O_operator_t op, 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_id < NELMTS(H5O_msg_class_g)); + type = H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ HDassert(type); /* Call the "real" iterate routine */ @@ -3914,7 +3724,7 @@ done: *------------------------------------------------------------------------- */ static herr_t -H5O_iterate_real(const H5O_loc_t *loc, const H5O_class_t *type, H5AC_protect_t prot, +H5O_iterate_real(const H5O_loc_t *loc, const H5O_msg_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 */ @@ -3944,7 +3754,7 @@ H5O_iterate_real(const H5O_loc_t *loc, const H5O_class_t *type, H5AC_protect_t p * Decode the message if necessary. If the message is shared then decode * a shared message, ignoring the message type. */ - LOAD_NATIVE(loc->file, dxpl_id, idx_msg) + LOAD_NATIVE(loc->file, dxpl_id, idx_msg, FAIL) /* Check for making an "internal" (i.e. within the H5O package) callback */ if(internal) { @@ -4005,20 +3815,62 @@ done: H5G_obj_t H5O_obj_type(H5O_loc_t *loc, hid_t dxpl_id) { - size_t i; /* Local index variable */ + H5O_t *oh = NULL; /* Object header for location */ H5G_obj_t ret_value = H5G_UNKNOWN; /* Return value */ FUNC_ENTER_NOAPI(H5O_obj_type, H5G_UNKNOWN) + /* Load the object header */ + if(NULL == (oh = H5AC_protect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, NULL, NULL, H5AC_READ))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTLOAD, H5G_UNKNOWN, "unable to load object header") + + /* Test whether entry qualifies as a particular type of object */ + if((ret_value = H5O_obj_type_real(oh)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type") + +done: + if(oh && H5AC_unprotect(loc->file, dxpl_id, H5AC_OHDR, loc->addr, oh, H5AC__NO_FLAGS_SET) != SUCCEED) + HDONE_ERROR(H5E_OHDR, H5E_PROTECT, H5G_UNKNOWN, "unable to release object header") + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_obj_type() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_obj_type_real + * + * Purpose: Returns the type of object pointed to by `oh'. + * + * Note: Same algorithm as H5O_obj_class() + * + * Return: Success: An object type defined in H5Gpublic.h + * Failure: H5G_UNKNOWN + * + * Programmer: Quincey Koziol + * Monday, November 21, 2005 + * + *------------------------------------------------------------------------- + */ +static H5G_obj_t +H5O_obj_type_real(H5O_t *oh) +{ + size_t i; /* Local index variable */ + H5G_obj_t ret_value = H5G_UNKNOWN; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_obj_type_real) + + /* Sanity check */ + HDassert(oh); + /* Test whether entry qualifies as a particular type of object */ /* (Note: loop is in reverse order, to test specific objects first) */ - for(i = H5O_ntypes_g; i > 0; --i) { + for(i = NELMTS(H5O_obj_class_g); i > 0; --i) { htri_t isa; /* Is entry a particular type? */ - if((isa = (H5O_type_g[i-1].isa)(loc, dxpl_id)) < 0) + if((isa = (H5O_obj_class_g[i - 1]->isa)(oh)) < 0) HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, H5G_UNKNOWN, "unable to determine object type") else if(isa) - HGOTO_DONE(H5O_type_g[i-1].type) + HGOTO_DONE(H5O_obj_class_g[i - 1]->type) } /* end for */ if(0 == i) @@ -4026,7 +3878,52 @@ H5O_obj_type(H5O_loc_t *loc, hid_t dxpl_id) done: FUNC_LEAVE_NOAPI(ret_value) -} /* end H5O_obj_type() */ +} /* end H5O_obj_type_real() */ + + +/*------------------------------------------------------------------------- + * Function: H5O_obj_class + * + * Purpose: Returns the class of object pointed to by `oh'. + * + * Note: Same algorithm as H5O_obj_type_real() + * + * Return: Success: An object class + * Failure: NULL + * + * Programmer: Quincey Koziol + * Monday, November 21, 2005 + * + *------------------------------------------------------------------------- + */ +static const H5O_obj_class_t * +H5O_obj_class(H5O_t *oh) +{ + size_t i; /* Local index variable */ + const H5O_obj_class_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_obj_class) + + /* Sanity check */ + HDassert(oh); + + /* Test whether entry qualifies as a particular type of object */ + /* (Note: loop is in reverse order, to test specific objects first) */ + for(i = NELMTS(H5O_obj_class_g); i > 0; --i) { + htri_t isa; /* Is entry a particular type? */ + + if((isa = (H5O_obj_class_g[i - 1]->isa)(oh)) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to determine object type") + else if(isa) + HGOTO_DONE(H5O_obj_class_g[i - 1]) + } /* end for */ + + if(0 == i) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, NULL, "unable to determine object type") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_obj_class() */ /*------------------------------------------------------------------------- @@ -4122,7 +4019,7 @@ H5O_loc_copy(H5O_loc_t *dst, const H5O_loc_t *src, H5O_copy_depth_t depth) *------------------------------------------------------------------------- */ static void * -H5O_copy_mesg_file(const H5O_class_t *type, H5F_t *file_src, +H5O_copy_mesg_file(const H5O_msg_class_t *type, H5F_t *file_src, void *native_src, H5F_t *file_dst, hid_t dxpl_id, H5SL_t *map_list, void *udata) { void *ret_value; @@ -4162,16 +4059,16 @@ 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 = 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; + size_t 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 */ + const H5O_msg_class_t *copy_type; /* Type of message to use for copying */ + const H5O_obj_class_t *obj_class; /* Type of object we are copying */ + void *udata = NULL; /* User data for passing to message callbacks */ herr_t ret_value = SUCCEED; FUNC_ENTER_NOAPI_NOINIT(H5O_copy_header_real) @@ -4182,148 +4079,180 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, HDassert(oloc_dst->file); HDassert(map_list); + /* Get source object header */ 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(oloc_dst->file); - - /* allocate memory space for the destitnation chunks */ - 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(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 */ - oloc_dst->addr = addr_new; + /* Get pointer to object class for this object */ + if(NULL == (obj_class = H5O_obj_class(oh_src))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to determine object type") - /* Set chunk's address */ - chunk[0].addr = addr_new + (hsize_t)hdr_size; + /* Retrieve user data for particular type of object to copy */ + if(obj_class->get_copy_file_udata && + (NULL == (udata = (obj_class->get_copy_file_udata)()))) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to retrieve copy user data") - /* Encode header information */ - p = buf; + /* Flush any dirty messages in source object header to update the header chunks */ + if(H5O_flush_msgs(oloc_src->file, oh_src) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object header messages") - /* encode version */ - *p++ = H5O_VERSION; + /* get the size of the file header of the destination file */ + hdr_size = H5O_SIZEOF_HDR(oloc_dst->file); - /* reserved */ - *p++ = 0; - /* encode number of messages */ - UINT16ENCODE(p, oh_src->nmesgs); + /* Allocate the destination object header and fill in header fields */ + if(NULL == (oh_dst = H5FL_MALLOC(H5O_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - /* encode link count (at zero initially) */ - UINT32ENCODE(p, 0); + /* Initialize header information */ + oh_dst->version = H5O_VERSION; + oh_dst->nlink = 0; - /* encode body size */ - UINT32ENCODE(p, oh_src->chunk[0].size); + /* Initialize size of chunk array */ + oh_dst->alloc_nchunks = oh_dst->nchunks = oh_src->nchunks; - /* zero to alignment */ - HDmemset(p, 0, (size_t)(hdr_size-12)); + /* Allocate memory for the chunk array */ + if(NULL == (oh_dst->chunk = H5FL_SEQ_MALLOC(H5O_chunk_t, oh_dst->alloc_nchunks))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") /* need to allocate all the chunks for the destination before copy the chunk message because continuation chunk message will need to know the chunk address of address of continuation block. */ - 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_src->nchunks; chunkno++) { - chunk_size = oh_src->chunk[chunkno].size; + size_t chunk_size = oh_src->chunk[chunkno].size; + + /* '0th' chunk is preceded by object header prefix */ + if(0 == chunkno) { + /* Allocate file space for the first chunk & object header prefix */ + if(HADDR_UNDEF == (addr_new = H5MF_alloc(oloc_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)hdr_size + chunk_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header") - /* copy chunk information */ - chunk[chunkno].dirty = oh_src->chunk[chunkno].dirty; - chunk[chunkno].size = chunk_size; + /* Set first chunk's address */ + oh_dst->chunk[0].addr = addr_new + (hsize_t)hdr_size; + } /* end if */ + else { + if(HADDR_UNDEF == (oh_dst->chunk[chunkno].addr = H5MF_alloc(oloc_dst->file, H5FD_MEM_OHDR, dxpl_id, (hsize_t)chunk_size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "file allocation failed for object header") + } /* end else */ - /* create memory image for the new chunk */ - if(NULL == (chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image,chunk_size))) + /* Create memory image for the new chunk */ + if(NULL == (oh_dst->chunk[chunkno].image = H5FL_BLK_MALLOC(chunk_image, chunk_size))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - /* copy the chunk image from source to destination in memory */ + /* Copy the chunk image from source to destination in memory */ /* (This copies over all the messages which don't require special * callbacks to fix them up.) */ - HDmemcpy(chunk[chunkno].image, oh_src->chunk[chunkno].image, chunk_size); + HDmemcpy(oh_dst->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_src->nmesgs; mesgno++) { - const H5O_class_t *copy_type; + /* Set dest. chunk information */ + oh_dst->chunk[chunkno].dirty = TRUE; + oh_dst->chunk[chunkno].size = chunk_size; + } /* end for */ - mesg_src = &(oh_src->mesg[mesgno]); - /* check if the message belongs to this chunk */ - if(mesg_src->chunkno != chunkno) - continue; + /* Initialize size of message list */ + oh_dst->alloc_nmesgs = oh_dst->nmesgs = oh_src->nmesgs; - if (mesg_src->flags & H5O_FLAG_SHARED) - copy_type = H5O_SHARED; - else - copy_type = mesg_src->type; + /* Allocate memory for message array */ + if(NULL == (oh_dst->mesg = H5FL_SEQ_CALLOC(H5O_mesg_t, oh_dst->alloc_nmesgs))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") - /* copy this message into destination file */ - HDassert(copy_type); - if(copy_type->copy_file) { - void *dst_native; /* Pointer to copy of native information for current message */ - - /* - * Decode the message if necessary. If the message is shared then d - * a shared message, ignoring the message type. - */ - if(NULL == mesg_src->native) { - /* Decode the message if necessary */ - HDassert(copy_type->decode); - 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, 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, 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_src->chunk[chunkno].image); + /* Copy basic information about messages */ + HDmemcpy(oh_dst->mesg, oh_src->mesg, oh_dst->alloc_nmesgs * sizeof(H5O_mesg_t)); - /* - * 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)(oloc_dst->file, p, dst_native) < 0) - HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message") + /* "pre copy" pass over messages, to gather information for actual message copy operation */ + /* (for messages which depend on information from other messages) */ + /* (also resets various destination message information) */ + for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) { + /* Set up convenience variables */ + mesg_src = &(oh_src->mesg[mesgno]); + mesg_dst = &(oh_dst->mesg[mesgno]); - /* Release native destination info */ - H5O_free_real(copy_type, dst_native); - } /* end if (mesg_src->type && mesg_src->type->copy_file) */ - } /* end of mesgno loop */ + /* Sanity check */ + HDassert(!mesg_src->dirty); /* Should be cleared by earlier call to flush messages */ - /* Write the object header to the file if this is the first chunk */ - if(chunkno == 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") + /* Fix up destination message pointers */ + mesg_dst->native = NULL; + mesg_dst->raw = oh_dst->chunk[mesg_dst->chunkno].image + (mesg_src->raw - oh_src->chunk[mesg_src->chunkno].image); - /* Write this chunk into disk */ - 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 */ + /* Check for shared message to operate on */ + if(mesg_src->flags & H5O_FLAG_SHARED) + copy_type = H5O_MSG_SHARED; + else + copy_type = mesg_src->type; + HDassert(copy_type); + if(copy_type->pre_copy_file) { + /* + * Decode the message if necessary. If the message is shared then do + * a shared message, ignoring the message type. + */ + if(NULL == mesg_src->native) { + /* Decode the message if necessary */ + HDassert(copy_type->decode); + 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) */ + + /* Perform "pre copy" operation on messge */ + if((copy_type->pre_copy_file)(oloc_src->file, mesg_src->native, udata) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to perform 'post copy' operation on message") + } /* end if */ + } /* end for */ - /* 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); + /* "copy" pass over messages, to perform main message copying */ + for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) { + /* Set up convenience variables */ + mesg_src = &(oh_src->mesg[mesgno]); + mesg_dst = &(oh_dst->mesg[mesgno]); + + /* Check for shared message to operate on */ + if (mesg_src->flags & H5O_FLAG_SHARED) + copy_type = H5O_MSG_SHARED; + else + copy_type = mesg_src->type; + + /* copy this message into destination file */ + HDassert(copy_type); + if(copy_type->copy_file) { + /* + * Decode the message if necessary. If the message is shared then do + * a shared message, ignoring the message type. + */ + if(NULL == mesg_src->native) { + /* Decode the message if necessary */ + HDassert(copy_type->decode); + 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 == mesg_src->type->id) { + if((mesg_dst->native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native, + oloc_dst->file, dxpl_id, map_list, oh_dst->chunk)) == NULL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message") + } /* end if */ + else { + if((mesg_dst->native = H5O_copy_mesg_file(copy_type, oloc_src->file, mesg_src->native, + oloc_dst->file, dxpl_id, map_list, udata)) == NULL) + HGOTO_ERROR(H5E_OHDR, H5E_CANTCOPY, FAIL, "unable to copy object header message") + } /* end else */ + + /* + * 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)(oloc_dst->file, mesg_dst->raw, mesg_dst->native) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, FAIL, "unable to encode object header message") + } /* end if (mesg_src->type->copy_file) */ + } /* end of mesgno loop */ + + + /* Set the dest. object location to the first chunk address */ + oloc_dst->addr = addr_new; /* Allocate space for the address mapping of the object copied */ if(NULL == (addr_map = H5FL_MALLOC(H5O_addr_map_t))) @@ -4338,14 +4267,14 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, 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 */ + /* "post copy" loop over messages, to fix up any messages which require a complete object header for destination object */ for(mesgno = 0; mesgno < oh_src->nmesgs; mesgno++) { - const H5O_class_t *copy_type; - + /* Set up convenience variables */ mesg_src = &(oh_src->mesg[mesgno]); + /* Check for shared message to operate on */ if(mesg_src->flags & H5O_FLAG_SHARED) - copy_type = H5O_SHARED; + copy_type = H5O_MSG_SHARED; else copy_type = mesg_src->type; @@ -4358,52 +4287,48 @@ H5O_copy_header_real(const H5O_loc_t *oloc_src, 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) + LOAD_NATIVE(oloc_dst->file, dxpl_id, mesg_dst, FAIL) /* 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) { + if(modified) mesg_dst->dirty = TRUE; - dst_oh_flags |= H5AC__DIRTIED_FLAG; - } /* end if */ } /* end if */ } /* end for */ + /* 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; + + /* Insert destination object header in cache */ + if(H5AC_set(oloc_dst->file, dxpl_id, H5AC_OHDR, oloc_dst->addr, oh_dst, H5AC__DIRTIED_FLAG) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTINIT, FAIL, "unable to cache object header") + done: /* 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(ret_value < 0 && oh_dst) { + if(H5O_dest(oloc_dst->file, oh_dst) < 0) + HDONE_ERROR(H5E_OHDR, H5E_CANTFREE, FAIL, "unable to destroy object header data") + } /* end if */ - /* 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") + /* Release user data for particular type of object to copy */ + if(udata) { + HDassert(obj_class); + HDassert(obj_class->free_copy_file_udata); + (obj_class->free_copy_file_udata)(udata); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -4571,16 +4496,16 @@ done: *------------------------------------------------------------------------- */ 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) +H5O_debug_id(unsigned type_id, H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, int indent, int fwidth) { - const H5O_class_t *type; /* Actual H5O class type for the ID */ + const H5O_msg_class_t *type; /* Actual H5O class type for the ID */ herr_t ret_value; /* Return value */ 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]))); - type=message_type_g[type_id]; /* map the type ID to the actual type object */ + assert(type_id < NELMTS(H5O_msg_class_g)); + type=H5O_msg_class_g[type_id]; /* map the type ID to the actual type object */ assert(type); assert(type->debug); assert(f); @@ -4675,15 +4600,14 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i } /* debug each message */ - if (NULL==(sequence = H5MM_calloc(NELMTS(message_type_g)*sizeof(int)))) + if (NULL==(sequence = H5MM_calloc(NELMTS(H5O_msg_class_g)*sizeof(int)))) HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); 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); /* check for bad message id */ - if (oh->mesg[i].type->id < 0 || - oh->mesg[i].type->id >= (int)NELMTS(message_type_g)) { + if (oh->mesg[i].type->id >= (int)NELMTS(H5O_msg_class_g)) { HDfprintf(stream, "*** BAD MESSAGE ID 0x%04x\n", oh->mesg[i].type->id); continue; @@ -4732,8 +4656,8 @@ H5O_debug_real(H5F_t *f, hid_t dxpl_id, H5O_t *oh, haddr_t addr, FILE *stream, i /* decode the message */ if (oh->mesg[i].flags & H5O_FLAG_SHARED) { - decode = H5O_SHARED->decode; - debug = H5O_SHARED->debug; + decode = H5O_MSG_SHARED->decode; + debug = H5O_MSG_SHARED->debug; } else { decode = oh->mesg[i].type->decode; debug = oh->mesg[i].type->debug; diff --git a/src/H5Oattr.c b/src/H5Oattr.c index 4d97b12..406c486 100644 --- a/src/H5Oattr.c +++ b/src/H5Oattr.c @@ -40,8 +40,8 @@ static void *H5O_attr_copy_file(H5F_t *file_src, void *native_src, static herr_t H5O_attr_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_ATTR[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_ATTR[1] = {{ H5O_ATTR_ID, /* message id number */ "attribute", /* message name for debugging */ sizeof(H5A_t), /* native message size */ @@ -55,6 +55,7 @@ const H5O_class_t H5O_ATTR[1] = {{ H5O_attr_link, /* link method */ NULL, /* get share method */ NULL, /* set share method */ + NULL, /* pre copy native value to file */ H5O_attr_copy_file, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_attr_debug /* debug the message */ @@ -155,18 +156,18 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p) H5O_shared_t *shared; /* Shared information */ /* Get the shared information */ - if (NULL == (shared = (H5O_SHARED->decode) (f, dxpl_id, p))) + if (NULL == (shared = (H5O_MSG_SHARED->decode) (f, dxpl_id, p))) HGOTO_ERROR(H5E_OHDR, H5E_CANTDECODE, NULL, "unable to decode shared message"); /* Get the actual datatype information */ - if((attr->dt= H5O_shared_read(f, dxpl_id, shared, H5O_DTYPE, NULL))==NULL) + if((attr->dt= H5O_shared_read(f, dxpl_id, shared, H5O_MSG_DTYPE, NULL))==NULL) HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute datatype"); /* Free the shared information */ - H5O_free_real(H5O_SHARED, shared); + H5O_free_real(H5O_MSG_SHARED, shared); } /* end if */ else { - if((attr->dt=(H5O_DTYPE->decode)(f,dxpl_id,p))==NULL) + if((attr->dt=(H5O_MSG_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 +179,7 @@ H5O_attr_decode(H5F_t *f, hid_t dxpl_id, const uint8_t *p) 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) + if((extent=(H5O_MSG_SDSPACE->decode)(f,dxpl_id,p))==NULL) HGOTO_ERROR(H5E_ATTR, H5E_CANTDECODE, NULL, "can't decode attribute dataspace"); /* Copy the extent information */ @@ -311,16 +312,16 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg) HDmemset(&sh_mesg,0,sizeof(H5O_shared_t)); /* Get shared message information from datatype */ - if ((H5O_DTYPE->get_share)(f, attr->dt, &sh_mesg/*out*/)<0) + if ((H5O_MSG_DTYPE->get_share)(f, attr->dt, &sh_mesg/*out*/)<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype"); /* Encode shared message information for datatype */ - if((H5O_SHARED->encode)(f,p,&sh_mesg)<0) + if((H5O_MSG_SHARED->encode)(f,p,&sh_mesg)<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode shared attribute datatype"); } /* end if */ else { /* Encode datatype information */ - if((H5O_DTYPE->encode)(f,p,attr->dt)<0) + if((H5O_MSG_DTYPE->encode)(f,p,attr->dt)<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute datatype"); } /* end else */ if(version < H5O_ATTR_VERSION_NEW) { @@ -331,7 +332,7 @@ H5O_attr_encode(H5F_t *f, uint8_t *p, const void *mesg) p += attr->dt_size; /* encode the attribute dataspace */ - if((H5O_SDSPACE->encode)(f,p,&(attr->ds->extent))<0) + if((H5O_MSG_SDSPACE->encode)(f,p,&(attr->ds->extent))<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't encode attribute dataspace"); if(version < H5O_ATTR_VERSION_NEW) { HDmemset(p+attr->ds_size, 0, H5O_ALIGN(attr->ds_size)-attr->ds_size); @@ -745,14 +746,14 @@ H5O_attr_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE * stream, int in HDmemset(&sh_mesg,0,sizeof(H5O_shared_t)); /* Get shared message information from datatype */ - if ((H5O_DTYPE->get_share)(f, mesg->dt, &sh_mesg/*out*/)<0) + if ((H5O_MSG_DTYPE->get_share)(f, mesg->dt, &sh_mesg/*out*/)<0) HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "can't retrieve shared message information"); - debug=H5O_SHARED->debug; + debug=H5O_MSG_SHARED->debug; dt_mesg=&sh_mesg; } /* end if */ else { - debug=H5O_DTYPE->debug; + debug=H5O_MSG_DTYPE->debug; dt_mesg=mesg->dt; } /* end else */ if(debug) diff --git a/src/H5Obogus.c b/src/H5Obogus.c index 7596ae2..21a983e 100644 --- a/src/H5Obogus.c +++ b/src/H5Obogus.c @@ -45,8 +45,8 @@ 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, int indent, int fwidth); -/* This message derives from H5O */ -const H5O_class_t H5O_BOGUS[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_BOGUS[1] = {{ H5O_BOGUS_ID, /*message id number */ "bogus", /*message name for debugging */ 0, /*native message size */ @@ -60,6 +60,7 @@ const H5O_class_t H5O_BOGUS[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ NULL, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_bogus_debug /*debug the message */ diff --git a/src/H5Ocache.c b/src/H5Ocache.c index e5e20e4..4cd5760 100644 --- a/src/H5Ocache.c +++ b/src/H5Ocache.c @@ -25,9 +25,6 @@ #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 */ @@ -57,25 +54,87 @@ const H5AC_class_t H5AC_OHDR[1] = {{ /*------------------------------------------------------------------------- - * Function: H5O_cache_init_interface + * Function: H5O_flush_msgs * - * Purpose: Initialize the H5O interface. (Just calls - * H5O_init_iterface currently). + * Purpose: Flushes messages for object header. * * Return: Non-negative on success/Negative on failure * * Programmer: Quincey Koziol - * Wednesday, September 28, 2005 + * koziol@ncsa.uiuc.edu + * Nov 21 2005 * *------------------------------------------------------------------------- */ -static herr_t -H5O_cache_init_interface(void) +herr_t +H5O_flush_msgs(H5F_t *f, H5O_t *oh) { - FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5O_cache_init_interface) + uint8_t *p; /* Temporary pointer to encode with */ + int id; /* ID of message to encode */ + H5O_mesg_t *curr_msg; /* Pointer to current message being operated on */ + herr_t (*encode)(H5F_t*, uint8_t*, const void*) = NULL; + unsigned u; /* Local index variable */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_flush_msgs, FAIL) + + /* check args */ + HDassert(f); + HDassert(oh); + + /* 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 == 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_MSG_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 */ - FUNC_LEAVE_NOAPI(H5O_init()) -} /* end H5O_cache_init_interface() */ + /* 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") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_flush_msgs() */ /*------------------------------------------------------------------------- @@ -191,7 +250,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, /* 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]) { + if(id >= NELMTS(H5O_msg_class_g) || NULL == H5O_msg_class_g[id]) { skipped_msgs++; continue; } /* end if */ @@ -208,7 +267,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, 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].type = H5O_msg_class_g[id]; oh->mesg[mesgno].dirty = FALSE; oh->mesg[mesgno].flags = flags; oh->mesg[mesgno].native = NULL; @@ -225,7 +284,7 @@ H5O_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, const void UNUSED * _udata1, if(H5O_CONT_ID == oh->mesg[curmesg].type->id) { H5O_cont_t *cont; - cont = (H5O_CONT->decode) (f, dxpl_id, oh->mesg[curmesg].raw); + cont = (H5O_MSG_CONT->decode) (f, dxpl_id, oh->mesg[curmesg].raw); oh->mesg[curmesg].native = cont; chunk_addr = cont->addr; chunk_size = cont->size; @@ -268,10 +327,7 @@ 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 */ + hbool_t combine = FALSE; /* Whether to combine the object header prefix & the first chunk */ unsigned u; /* Local index variable */ herr_t ret_value = SUCCEED; /* Return value */ @@ -285,54 +341,8 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *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") + if(H5O_flush_msgs(f, oh) < 0) + HGOTO_ERROR(H5E_OHDR, H5E_CANTFLUSH, FAIL, "unable to flush object header messages") /* Encode header prefix */ p = buf; @@ -359,7 +369,7 @@ H5O_flush(H5F_t *f, hid_t dxpl_id, hbool_t destroy, haddr_t addr, H5O_t *oh) /* 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; + combine = TRUE; } /* end if */ else { if(H5F_block_write(f, H5FD_MEM_OHDR, addr, (size_t)H5O_SIZEOF_HDR(f), dxpl_id, buf) < 0) diff --git a/src/H5Ocont.c b/src/H5Ocont.c index f471c61..0808384 100644 --- a/src/H5Ocont.c +++ b/src/H5Ocont.c @@ -46,8 +46,8 @@ static void *H5O_cont_copy_file(H5F_t *file_src, void *mesg_src, static herr_t H5O_cont_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_CONT[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_CONT[1] = {{ H5O_CONT_ID, /*message id number */ "hdr continuation", /*message name for debugging */ sizeof(H5O_cont_t), /*native message size */ @@ -61,6 +61,7 @@ const H5O_class_t H5O_CONT[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ H5O_cont_copy_file, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_cont_debug /*debugging */ diff --git a/src/H5Odtype.c b/src/H5Odtype.c index 73d8909..af2a6c7 100644 --- a/src/H5Odtype.c +++ b/src/H5Odtype.c @@ -35,13 +35,15 @@ static herr_t H5O_dtype_get_share (H5F_t *f, const void *_mesg, H5O_shared_t *sh); static herr_t H5O_dtype_set_share (H5F_t *f, void *_mesg, const H5O_shared_t *sh); +static herr_t H5O_dtype_pre_copy_file(H5F_t *file_src, void *mesg_src, + void *_udata); static herr_t H5O_dtype_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_DTYPE[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_DTYPE[1] = {{ H5O_DTYPE_ID, /* message id number */ - "data_type", /* message name for debugging */ + "datatype", /* message name for debugging */ sizeof(H5T_t), /* native message size */ H5O_dtype_decode, /* decode message */ H5O_dtype_encode, /* encode message */ @@ -53,8 +55,9 @@ const H5O_class_t H5O_DTYPE[1] = {{ NULL, /* link method */ H5O_dtype_get_share, /* get share method */ H5O_dtype_set_share, /* set share method */ + H5O_dtype_pre_copy_file, /* pre copy native value to file */ NULL, /* copy native value to file */ - NULL, /* post copy native value to file */ + NULL, /* post copy native value to file */ H5O_dtype_debug /* debug the message */ }}; @@ -1160,6 +1163,56 @@ H5O_dtype_set_share(H5F_t UNUSED *f, void *_mesg/*in,out*/, } /* end H5O_dtype_set_share() */ +/*------------------------------------------------------------------------- + * Function: H5O_dtype_pre_copy_file + * + * Purpose: Perform any necessary actions before copying message between + * files + * + * Return: Success: Non-negative + * + * Failure: Negative + * + * Programmer: Quincey Koziol + * November 21, 2005 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5O_dtype_pre_copy_file(H5F_t *file_src, void *mesg_src, void *_udata) +{ + H5T_t *dt_src = (H5T_t *)mesg_src; /* Source datatype */ + H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5O_dtype_pre_copy_file) + + /* check args */ + HDassert(file_src); + HDassert(dt_src); + + /* If the user data is non-NULL, assume we are copying a dataset + * and check if we need to make a copy of the datatype for later in + * the object copying process. (We currently only need to make a copy + * of the datatype if it's a vlen datatype) + */ + if(udata) { + if(H5T_detect_class(dt_src, H5T_VLEN) > 0) { + /* Create a memory copy of the variable-length datatype */ + if(NULL == (udata->src_dtype = H5T_copy(dt_src, H5T_COPY_TRANSIENT))) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to copy") + + /* Set the location of the source datatype */ + if(H5T_set_loc(udata->src_dtype, file_src, H5T_LOC_DISK) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "cannot mark datatype on disk") + } /* end if */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_dtype_pre_copy_file() */ + + /*-------------------------------------------------------------------------- NAME H5O_dtype_debug @@ -1475,3 +1528,4 @@ H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream, FUNC_LEAVE_NOAPI(SUCCEED); } + diff --git a/src/H5Oefl.c b/src/H5Oefl.c index 24f8c3b..a70a9b2 100644 --- a/src/H5Oefl.c +++ b/src/H5Oefl.c @@ -38,8 +38,8 @@ static void *H5O_efl_copy_file(H5F_t *file_src, void *mesg_src, static herr_t H5O_efl_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_EFL[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_EFL[1] = {{ H5O_EFL_ID, /*message id number */ "external file list", /*message name for debugging */ sizeof(H5O_efl_t), /*native message size */ @@ -53,6 +53,7 @@ const H5O_class_t H5O_EFL[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ H5O_efl_copy_file, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_efl_debug /*debug the message */ diff --git a/src/H5Ofill.c b/src/H5Ofill.c index f6e68a0..e7c5537 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -48,8 +48,8 @@ static herr_t H5O_fill_free(void *_mesg); static herr_t H5O_fill_debug(H5F_t *f, hid_t dxpl_id, const void *_mesg, FILE *stream, int indent, int fwidth); -/* This message derives from H5O, for old fill value before version 1.5 */ -const H5O_class_t H5O_FILL[1] = {{ +/* This message derives from H5O message class, for old fill value before version 1.5 */ +const H5O_msg_class_t H5O_MSG_FILL[1] = {{ H5O_FILL_ID, /*message id number */ "fill", /*message name for debugging */ sizeof(H5O_fill_t), /*native message size */ @@ -63,13 +63,14 @@ const H5O_class_t H5O_FILL[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ NULL, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_fill_debug /*debug the message */ }}; -/* This message derives from H5O, for new fill value after version 1.4 */ -const H5O_class_t H5O_FILL_NEW[1] = {{ +/* This message derives from H5O message class, for new fill value after version 1.4 */ +const H5O_msg_class_t H5O_MSG_FILL_NEW[1] = {{ H5O_FILL_NEW_ID, /*message id number */ "fill_new", /*message name for debugging */ sizeof(H5O_fill_new_t), /*native message size */ @@ -83,6 +84,7 @@ const H5O_class_t H5O_FILL_NEW[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ NULL, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_fill_new_debug /*debug the message */ diff --git a/src/H5Oginfo.c b/src/H5Oginfo.c index 6aeda3d..10bde6d 100644 --- a/src/H5Oginfo.c +++ b/src/H5Oginfo.c @@ -42,8 +42,8 @@ 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] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_GINFO[1] = {{ H5O_GINFO_ID, /*message id number */ "ginfo", /*message name for debugging */ sizeof(H5O_ginfo_t), /*native message size */ @@ -57,6 +57,7 @@ const H5O_class_t H5O_GINFO[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ NULL, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_ginfo_debug /*debug the message */ diff --git a/src/H5Olayout.c b/src/H5Olayout.c index 0844010..3665e13 100644 --- a/src/H5Olayout.c +++ b/src/H5Olayout.c @@ -44,8 +44,8 @@ static void *H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, static herr_t H5O_layout_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_LAYOUT[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_LAYOUT[1] = {{ H5O_LAYOUT_ID, /*message id number */ "layout", /*message name for debugging */ sizeof(H5O_layout_t), /*native message size */ @@ -59,6 +59,7 @@ const H5O_class_t H5O_LAYOUT[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ H5O_layout_copy_file, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_layout_debug /*debug the message */ @@ -436,7 +437,7 @@ H5O_layout_meta_size(const H5F_t *f, const void *_mesg) break; default: - HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, 0, "Invalid layout class"); + HGOTO_ERROR(H5E_OHDR, H5E_CANTENCODE, 0, "Invalid layout class") } /* end switch */ done: @@ -606,7 +607,7 @@ done: /*------------------------------------------------------------------------- * Function: H5O_layout_copy_file * - * Purpose: Copies a data layout message from _MESG to _DEST in file + * Purpose: Copies a message from _MESG to _DEST in file * * Return: Success: Ptr to _DEST * @@ -621,8 +622,9 @@ done: */ static void * H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, - H5F_t *file_dst, hid_t dxpl_id, H5SL_t UNUSED *map_list, void UNUSED *_udata) + H5F_t *file_dst, hid_t dxpl_id, H5SL_t UNUSED *map_list, void *_udata) { + H5D_copy_file_ud_t *udata = (H5D_copy_file_ud_t *)_udata; /* Dataset copying user data */ H5O_layout_t *layout_src = (H5O_layout_t *) mesg_src; H5O_layout_t *layout_dst = NULL; void *ret_value; /* Return value */ @@ -646,6 +648,7 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, if(layout_src->u.compact.buf) { if(NULL == (layout_dst->u.compact.buf = H5MM_malloc(layout_src->u.compact.size))) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate memory for compact dataset") +HDassert(!udata->src_dtype); HDmemcpy(layout_dst->u.compact.buf, layout_src->u.compact.buf, layout_src->u.compact.size); layout_dst->u.compact.dirty = TRUE; } @@ -653,38 +656,18 @@ H5O_layout_copy_file(H5F_t *file_src, void *mesg_src, case H5D_CONTIGUOUS: if(H5F_addr_defined(layout_src->u.contig.addr)) { - haddr_t addr_src, addr_dst; - unsigned DRAW_BUF_SIZE = 4096; - uint8_t buf[4096]; - size_t nbytes=0, total_nbytes=0; - - /* create layout */ - if(H5D_contig_create (file_dst, dxpl_id, layout_dst)<0) - HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to initialize contiguous storage") - - /* copy raw data*/ - nbytes = total_nbytes = 0; - while(total_nbytes < layout_src->u.contig.size) { - addr_src = layout_src->u.contig.addr + total_nbytes; - addr_dst = layout_dst->u.contig.addr + total_nbytes; - - nbytes = layout_src->u.contig.size-total_nbytes; - if(nbytes > DRAW_BUF_SIZE) - nbytes = DRAW_BUF_SIZE; - total_nbytes += nbytes; - - if(H5F_block_read(file_src, H5FD_MEM_DRAW, addr_src, nbytes, H5P_DATASET_XFER_DEFAULT, buf)<0) - HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unable to read raw data") - - if(H5F_block_write(file_dst, H5FD_MEM_DRAW, addr_dst, nbytes, H5P_DATASET_XFER_DEFAULT, buf)<0) - HGOTO_ERROR(H5E_SYM, H5E_READERROR, NULL, "unable to write raw data") - } + /* create contig layout */ + if(H5D_contig_copy(file_src, layout_src, file_dst, layout_dst, udata->src_dtype, dxpl_id) < 0) + HGOTO_ERROR(H5E_IO, H5E_CANTINIT, NULL, "unable to copy contiguous storage") + + /* Freed by copy routine */ + udata->src_dtype = NULL; } /* if ( H5F_addr_defined(layout_src->u.contig.addr)) */ break; case H5D_CHUNKED: if(H5F_addr_defined(layout_src->u.chunk.addr)) { - +HDassert(!udata->src_dtype); /* layout is not created in the destination file, undef btree address */ layout_dst->u.chunk.addr = HADDR_UNDEF; @@ -707,7 +690,7 @@ done: H5FL_FREE(H5O_layout_t, layout_dst); FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5O_layout_copy_file() */ /*------------------------------------------------------------------------- diff --git a/src/H5Olinfo.c b/src/H5Olinfo.c index cc0ce2d..11699b7 100644 --- a/src/H5Olinfo.c +++ b/src/H5Olinfo.c @@ -42,8 +42,8 @@ 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] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_LINFO[1] = {{ H5O_LINFO_ID, /*message id number */ "linfo", /*message name for debugging */ sizeof(H5O_linfo_t), /*native message size */ @@ -57,6 +57,7 @@ const H5O_class_t H5O_LINFO[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ NULL, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_linfo_debug /*debug the message */ diff --git a/src/H5Olink.c b/src/H5Olink.c index 2284ecb..062359b 100644 --- a/src/H5Olink.c +++ b/src/H5Olink.c @@ -49,8 +49,8 @@ static herr_t H5O_link_post_copy_file(H5F_t *file_src, const void *mesg_src, 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] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_LINK[1] = {{ H5O_LINK_ID, /*message id number */ "link", /*message name for debugging */ sizeof(H5O_link_t), /*native message size */ @@ -64,6 +64,7 @@ const H5O_class_t H5O_LINK[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ 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 */ diff --git a/src/H5Omtime.c b/src/H5Omtime.c index d452ea2..8673d32 100644 --- a/src/H5Omtime.c +++ b/src/H5Omtime.c @@ -45,8 +45,8 @@ static herr_t H5O_mtime_free(void *_mesg); static herr_t H5O_mtime_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_MTIME[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_MTIME[1] = {{ H5O_MTIME_ID, /*message id number */ "mtime", /*message name for debugging */ sizeof(time_t), /*native message size */ @@ -60,14 +60,15 @@ const H5O_class_t H5O_MTIME[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ NULL, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_mtime_debug /*debug the message */ }}; -/* This message derives from H5O */ +/* This message derives from H5O message class */ /* (Only encode, decode & size routines are different from old mtime routines) */ -const H5O_class_t H5O_MTIME_NEW[1] = {{ +const H5O_msg_class_t H5O_MSG_MTIME_NEW[1] = {{ H5O_MTIME_NEW_ID, /*message id number */ "mtime_new", /*message name for debugging */ sizeof(time_t), /*native message size */ @@ -81,6 +82,7 @@ const H5O_class_t H5O_MTIME_NEW[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ NULL, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_mtime_debug /*debug the message */ diff --git a/src/H5Oname.c b/src/H5Oname.c index d6f7e3e..7b43b6c 100644 --- a/src/H5Oname.c +++ b/src/H5Oname.c @@ -42,8 +42,8 @@ static herr_t H5O_name_reset(void *_mesg); static herr_t H5O_name_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_NAME[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_NAME[1] = {{ H5O_NAME_ID, /*message id number */ "name", /*message name for debugging */ sizeof(H5O_name_t), /*native message size */ @@ -57,6 +57,7 @@ const H5O_class_t H5O_NAME[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ NULL, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_name_debug /*debug the message */ diff --git a/src/H5Onull.c b/src/H5Onull.c index 074026e..0b8d742 100644 --- a/src/H5Onull.c +++ b/src/H5Onull.c @@ -31,8 +31,8 @@ #include "H5Opkg.h" /* Object header functions */ -/* This message derives from H5O */ -const H5O_class_t H5O_NULL[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_NULL[1] = {{ H5O_NULL_ID, /*message id number */ "null", /*message name for debugging */ 0, /*native message size */ @@ -46,6 +46,7 @@ const H5O_class_t H5O_NULL[1] = {{ NULL, /*no link method */ NULL, /*no get share method */ NULL, /*no set share method */ + NULL, /*no pre copy native value to file */ NULL, /*no copy native value to file */ NULL, /*no post copy native value to file */ NULL /*no debug method */ diff --git a/src/H5Opkg.h b/src/H5Opkg.h index 874ea91..ed70bb7 100644 --- a/src/H5Opkg.h +++ b/src/H5Opkg.h @@ -59,8 +59,8 @@ 2 + /*sizeof message data */ \ 4) /*reserved */ -typedef struct H5O_class_t { - int id; /*message type ID on disk */ +struct H5O_msg_class_t { + unsigned 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*); @@ -73,13 +73,14 @@ typedef struct H5O_class_t { herr_t (*link)(H5F_t *, hid_t, const void *); /* Increment any links in file reference by this message */ 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 */ + herr_t (*pre_copy_file)(H5F_t *, void *, void *); /*"pre copy" action when copying native value to file */ 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 *, 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; +}; typedef struct H5O_mesg_t { - const H5O_class_t *type; /*type of message */ + const H5O_msg_class_t *type; /*type of message */ hbool_t dirty; /*raw out of date wrt native */ uint8_t flags; /*message flags */ unsigned chunkno; /*chunk number for this mesg */ @@ -95,24 +96,41 @@ typedef struct H5O_chunk_t { uint8_t *image; /*image of file */ } H5O_chunk_t; -typedef struct H5O_t { +struct H5O_t { H5AC_info_t cache_info; /* Information for H5AC cache functions, _must_ be */ /* first field in structure */ - int version; /*version number */ + unsigned version; /*version number */ int nlink; /*link count */ - unsigned nmesgs; /*number of messages */ - unsigned alloc_nmesgs; /*number of message slots */ + size_t nmesgs; /*number of messages */ + size_t alloc_nmesgs; /*number of message slots */ H5O_mesg_t *mesg; /*array of messages */ - unsigned nchunks; /*number of chunks */ - unsigned alloc_nchunks; /*chunks allocated */ + size_t nchunks; /*number of chunks */ + size_t alloc_nchunks; /*chunks allocated */ H5O_chunk_t *chunk; /*array of chunks */ -} H5O_t; +}; + +/* Callback information for copying dataset */ +typedef struct { + H5T_t *src_dtype; /* Copy of datatype for dataset */ +} H5D_copy_file_ud_t; + +/* Class for types of objects in file */ +typedef struct H5O_obj_class_t { + H5G_obj_t type; /*object type on disk */ + const char *name; /*for debugging */ + void *(*get_copy_file_udata)(void); /*retrieve user data for 'copy file' operation */ + void (*free_copy_file_udata)(void *); /*free user data for 'copy file' operation */ + htri_t (*isa)(H5O_t *); /*if a header matches an object class */ +} H5O_obj_class_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]; +/* Header message ID to class mapping */ +H5_DLLVAR const H5O_msg_class_t *const H5O_msg_class_g[19]; + +/* Header object ID to class mapping */ +H5_DLLVAR const H5O_obj_class_t *const H5O_obj_class_g[3]; /* Declare external the free list for H5O_t's */ H5FL_EXTERN(H5O_t); @@ -127,126 +145,114 @@ H5FL_SEQ_EXTERN(H5O_chunk_t); H5FL_BLK_EXTERN(chunk_image); /* - * Null Message. (0x0000) + * Object header messages */ -H5_DLLVAR const H5O_class_t H5O_NULL[1]; -/* - * Simple Dataspace Message. (0x0001) - */ -H5_DLLVAR const H5O_class_t H5O_SDSPACE[1]; +/* Null Message. (0x0000) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_NULL[1]; -/* - * Link Information Message. (0x0002) - */ -H5_DLLVAR const H5O_class_t H5O_LINFO[1]; +/* Simple Dataspace Message. (0x0001) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_SDSPACE[1]; -/* - * Datatype Message. (0x0003) - */ -H5_DLLVAR const H5O_class_t H5O_DTYPE[1]; +/* Link Information Message. (0x0002) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_LINFO[1]; -/* - * Old Fill Value Message. (0x0004) - */ -H5_DLLVAR const H5O_class_t H5O_FILL[1]; +/* Datatype Message. (0x0003) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_DTYPE[1]; -/* - * New Fill Value Message. (0x0005) - * +/* Old Fill Value Message. (0x0004) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_FILL[1]; + +/* New Fill Value Message. (0x0005) */ +/* * The new fill value message is fill value plus * space allocation time and fill value writing time and whether fill * value is defined. */ -H5_DLLVAR const H5O_class_t H5O_FILL_NEW[1]; +H5_DLLVAR const H5O_msg_class_t H5O_MSG_FILL_NEW[1]; -/* - * Link Message. (0x0006) - * - */ -H5_DLLVAR const H5O_class_t H5O_LINK[1]; +/* Link Message. (0x0006) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_LINK[1]; -/* - * External File List Message. (0x0007) - */ -H5_DLLVAR const H5O_class_t H5O_EFL[1]; +/* External File List Message. (0x0007) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_EFL[1]; -/* - * Data Layout Message. (0x0008) - */ -H5_DLLVAR const H5O_class_t H5O_LAYOUT[1]; +/* Data Layout Message. (0x0008) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_LAYOUT[1]; #ifdef H5O_ENABLE_BOGUS +/* "Bogus" Message. (0x0009) */ /* - * "Bogus" Message. (0x0009) + * Used for debugging - should never be found in valid HDF5 file. */ -H5_DLLVAR const H5O_class_t H5O_BOGUS[1]; +H5_DLLVAR const H5O_msg_class_t H5O_MSG_BOGUS[1]; #endif /* H5O_ENABLE_BOGUS */ -/* - * Group Information Message. (0x000a) - */ -H5_DLLVAR const H5O_class_t H5O_GINFO[1]; +/* Group Information Message. (0x000a) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_GINFO[1]; -/* - * Filter pipeline message. (0x000b) - */ -H5_DLLVAR const H5O_class_t H5O_PLINE[1]; +/* Filter pipeline message. (0x000b) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_PLINE[1]; -/* - * Attribute Message. (0x000c) - */ -H5_DLLVAR const H5O_class_t H5O_ATTR[1]; +/* Attribute Message. (0x000c) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_ATTR[1]; -/* - * Object name message. (0x000d) - */ -H5_DLLVAR const H5O_class_t H5O_NAME[1]; +/* Object name message. (0x000d) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_NAME[1]; +/* Modification Time Message. (0x000e) */ /* - * Modification Time Message. (0x000e) - * * The message is just a `time_t'. * (See also the "new" modification time message) */ -H5_DLLVAR const H5O_class_t H5O_MTIME[1]; +H5_DLLVAR const H5O_msg_class_t H5O_MSG_MTIME[1]; -/* - * Shared Object Message. (0x000f) - * +/* Shared Object Message. (0x000f) */ +/* * This message ID never really appears in an object * header. Instead, bit 2 of the `Flags' field will be set and the ID field * will be the ID of the pointed-to message. */ -H5_DLLVAR const H5O_class_t H5O_SHARED[1]; +H5_DLLVAR const H5O_msg_class_t H5O_MSG_SHARED[1]; -/* - * Object Header Continuation Message. (0x0010) - */ -H5_DLLVAR const H5O_class_t H5O_CONT[1]; +/* Object Header Continuation Message. (0x0010) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_CONT[1]; -/* - * Symbol Table Message. (0x0011) +/* Symbol Table Message. (0x0011) */ +H5_DLLVAR const H5O_msg_class_t H5O_MSG_STAB[1]; + +/* New Modification Time Message. (0x0012) */ +/* + * The message is just a `time_t'. */ -H5_DLLVAR const H5O_class_t H5O_STAB[1]; +H5_DLLVAR const H5O_msg_class_t H5O_MSG_MTIME_NEW[1]; + /* - * New Modification Time Message. (0x0012) - * - * The message is just a `time_t'. + * Object header "object" types */ -H5_DLLVAR const H5O_class_t H5O_MTIME_NEW[1]; + +/* Group Object. (H5G_GROUP - 0) */ +H5_DLLVAR const H5O_obj_class_t H5O_OBJ_GROUP[1]; + +/* Dataset Object. (H5G_DATASET - 1) */ +H5_DLLVAR const H5O_obj_class_t H5O_OBJ_DATASET[1]; + +/* Datatype Object. (H5G_TYPE - 2) */ +H5_DLLVAR const H5O_obj_class_t H5O_OBJ_DATATYPE[1]; + /* Package-local function prototypes */ -H5_DLL void * H5O_read_real(const H5O_loc_t *loc, const H5O_class_t *type, +H5_DLL herr_t H5O_flush_msgs(H5F_t *f, H5O_t *oh); +H5_DLL void * H5O_read_real(const H5O_loc_t *loc, const H5O_msg_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 void * H5O_free_real(const H5O_msg_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); + const H5O_msg_class_t *type, void *mesg); /* Useful metadata cache callbacks */ H5_DLL herr_t H5O_dest(H5F_t *f, H5O_t *oh); diff --git a/src/H5Opline.c b/src/H5Opline.c index d7fec7e..9b6f147 100644 --- a/src/H5Opline.c +++ b/src/H5Opline.c @@ -39,8 +39,8 @@ static herr_t H5O_pline_free (void *_mesg); static herr_t H5O_pline_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_PLINE[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_PLINE[1] = {{ H5O_PLINE_ID, /* message id number */ "filter pipeline", /* message name for debugging */ sizeof(H5O_pline_t), /* native message size */ @@ -54,6 +54,7 @@ const H5O_class_t H5O_PLINE[1] = {{ NULL, /* link method */ NULL, /* get share method */ NULL, /* set share method */ + NULL, /* pre copy native value to file */ NULL, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_pline_debug /* debug the message */ diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h index b9c7511..415ef03 100644 --- a/src/H5Oprivate.h +++ b/src/H5Oprivate.h @@ -39,6 +39,10 @@ #include "H5Tprivate.h" /* Datatype functions */ #include "H5Zprivate.h" /* I/O pipeline filters */ +/* Forward references of package typedefs */ +typedef struct H5O_msg_class_t H5O_msg_class_t; +typedef struct H5O_t H5O_t; + /* Object header macros */ #define H5O_MIN_SIZE H5O_ALIGN(32) /*min obj header data size */ #define H5O_MAX_SIZE 65536 /*max obj header data size */ @@ -291,6 +295,7 @@ typedef enum { /* Forward declarations for prototype arguments */ struct H5SL_t; +struct H5O_t; /* General message operators */ H5_DLL herr_t H5O_init(void); @@ -302,6 +307,7 @@ 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 htri_t H5O_exists_oh(struct H5O_t *oh, 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(H5O_loc_t *loc, unsigned type_id, @@ -340,7 +346,7 @@ 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_id(unsigned 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); diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c index e09f029..63eb122 100644 --- a/src/H5Osdspace.c +++ b/src/H5Osdspace.c @@ -34,10 +34,10 @@ static herr_t H5O_sdspace_free (void *_mesg); static herr_t H5O_sdspace_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_SDSPACE[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_SDSPACE[1] = {{ H5O_SDSPACE_ID, /* message id number */ - "simple_dspace", /* message name for debugging */ + "dataspace", /* message name for debugging */ sizeof(H5S_extent_t), /* native message size */ H5O_sdspace_decode, /* decode message */ H5O_sdspace_encode, /* encode message */ @@ -49,6 +49,7 @@ const H5O_class_t H5O_SDSPACE[1] = {{ NULL, /* link method */ NULL, /* get share method */ NULL, /* set share method */ + NULL, /* pre copy native value to file */ NULL, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_sdspace_debug /* debug the message */ diff --git a/src/H5Oshared.c b/src/H5Oshared.c index de58460..a8e8246 100644 --- a/src/H5Oshared.c +++ b/src/H5Oshared.c @@ -46,8 +46,8 @@ static void *H5O_shared_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_shared_debug (H5F_t*, hid_t dxpl_id, const void*, FILE*, int, int); -/* This message derives from H5O */ -const H5O_class_t H5O_SHARED[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_SHARED[1] = {{ H5O_SHARED_ID, /*message id number */ "shared", /*message name for debugging */ sizeof(H5O_shared_t), /*native message size */ @@ -61,6 +61,7 @@ const H5O_class_t H5O_SHARED[1] = {{ H5O_shared_link, /*link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ H5O_shared_copy_file, /* copy native value to file */ NULL, /* post copy native value to file */ H5O_shared_debug /*debug method */ @@ -95,7 +96,7 @@ const H5O_class_t H5O_SHARED[1] = {{ *------------------------------------------------------------------------- */ void * -H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared, const H5O_class_t *type, void *mesg) +H5O_shared_read(H5F_t *f, hid_t dxpl_id, H5O_shared_t *shared, const H5O_msg_class_t *type, void *mesg) { void *ret_value = NULL; /* Return value */ diff --git a/src/H5Ostab.c b/src/H5Ostab.c index b74fd8c..f1e8a25 100644 --- a/src/H5Ostab.c +++ b/src/H5Ostab.c @@ -50,8 +50,8 @@ static herr_t H5O_stab_post_copy_file(H5F_t *file_src, const void *mesg_src, static herr_t H5O_stab_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_STAB[1] = {{ +/* This message derives from H5O message class */ +const H5O_msg_class_t H5O_MSG_STAB[1] = {{ H5O_STAB_ID, /*message id number */ "stab", /*message name for debugging */ sizeof(H5O_stab_t), /*native message size */ @@ -65,6 +65,7 @@ const H5O_class_t H5O_STAB[1] = {{ NULL, /* link method */ NULL, /*get share method */ NULL, /*set share method */ + NULL, /* pre copy native value to file */ H5O_stab_copy_file, /* copy native value to file */ H5O_stab_post_copy_file, /* post copy native value to file */ H5O_stab_debug /*debug the message */ diff --git a/src/H5T.c b/src/H5T.c index cb96e42..ea03576 100644 --- a/src/H5T.c +++ b/src/H5T.c @@ -2965,40 +2965,6 @@ done: /*------------------------------------------------------------------------- - * Function: H5T_isa - * - * Purpose: Determines if an object has the requisite messages for being - * a datatype. - * - * Return: Success: TRUE if the required data type messages are - * present; FALSE otherwise. - * - * Failure: FAIL if the existence of certain messages - * cannot be determined. - * - * Programmer: Robb Matzke - * Monday, November 2, 1998 - * - *------------------------------------------------------------------------- - */ -htri_t -H5T_isa(H5O_loc_t *loc, hid_t dxpl_id) -{ - htri_t ret_value; - - FUNC_ENTER_NOAPI(H5T_isa, FAIL) - - HDassert(loc); - - 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: - FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_isa() */ - - -/*------------------------------------------------------------------------- * Function: H5T_copy * * Purpose: Copies datatype OLD_DT. The resulting data type is not diff --git a/src/H5Toh.c b/src/H5Toh.c new file mode 100644 index 0000000..5e86c30 --- /dev/null +++ b/src/H5Toh.c @@ -0,0 +1,95 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * 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. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/****************/ +/* Module Setup */ +/****************/ + +#define H5O_PACKAGE /*suppress error about including H5Opkg */ + +/***********/ +/* Headers */ +/***********/ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Opkg.h" /* Object headers */ + +/****************/ +/* Local Macros */ +/****************/ + +/******************/ +/* Local Typedefs */ +/******************/ + +/********************/ +/* Local Prototypes */ +/********************/ +static htri_t H5O_dtype_isa(H5O_t *loc); + +/*********************/ +/* Package Variables */ +/*********************/ + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + +/*******************/ +/* Local Variables */ +/*******************/ + +/* This message derives from H5O object class */ +const H5O_obj_class_t H5O_OBJ_DATATYPE[1] = {{ + H5G_TYPE, /* object type */ + "named datatype", /* object name, for debugging */ + NULL, /* get 'copy file' user data */ + NULL, /* free 'copy file' user data */ + H5O_dtype_isa /* "isa" */ +}}; + + +/*------------------------------------------------------------------------- + * Function: H5O_dtype_isa + * + * Purpose: Determines if an object has the requisite messages for being + * a datatype. + * + * Return: Success: TRUE if the required data type messages are + * present; FALSE otherwise. + * + * Failure: FAIL if the existence of certain messages + * cannot be determined. + * + * Programmer: Robb Matzke + * Monday, November 2, 1998 + * + *------------------------------------------------------------------------- + */ +htri_t +H5O_dtype_isa(struct H5O_t *oh) +{ + htri_t ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5O_dtype_isa, FAIL) + + HDassert(oh); + + if((ret_value = H5O_exists_oh(oh, H5O_DTYPE_ID, 0)) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to read object header") + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5O_dtype_isa() */ + diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 62a4e13..2fb6b54 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -63,10 +63,12 @@ typedef struct H5T_conv_cb_t { void* user_data; } H5T_conv_cb_t; +/* Forward declarations for prototype arguments */ +struct H5O_t; + /* Private functions */ H5_DLL herr_t H5TN_init_interface(void); H5_DLL herr_t H5T_init(void); -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); diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c index e4b40f9..6ae20a7 100644 --- a/src/H5Tvlen.c +++ b/src/H5Tvlen.c @@ -1184,3 +1184,4 @@ H5T_vlen_get_alloc_info(hid_t dxpl_id, H5T_vlen_alloc_info_t **vl_alloc_info) done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5T_vlen_get_alloc_info() */ + diff --git a/src/H5private.h b/src/H5private.h index b86a419..088551e 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -1399,7 +1399,6 @@ 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); @@ -1407,3 +1406,4 @@ H5_DLL int H5T_term_interface(void); H5_DLL int H5Z_term_interface(void); #endif + diff --git a/src/Makefile.am b/src/Makefile.am index 387aea6..bd0108e 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,14 +42,16 @@ libhdf5_la_SOURCES= H5.c H5A.c H5AC.c H5B.c H5Bcache.c H5B2.c H5B2cache.c \ H5B2test.c H5BP.c H5BPcache.c H5BPdbg.c H5BPtest.c \ H5BT.c H5BTbtree2.c H5BTcache.c H5BTdbg.c H5BTtest.c H5C.c \ H5D.c \ - H5Dcontig.c \ H5Dcompact.c \ - H5Defl.c H5Dio.c H5Distore.c H5Dmpio.c H5Dselect.c H5Dtest.c H5E.c H5F.c \ + H5Dcontig.c \ + H5Defl.c H5Dio.c H5Distore.c H5Dmpio.c H5Doh.c H5Dselect.c H5Dtest.c \ + H5E.c H5F.c \ H5Fdbg.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5FD.c H5FDcore.c \ H5FDfamily.c 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 H5Glink.c H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c \ + H5Goh.c \ H5Gstab.c \ H5Gtest.c \ H5Gtraverse.c \ @@ -69,7 +71,8 @@ libhdf5_la_SOURCES= H5.c H5A.c H5AC.c H5B.c H5Bcache.c H5B2.c H5B2cache.c \ H5Sselect.c H5Stest.c H5SH.c H5SHcache.c H5SHdbg.c \ H5SL.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \ H5Tcompound.c H5Tconv.c H5Tcset.c H5Tenum.c H5Tfields.c H5Tfixed.c \ - H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Topaque.c H5Torder.c \ + H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Toh.c H5Topaque.c \ + H5Torder.c \ H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TS.c H5V.c H5Z.c \ H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zszip.c \ H5Zscaleoffset.c H5Ztrans.c diff --git a/src/Makefile.in b/src/Makefile.in index c802bfb..c6d7a85 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -85,31 +85,32 @@ libhdf5_la_LIBADD = am_libhdf5_la_OBJECTS = H5.lo H5A.lo H5AC.lo H5B.lo H5Bcache.lo \ H5B2.lo H5B2cache.lo H5B2dbg.lo H5B2test.lo H5BP.lo \ H5BPcache.lo H5BPdbg.lo H5BPtest.lo H5BT.lo H5BTbtree2.lo \ - H5BTcache.lo H5BTdbg.lo H5BTtest.lo H5C.lo H5D.lo H5Dcontig.lo \ - H5Dcompact.lo H5Defl.lo H5Dio.lo H5Distore.lo H5Dmpio.lo \ - H5Dselect.lo H5Dtest.lo H5E.lo H5F.lo H5Fdbg.lo H5Fmount.lo \ - H5Fsfile.lo H5Fsuper.lo H5FD.lo H5FDcore.lo H5FDfamily.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 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 \ - H5RC.lo H5RS.lo H5S.lo H5Sall.lo H5Shyper.lo H5Smpio.lo \ - H5Snone.lo H5Spoint.lo H5Sselect.lo H5Stest.lo H5SH.lo \ - H5SHcache.lo H5SHdbg.lo H5SL.lo H5ST.lo H5T.lo H5Tarray.lo \ - H5Tbit.lo H5Tcommit.lo H5Tcompound.lo H5Tconv.lo H5Tcset.lo \ - H5Tenum.lo H5Tfields.lo H5Tfixed.lo H5Tfloat.lo H5Tinit.lo \ - H5Tnative.lo H5Toffset.lo H5Topaque.lo H5Torder.lo H5Tpad.lo \ - H5Tprecis.lo H5Tstrpad.lo H5Tvlen.lo H5TS.lo H5V.lo H5Z.lo \ - H5Zdeflate.lo H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo \ - H5Zszip.lo H5Zscaleoffset.lo H5Ztrans.lo + H5BTcache.lo H5BTdbg.lo H5BTtest.lo H5C.lo H5D.lo \ + H5Dcompact.lo H5Dcontig.lo H5Defl.lo H5Dio.lo H5Distore.lo \ + H5Dmpio.lo H5Doh.lo H5Dselect.lo H5Dtest.lo H5E.lo H5F.lo \ + H5Fdbg.lo H5Fmount.lo H5Fsfile.lo H5Fsuper.lo H5FD.lo \ + H5FDcore.lo H5FDfamily.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 \ + H5Glink.lo H5Gloc.lo H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.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 H5RC.lo H5RS.lo H5S.lo H5Sall.lo \ + H5Shyper.lo H5Smpio.lo H5Snone.lo H5Spoint.lo H5Sselect.lo \ + H5Stest.lo H5SH.lo H5SHcache.lo H5SHdbg.lo H5SL.lo H5ST.lo \ + H5T.lo H5Tarray.lo H5Tbit.lo H5Tcommit.lo H5Tcompound.lo \ + H5Tconv.lo H5Tcset.lo H5Tenum.lo H5Tfields.lo H5Tfixed.lo \ + H5Tfloat.lo H5Tinit.lo H5Tnative.lo H5Toffset.lo H5Toh.lo \ + H5Topaque.lo H5Torder.lo H5Tpad.lo H5Tprecis.lo H5Tstrpad.lo \ + H5Tvlen.lo H5TS.lo H5V.lo H5Z.lo H5Zdeflate.lo \ + H5Zfletcher32.lo H5Znbit.lo H5Zshuffle.lo H5Zszip.lo \ + H5Zscaleoffset.lo H5Ztrans.lo libhdf5_la_OBJECTS = $(am_libhdf5_la_OBJECTS) PROGRAMS = $(noinst_PROGRAMS) H5detect_SOURCES = H5detect.c @@ -395,14 +396,16 @@ libhdf5_la_SOURCES = H5.c H5A.c H5AC.c H5B.c H5Bcache.c H5B2.c H5B2cache.c \ H5B2test.c H5BP.c H5BPcache.c H5BPdbg.c H5BPtest.c \ H5BT.c H5BTbtree2.c H5BTcache.c H5BTdbg.c H5BTtest.c H5C.c \ H5D.c \ - H5Dcontig.c \ H5Dcompact.c \ - H5Defl.c H5Dio.c H5Distore.c H5Dmpio.c H5Dselect.c H5Dtest.c H5E.c H5F.c \ + H5Dcontig.c \ + H5Defl.c H5Dio.c H5Distore.c H5Dmpio.c H5Doh.c H5Dselect.c H5Dtest.c \ + H5E.c H5F.c \ H5Fdbg.c H5Fmount.c H5Fsfile.c H5Fsuper.c H5FD.c H5FDcore.c \ H5FDfamily.c 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 H5Glink.c H5Gloc.c H5Gname.c H5Gnode.c H5Gobj.c \ + H5Goh.c \ H5Gstab.c \ H5Gtest.c \ H5Gtraverse.c \ @@ -422,7 +425,8 @@ libhdf5_la_SOURCES = H5.c H5A.c H5AC.c H5B.c H5Bcache.c H5B2.c H5B2cache.c \ H5Sselect.c H5Stest.c H5SH.c H5SHcache.c H5SHdbg.c \ H5SL.c H5ST.c H5T.c H5Tarray.c H5Tbit.c H5Tcommit.c \ H5Tcompound.c H5Tconv.c H5Tcset.c H5Tenum.c H5Tfields.c H5Tfixed.c \ - H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Topaque.c H5Torder.c \ + H5Tfloat.c H5Tinit.c H5Tnative.c H5Toffset.c H5Toh.c H5Topaque.c \ + H5Torder.c \ H5Tpad.c H5Tprecis.c H5Tstrpad.c H5Tvlen.c H5TS.c H5V.c H5Z.c \ H5Zdeflate.c H5Zfletcher32.c H5Znbit.c H5Zshuffle.c H5Zszip.c \ H5Zscaleoffset.c H5Ztrans.c @@ -585,6 +589,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Distore.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dmpio.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Doh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dselect.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Dtest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5E.Plo@am__quote@ @@ -618,6 +623,7 @@ distclean-compile: @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)/H5Goh.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@ @@ -689,6 +695,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tinit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tnative.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Toffset.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Toh.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Topaque.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Torder.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Tpad.Plo@am__quote@ diff --git a/test/objcopy.c b/test/objcopy.c index 9d05ead..9a74cef 100755 --- a/test/objcopy.c +++ b/test/objcopy.c @@ -31,6 +31,9 @@ const char *FILENAME[] = { #define FILE_EXT "objcopy_ext.dat" #define NAME_DATATYPE_SIMPLE "H5T_NATIVE_INT" +#define NAME_DATATYPE_SIMPLE2 "H5T_NATIVE_INT-2" +#define NAME_DATATYPE_VL "vlen of int" +#define NAME_DATATYPE_VL_VL "vlen of vlen of int" #define NAME_DATASET_SIMPLE "dataset_simple" #define NAME_DATASET_COMPOUND "dataset_compound" #define NAME_DATASET_CHUNKED "dataset_chunked" @@ -41,18 +44,23 @@ const char *FILENAME[] = { #define NAME_DATASET_MULTI_OHDR "dataset_multi_ohdr" #define NAME_DATASET_MULTI_OHDR2 "dataset_multi_ohdr2" #define NAME_DATASET_VL "dataset_vl" +#define NAME_DATASET_SUB_SUB "/g0/g00/g000/dataset_simple" #define NAME_GROUP_UNCOPIED "/uncopied" #define NAME_GROUP_EMPTY "/empty" #define NAME_GROUP_TOP "/g0" #define NAME_GROUP_SUB "/g0/g00" #define NAME_GROUP_SUB_2 "/g0/g01" #define NAME_GROUP_SUB_SUB "/g0/g00/g000" +#define NAME_GROUP_SUB_SUB2 "g000" #define NAME_GROUP_DATASET "/g0/dataset_simple" #define NAME_GROUP_LINK "/g_links" #define NAME_GROUP_LOOP "g_loop" +#define NAME_GROUP_LOOP2 "g_loop2" +#define NAME_GROUP_LOOP3 "g_loop3" #define NAME_LINK_DATASET "/g_links/dataset_simple" #define NAME_LINK_HARD "/g_links/hard_link_to_dataset_simple" -#define NAME_LINK_SOFT "/g_links/soft_link_to_nowhere" +#define NAME_LINK_SOFT "/g_links/soft_link_to_dataset_simple" +#define NAME_LINK_SOFT_DANGLE "/g_links/soft_link_to_nowhere" #define NAME_BUF_SIZE 1024 #define NUM_ATTRIBUTES 8 @@ -60,6 +68,7 @@ const char *FILENAME[] = { #define DIM_SIZE_1 12 #define DIM_SIZE_2 6 #define NUM_SUB_GROUPS 20 +#define NUM_WIDE_LOOP_GROUPS 10 #define NUM_DATASETS 10 /* Table containing object id and object name */ @@ -390,6 +399,62 @@ error: /*------------------------------------------------------------------------- + * Function: compare_data + * + * Purpose: Compare two buffers of data to check that they are equal + * + * Return: TRUE if buffer are equal/FALSE if they are different + * + * Programmer: Quincey Koziol + * Monday, November 21, 2005 + * + *------------------------------------------------------------------------- + */ +static int +compare_data(hid_t tid, size_t elmt_size, size_t nelmts, void *buf1, void *buf2) +{ + /* Check for references, which aren't handled */ + if(H5Tdetect_class(tid, H5T_REFERENCE) == TRUE) TEST_ERROR + + /* Check for vlen datatype */ + if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) { + hvl_t *vl_buf1, *vl_buf2; /* Aliases for buffers to compare */ + hid_t base_tid; /* Base type of vlen datatype */ + size_t base_size; /* Size of base type */ + size_t u; /* Local index variable */ + + /* Check for "simple" vlen datatype */ + if(H5Tget_class(tid) != H5T_VLEN) TEST_ERROR; + + /* Get base type of vlen datatype */ + if ( (base_tid = H5Tget_super(tid)) < 0) TEST_ERROR + if ( (base_size = H5Tget_size(base_tid)) == 0) TEST_ERROR + + /* Loop over elements in buffers */ + vl_buf1 = buf1; + vl_buf2 = buf2; + for(u = 0; u < nelmts; u++, vl_buf1++, vl_buf2++) { + /* Check vlen lengths */ + if(vl_buf1->len != vl_buf2->len) TEST_ERROR + + /* Check vlen data */ + if(!compare_data(base_tid, base_size, vl_buf1->len, vl_buf1->p, vl_buf2->p)) TEST_ERROR + } /* end for */ + + if(H5Tclose(base_tid) < 0) TEST_ERROR + } /* end if */ + else + if ( HDmemcmp(buf1, buf2, (size_t)(elmt_size * nelmts))) TEST_ERROR + + /* Data should be the same. :-) */ + return TRUE; + +error: + return FALSE; +} /* end compare_data() */ + + +/*------------------------------------------------------------------------- * Function: compare_datasets * * Purpose: Compare two datasets to check that they are equal @@ -406,12 +471,11 @@ compare_datasets(hid_t did, hid_t did2, void *wbuf) { hid_t sid = -1, sid2 = -1; /* Dataspace IDs */ hid_t tid = -1, tid2 = -1; /* Datatype IDs */ - hid_t tmp_tid = -1; /* Temporary datatype ID for reading data */ hid_t dcpl = -1, dcpl2 = -1; /* Dataset creation property list IDs */ - size_t elem_size; /* Size of datatype */ + size_t elmt_size; /* Size of datatype */ htri_t is_committed; /* If the datatype is committed */ htri_t is_committed2; /* If the datatype is committed */ - hssize_t nelem; /* # of elements in dataspace */ + hssize_t nelmts; /* # of elements in dataspace */ void *rbuf = NULL; /* Buffer for reading raw data */ void *rbuf2 = NULL; /* Buffer for reading raw data */ H5D_space_status_t space_status; /* Dataset's raw data space status */ @@ -436,16 +500,7 @@ compare_datasets(hid_t did, hid_t did2, void *wbuf) if ( H5Tequal(tid, tid2) != TRUE) TEST_ERROR; /* Determine the size of datatype (for later) */ - if ( (elem_size = H5Tget_size(tid)) == 0) TEST_ERROR; - - /* Make copy of the datatype (for later) */ - if ( (tmp_tid = H5Tcopy(tid)) < 0) TEST_ERROR; - - /* close the source datatype */ - if ( H5Tclose(tid) < 0) TEST_ERROR; - - /* close the destination datatype */ - if ( H5Tclose(tid2) < 0) TEST_ERROR; + if ( (elmt_size = H5Tget_size(tid)) == 0) TEST_ERROR /* Check the dataspaces are equal */ @@ -460,13 +515,7 @@ compare_datasets(hid_t did, hid_t did2, void *wbuf) if ( H5Sextent_equal(sid, sid2) != TRUE) TEST_ERROR; /* Determine the number of elements in dataspace (for later) */ - if ( (nelem = H5Sget_simple_extent_npoints(sid)) < 0) TEST_ERROR - - /* close the source dataspace */ - if ( H5Sclose(sid) < 0) TEST_ERROR; - - /* close the destination dataspace */ - if ( H5Sclose(sid2) < 0) TEST_ERROR; + if ( (nelmts = H5Sget_simple_extent_npoints(sid)) < 0) TEST_ERROR /* Check the dataset creation property lists are equal */ @@ -503,28 +552,43 @@ compare_datasets(hid_t did, hid_t did2, void *wbuf) /* Check the raw data is equal */ /* Allocate & initialize space for the raw data buffers */ - if ( (rbuf = HDcalloc( elem_size, (size_t)nelem)) == NULL) TEST_ERROR; - if ( (rbuf2 = HDcalloc( elem_size, (size_t)nelem)) == NULL) TEST_ERROR; + if ( (rbuf = HDcalloc( elmt_size, (size_t)nelmts)) == NULL) TEST_ERROR; + if ( (rbuf2 = HDcalloc( elmt_size, (size_t)nelmts)) == NULL) TEST_ERROR; /* Read data from datasets */ - if ( H5Dread(did, tmp_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) TEST_ERROR; - if ( H5Dread(did2, tmp_tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR; + if ( H5Dread(did, tid, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf) < 0) TEST_ERROR; + if ( H5Dread(did2, tid2, H5S_ALL, H5S_ALL, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR; /* Check raw data read in against data written out */ if(wbuf) { - if ( HDmemcmp(wbuf, rbuf, (size_t)(elem_size * nelem))) TEST_ERROR - if ( HDmemcmp(wbuf, rbuf2, (size_t)(elem_size * nelem))) TEST_ERROR + if ( !compare_data(tid, elmt_size, (size_t)nelmts, wbuf, rbuf)) TEST_ERROR + if ( !compare_data(tid2, elmt_size, (size_t)nelmts, wbuf, rbuf2)) TEST_ERROR } /* end if */ /* Don't have written data, just compare data between the two datasets */ else - if ( HDmemcmp(rbuf, rbuf2, (size_t)(elem_size * nelem))) TEST_ERROR + if ( !compare_data(tid, elmt_size, (size_t)nelmts, rbuf, rbuf2)) TEST_ERROR + + /* Reclaim vlen data, if necessary */ + if(H5Tdetect_class(tid, H5T_VLEN) == TRUE) + if(H5Dvlen_reclaim(tid, sid, H5P_DEFAULT, rbuf) < 0) TEST_ERROR + if(H5Tdetect_class(tid2, H5T_VLEN) == TRUE) + if(H5Dvlen_reclaim(tid2, sid2, H5P_DEFAULT, rbuf2) < 0) TEST_ERROR /* Release raw data buffers */ HDfree(rbuf); HDfree(rbuf2); - /* Release temporary datatype */ - if ( H5Tclose(tmp_tid) < 0) TEST_ERROR; + /* close the source dataspace */ + if ( H5Sclose(sid) < 0) TEST_ERROR; + + /* close the destination dataspace */ + if ( H5Sclose(sid2) < 0) TEST_ERROR; + + /* close the source datatype */ + if ( H5Tclose(tid) < 0) TEST_ERROR; + + /* close the destination datatype */ + if ( H5Tclose(tid2) < 0) TEST_ERROR; /* Check if the attributes are equal */ @@ -544,7 +608,6 @@ error: H5Pclose(dcpl); H5Sclose(sid2); H5Sclose(sid); - H5Tclose(tmp_tid); H5Tclose(tid2); H5Tclose(tid); } H5E_END_TRY; @@ -783,6 +846,198 @@ error: /*------------------------------------------------------------------------- + * Function: test_copy_named_datatype_vl + * + * Purpose: Create name vlen datatype in SRC file and copy it to DST file + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Quincey Koziol + * Tuesday, November 22, 2005 + * + *------------------------------------------------------------------------- + */ +static int +test_copy_named_datatype_vl(hid_t fapl) +{ + hid_t fid_src = -1, fid_dst = -1; /* File IDs */ + hid_t tid = -1, tid2 = -1; /* Datatype IDs */ + char src_filename[NAME_BUF_SIZE]; + char dst_filename[NAME_BUF_SIZE]; + + TESTING("H5Gcopy(): named vlen datatype"); + + /* Initialize the filenames */ + h5_fixname(FILENAME[0], fapl, src_filename, sizeof src_filename); + h5_fixname(FILENAME[1], fapl, dst_filename, sizeof dst_filename); + + /* Reset file address checking info */ + addr_reset(); + + /* create source file */ + if ( (fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; + + /* create datatype */ + if ( (tid = H5Tvlen_create(H5T_NATIVE_INT)) < 0) TEST_ERROR; + + /* create named datatype */ + if ( (H5Tcommit(fid_src, NAME_DATATYPE_VL, tid)) < 0) TEST_ERROR; + + /* close the datatype */ + if ( H5Tclose(tid) < 0) TEST_ERROR; + + /* close the SRC file */ + if ( H5Fclose(fid_src) < 0) TEST_ERROR; + + + /* open the source file with read-only */ + if ( (fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR; + + /* create destination file */ + if ( (fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; + + /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + if ( H5Gclose(H5Gcreate(fid_dst, NAME_GROUP_UNCOPIED, (size_t)0)) < 0) TEST_ERROR; + + /* open the datatype for copy */ + if ( (tid = H5Topen(fid_src, NAME_DATATYPE_VL)) < 0) TEST_ERROR; + + /* copy the datatype from SRC to DST */ + if ( H5Gcopy(tid, fid_dst, NAME_DATATYPE_VL, H5P_DEFAULT) < 0) TEST_ERROR; + + /* open the copied datatype */ + if ( (tid2 = H5Topen(fid_dst, NAME_DATATYPE_VL)) < 0) TEST_ERROR; + + /* Compare the datatypes */ + if ( H5Tequal(tid, tid2) != TRUE) TEST_ERROR; + + /* close the destination datatype */ + if ( H5Tclose(tid2) < 0) TEST_ERROR; + + /* close the source datatype */ + if ( H5Tclose(tid) < 0) TEST_ERROR; + + /* close the SRC file */ + if ( H5Fclose(fid_src) < 0) TEST_ERROR; + + /* close the DST file */ + if ( H5Fclose(fid_dst) < 0) TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Tclose(tid2); + H5Tclose(tid); + H5Fclose(fid_dst); + H5Fclose(fid_src); + } H5E_END_TRY; + return 1; +} /* end test_copy_named_datatype_vl */ + + +/*------------------------------------------------------------------------- + * Function: test_copy_named_datatype_vl_vl + * + * Purpose: Create named vlen of vlen datatype in SRC file and copy it to DST file + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Quincey Koziol + * Tuesday, November 22, 2005 + * + *------------------------------------------------------------------------- + */ +static int +test_copy_named_datatype_vl_vl(hid_t fapl) +{ + hid_t fid_src = -1, fid_dst = -1; /* File IDs */ + hid_t tid = -1, tid2 = -1; /* Datatype IDs */ + char src_filename[NAME_BUF_SIZE]; + char dst_filename[NAME_BUF_SIZE]; + + TESTING("H5Gcopy(): named nested vlen datatype"); + + /* Initialize the filenames */ + h5_fixname(FILENAME[0], fapl, src_filename, sizeof src_filename); + h5_fixname(FILENAME[1], fapl, dst_filename, sizeof dst_filename); + + /* Reset file address checking info */ + addr_reset(); + + /* create source file */ + if ( (fid_src = H5Fcreate(src_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; + + /* create first vlen datatype */ + if ( (tid = H5Tvlen_create(H5T_NATIVE_INT)) < 0) TEST_ERROR; + + /* create second (nested) vlen datatype */ + if ( (tid2 = H5Tvlen_create(tid)) < 0) TEST_ERROR; + + /* create named datatype */ + if ( (H5Tcommit(fid_src, NAME_DATATYPE_VL_VL, tid2)) < 0) TEST_ERROR; + + /* close the first datatype */ + if ( H5Tclose(tid) < 0) TEST_ERROR; + + /* close the second datatype */ + if ( H5Tclose(tid2) < 0) TEST_ERROR; + + /* close the SRC file */ + if ( H5Fclose(fid_src) < 0) TEST_ERROR; + + + /* open the source file with read-only */ + if ( (fid_src = H5Fopen(src_filename, H5F_ACC_RDONLY, fapl)) < 0) TEST_ERROR; + + /* create destination file */ + if ( (fid_dst = H5Fcreate(dst_filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; + + /* Create an uncopied object in destination file so that addresses in source and destination files aren't the same */ + if ( H5Gclose(H5Gcreate(fid_dst, NAME_GROUP_UNCOPIED, (size_t)0)) < 0) TEST_ERROR; + + /* open the datatype for copy */ + if ( (tid = H5Topen(fid_src, NAME_DATATYPE_VL_VL)) < 0) TEST_ERROR; + + /* copy the datatype from SRC to DST */ + if ( H5Gcopy(tid, fid_dst, NAME_DATATYPE_VL_VL, H5P_DEFAULT) < 0) TEST_ERROR; + + /* open the copied datatype */ + if ( (tid2 = H5Topen(fid_dst, NAME_DATATYPE_VL_VL)) < 0) TEST_ERROR; + + /* Compare the datatypes */ + if ( H5Tequal(tid, tid2) != TRUE) TEST_ERROR; + + /* close the destination datatype */ + if ( H5Tclose(tid2) < 0) TEST_ERROR; + + /* close the source datatype */ + if ( H5Tclose(tid) < 0) TEST_ERROR; + + /* close the SRC file */ + if ( H5Fclose(fid_src) < 0) TEST_ERROR; + + /* close the DST file */ + if ( H5Fclose(fid_dst) < 0) TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Tclose(tid2); + H5Tclose(tid); + H5Fclose(fid_dst); + H5Fclose(fid_src); + } H5E_END_TRY; + return 1; +} /* end test_copy_named_datatype_vl */ + + +/*------------------------------------------------------------------------- * Function: test_copy_dataset_simple * * Purpose: Create a simple dataset in SRC file and copy it to DST file @@ -1158,7 +1413,7 @@ test_copy_dataset_chunked(hid_t fapl) { hid_t fid_src = -1, fid_dst = -1; /* File IDs */ hid_t sid = -1; /* Dataspace ID */ - hid_t pid = -1; /* Datasset creation property list ID */ + hid_t pid = -1; /* Dataset creation property list ID */ hid_t did = -1, did2 = -1; /* Dataset IDs */ hsize_t dim2d[2]; /* Dataset dimensions */ hsize_t chunk_dim2d[2] ={2, 3}; /* Chunk dimensions */ @@ -1285,7 +1540,7 @@ test_copy_dataset_chunked_empty(hid_t fapl) { hid_t fid_src = -1, fid_dst = -1; /* File IDs */ hid_t sid = -1; /* Dataspace ID */ - hid_t pid = -1; /* Datasset creation property list ID */ + hid_t pid = -1; /* Dataset creation property list ID */ hid_t did = -1, did2 = -1; /* Dataset IDs */ hsize_t dim2d[2]; /* Dataset dimensions */ hsize_t chunk_dim2d[2] ={2, 3}; /* Chunk dimensions */ @@ -1380,7 +1635,7 @@ error: H5Fclose(fid_src); } H5E_END_TRY; return 1; -} /* end test_copy_dataset_chunked */ +} /* end test_copy_dataset_chunked_empty */ /*------------------------------------------------------------------------- @@ -1402,7 +1657,7 @@ test_copy_dataset_chunked_sparse(hid_t fapl) { hid_t fid_src = -1, fid_dst = -1; /* File IDs */ hid_t sid = -1; /* Dataspace ID */ - hid_t pid = -1; /* Datasset creation property list ID */ + hid_t pid = -1; /* Dataset creation property list ID */ hid_t did = -1, did2 = -1; /* Dataset IDs */ hsize_t dim2d[2]; /* Dataset dimensions */ hsize_t new_dim2d[2]; /* Dataset dimensions */ @@ -1520,7 +1775,6 @@ error: return 1; } /* end test_copy_dataset_chunked_sparse */ -#ifdef H5_HAVE_FILTER_DEFLATE /*------------------------------------------------------------------------- * Function: test_copy_dataset_compressed @@ -1538,9 +1792,10 @@ error: static int test_copy_dataset_compressed(hid_t fapl) { +#ifdef H5_HAVE_FILTER_DEFLATE hid_t fid_src = -1, fid_dst = -1; /* File IDs */ hid_t sid = -1; /* Dataspace ID */ - hid_t pid = -1; /* Datasset creation property list ID */ + hid_t pid = -1; /* Dataset creation property list ID */ hid_t did = -1, did2 = -1; /* Dataset IDs */ hsize_t dim2d[2]; /* Dataset dimensions */ hsize_t chunk_dim2d[2] ={2, 3}; /* Chunk dimensions */ @@ -1548,9 +1803,14 @@ test_copy_dataset_compressed(hid_t fapl) int i, j; /* Local index variables */ char src_filename[NAME_BUF_SIZE]; char dst_filename[NAME_BUF_SIZE]; +#endif /* H5_HAVE_FILTER_DEFLATE */ TESTING("H5Gcopy(): compressed dataset"); +#ifndef H5_HAVE_FILTER_DEFLATE + SKIPPED(); + puts(" Deflation filter not available"); +#else /* H5_HAVE_FILTER_DEFLATE */ /* set initial data values */ for (i=0; i= 0) TEST_ERROR; + + /* close the source dataset */ + if ( H5Dclose(did) < 0) TEST_ERROR; + + /* close the SRC file */ + if ( H5Fclose(fid_src) < 0) TEST_ERROR; + + /* close the DST file */ + if ( H5Fclose(fid_dst) < 0) TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Dclose(did); + H5Sclose(sid); + H5Fclose(fid_dst); + H5Fclose(fid_src); + } H5E_END_TRY; + return 1; +} /* end test_copy_exist */ + + +/*------------------------------------------------------------------------- + * Function: test_copy_path + * + * Purpose: Create a simple dataset in SRC file and copy it to DST file + * using a full path name + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Quincey Koziol + * Tuesday, November 8, 2005 + * + *------------------------------------------------------------------------- + */ +static int +test_copy_path(hid_t fapl) +{ + hid_t fid_src = -1, fid_dst = -1; /* File IDs */ + hid_t sid = -1; /* Dataspace ID */ + hid_t did = -1, did2 = -1; /* Dataset IDs */ + hid_t gid = -1; /* Group ID */ + int buf[DIM_SIZE_1][DIM_SIZE_2]; /* Buffer for writing data */ + hsize_t dim2d[2]; /* Dataset dimensions */ + int i, j; /* local index variables */ + herr_t ret; /* Generic return value */ + char src_filename[NAME_BUF_SIZE]; + char dst_filename[NAME_BUF_SIZE]; + + TESTING("H5Gcopy(): full path"); + + /* Initialize write buffer */ + for (i=0; i= 0) TEST_ERROR; + + /* Create the intermediate groups in destination file */ + if ( (gid = H5Gcreate(fid_dst, NAME_GROUP_TOP, (size_t)0)) < 0) TEST_ERROR; + if ( H5Gclose(gid) < 0) TEST_ERROR; + + if ( (gid = H5Gcreate(fid_dst, NAME_GROUP_SUB, (size_t)0)) < 0) TEST_ERROR; + if ( H5Gclose(gid) < 0) TEST_ERROR; + + if ( (gid = H5Gcreate(fid_dst, NAME_GROUP_SUB_SUB, (size_t)0)) < 0) TEST_ERROR; + if ( H5Gclose(gid) < 0) TEST_ERROR; + + /* copy the dataset from SRC to DST, using full path */ + if ( H5Gcopy(did, fid_dst, NAME_DATASET_SUB_SUB, H5P_DEFAULT) < 0) TEST_ERROR; + + /* open the destination dataset */ + if ( (did2 = H5Dopen(fid_dst, NAME_DATASET_SUB_SUB)) < 0) TEST_ERROR; + + /* Check if the datasets are equal */ + if ( compare_datasets(did, did2, buf) != TRUE) TEST_ERROR; + + /* close the destination dataset */ + if ( H5Dclose(did2) < 0) TEST_ERROR; + + /* close the source dataset */ + if ( H5Dclose(did) < 0) TEST_ERROR; + + /* close the SRC file */ + if ( H5Fclose(fid_src) < 0) TEST_ERROR; + + /* close the DST file */ + if ( H5Fclose(fid_dst) < 0) TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Dclose(did2); + H5Dclose(did); + H5Sclose(sid); + H5Gclose(gid); + H5Fclose(fid_dst); + H5Fclose(fid_src); + } H5E_END_TRY; + return 1; +} /* end test_copy_path */ + + +/*------------------------------------------------------------------------- + * Function: test_copy_same_file_named_datatype + * + * Purpose: Create name datatype in SRC file and copy it to same file + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Quincey Koziol + * Tuesday, November 8, 2005 + * + *------------------------------------------------------------------------- + */ +static int +test_copy_same_file_named_datatype(hid_t fapl) +{ + hid_t fid = -1; /* File ID */ + hid_t tid = -1, tid2 = -1; /* Datatype IDs */ + char filename[NAME_BUF_SIZE]; + + TESTING("H5Gcopy(): named datatype in same file"); + + /* Initialize the filenames */ + h5_fixname(FILENAME[0], fapl, filename, sizeof filename); + + /* Reset file address checking info */ + addr_reset(); + + /* create source file */ + if ( (fid = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR; + + /* create datatype */ + if ( (tid = H5Tcopy(H5T_NATIVE_INT)) < 0) TEST_ERROR; + + /* create named datatype */ + if ( (H5Tcommit(fid, NAME_DATATYPE_SIMPLE, tid)) < 0) TEST_ERROR; + + + /* copy the datatype from SRC to DST */ + if ( H5Gcopy(tid, fid, NAME_DATATYPE_SIMPLE2, H5P_DEFAULT) < 0) TEST_ERROR; + + /* open the copied datatype */ + if ( (tid2 = H5Topen(fid, NAME_DATATYPE_SIMPLE2)) < 0) TEST_ERROR; + + /* Compare the datatypes */ + if ( H5Tequal(tid, tid2) != TRUE) TEST_ERROR; + + /* close the destination datatype */ + if ( H5Tclose(tid2) < 0) TEST_ERROR; + + /* close the source datatype */ + if ( H5Tclose(tid) < 0) TEST_ERROR; + + /* close the file */ + if ( H5Fclose(fid) < 0) TEST_ERROR; + + PASSED(); + return 0; + +error: + H5E_BEGIN_TRY { + H5Tclose(tid2); + H5Tclose(tid); + H5Fclose(fid); + } H5E_END_TRY; + return 1; +} /* end test_copy_same_file_named_datatype */ + + +/*------------------------------------------------------------------------- + * Function: test_copy_mount + * + * Purpose: Test copying objects between mounted files + * + * Return: Success: 0 + * Failure: number of errors + * + * Programmer: Quincey Koziol + * Saturday, November 5, 2005 + * + *------------------------------------------------------------------------- + */ +static int +test_copy_mount(hid_t fapl) +{ + TESTING("H5Gcopy(): objects between mounted files"); + + SKIPPED(); + puts(" Not tested yet!!"); + return 0; +} /* end test_copy_mount */ + + /*------------------------------------------------------------------------- * Function: main * @@ -3379,15 +4358,15 @@ main(void) /* The tests... */ nerrors += test_copy_named_datatype(fapl); + nerrors += test_copy_named_datatype_vl(fapl); + nerrors += test_copy_named_datatype_vl_vl(fapl); nerrors += test_copy_dataset_simple(fapl); nerrors += test_copy_dataset_simple_empty(fapl); nerrors += test_copy_dataset_compound(fapl); nerrors += test_copy_dataset_chunked(fapl); nerrors += test_copy_dataset_chunked_empty(fapl); nerrors += test_copy_dataset_chunked_sparse(fapl); -#ifdef H5_HAVE_FILTER_DEFLATE nerrors += test_copy_dataset_compressed(fapl); -#endif /* H5_HAVE_FILTER_DEFLATE */ nerrors += test_copy_dataset_compact(fapl); nerrors += test_copy_dataset_external(fapl); nerrors += test_copy_dataset_named_dtype(fapl); @@ -3395,12 +4374,20 @@ main(void) nerrors += test_copy_dataset_named_dtype_hier_outside(fapl); nerrors += test_copy_dataset_multi_ohdr_chunks(fapl); nerrors += test_copy_dataset_attr_named_dtype(fapl); - nerrors += test_copy_dataset_vl(fapl); /* TODO */ + nerrors += test_copy_dataset_contig_vl(fapl); + nerrors += test_copy_dataset_chunked_vl(fapl); /* TODO */ +/* TODO: Add more tests for copying vlen data */ nerrors += test_copy_group_empty(fapl); nerrors += test_copy_group(fapl); nerrors += test_copy_group_deep(fapl); nerrors += test_copy_group_loop(fapl); - nerrors += test_copy_link(fapl); + nerrors += test_copy_group_wide_loop(fapl); + nerrors += test_copy_group_links(fapl); + nerrors += test_copy_soft_link(fapl); + nerrors += test_copy_exist(fapl); + nerrors += test_copy_path(fapl); + nerrors += test_copy_same_file_named_datatype(fapl); +/* TODO: Add more tests for copying objects in same file */ nerrors += test_copy_mount(fapl); /* TODO */ /* TODO: Add more tests for copying objects in mounted files */ -- cgit v0.12