summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorJonathan Kim <jkm@hdfgroup.org>2011-09-20 16:34:01 (GMT)
committerJonathan Kim <jkm@hdfgroup.org>2011-09-20 16:34:01 (GMT)
commit3f1489ee7b4be9e439c93ca8870fb3a0b9eb5c61 (patch)
tree7a3509a114dd983898340233953699d68d2b1955 /tools
parent563722468c739cb997053649524323aa427af297 (diff)
downloadhdf5-3f1489ee7b4be9e439c93ca8870fb3a0b9eb5c61.zip
hdf5-3f1489ee7b4be9e439c93ca8870fb3a0b9eb5c61.tar.gz
hdf5-3f1489ee7b4be9e439c93ca8870fb3a0b9eb5c61.tar.bz2
[svn-r21400] Purpose:
HDFFV-5932 - h5repack breaks files with dimension scales Description: - Fixed h5repack to update values of references(object and region) of attributes in h5repack for 1) references, 2) ARRAY of references, 3) VLEN of references, and 4) COMPOUND of references. - Merged from HDF5 trunk 21393, 21382, 21386, 21389. (support Peter) Tested: jam (linux32-LE), koala (linux64-LE), heiwa (linuxppc64-BE), tejeda (mac32-LE)
Diffstat (limited to 'tools')
-rw-r--r--tools/h5repack/h5repack.c75
-rwxr-xr-xtools/h5repack/h5repack.sh.in4
-rw-r--r--tools/h5repack/h5repack_refs.c418
-rw-r--r--tools/h5repack/testfiles/h5repack_attr_refs.h5bin0 -> 10112 bytes
4 files changed, 333 insertions, 164 deletions
diff --git a/tools/h5repack/h5repack.c b/tools/h5repack/h5repack.c
index 6672b68..c2cecf1 100644
--- a/tools/h5repack/h5repack.c
+++ b/tools/h5repack/h5repack.c
@@ -105,7 +105,7 @@ int h5repack_init (pack_opt_t *options,
return (options_table_init(&(options->op_tbl)));
}
-
+
/*-------------------------------------------------------------------------
* Function: h5repack_end
*
@@ -119,7 +119,7 @@ int h5repack_end (pack_opt_t *options)
return options_table_free(options->op_tbl);
}
-
+
/*-------------------------------------------------------------------------
* Function: h5repack_addfilter
*
@@ -167,7 +167,7 @@ int h5repack_addfilter(const char* str,
return 0;
}
-
+
/*-------------------------------------------------------------------------
* Function: h5repack_addlayout
*
@@ -233,9 +233,9 @@ int h5repack_addlayout(const char* str,
return 0;
}
-/* Note: The below copy_named_datatype(), named_datatype_free(), copy_attr()
- * were located in h5repack_copy.c as static prior to bugfix1726.
- * Made shared functions as copy_attr() was needed in h5repack_refs.c.
+/* Note: The below copy_named_datatype(), named_datatype_free(), copy_attr()
+ * were located in h5repack_copy.c as static prior to bugfix1726.
+ * Made shared functions as copy_attr() was needed in h5repack_refs.c.
* However copy_attr() may be obsoleted when H5Acopy is available and put back
* others to static in h5repack_copy.c.
*/
@@ -266,21 +266,21 @@ hid_t copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_hea
if(H5Oget_info(type_in, &oinfo) < 0)
goto error;
- if(*named_dt_head_p)
+ if(*named_dt_head_p)
{
/* Stack already exists, search for the datatype */
while(dt && dt->addr_in != oinfo.addr)
dt = dt->next;
dt_ret = dt;
- }
- else
+ }
+ else
{
/* Create the stack */
size_t i;
for(i=0; i<travt->nobjs; i++)
- if(travt->objs[i].type == H5TRAV_TYPE_NAMED_DATATYPE)
+ if(travt->objs[i].type == H5TRAV_TYPE_NAMED_DATATYPE)
{
/* Push onto the stack */
if(NULL == (dt = (named_dt_t *) HDmalloc(sizeof(named_dt_t))))
@@ -293,7 +293,7 @@ hid_t copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_hea
dt->id_out = -1;
/* Check if this type is the one requested */
- if(oinfo.addr == dt->addr_in)
+ if(oinfo.addr == dt->addr_in)
{
HDassert(!dt_ret);
dt_ret = dt;
@@ -303,7 +303,7 @@ hid_t copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_hea
/* Handle the case that the requested datatype was not found. This is
* possible if the datatype was committed anonymously in the input file. */
- if(!dt_ret)
+ if(!dt_ret)
{
/* Push the new datatype onto the stack */
if(NULL == (dt_ret = (named_dt_t *) HDmalloc(sizeof(named_dt_t))))
@@ -318,7 +318,7 @@ hid_t copy_named_datatype(hid_t type_in, hid_t fidout, named_dt_t **named_dt_hea
/* If the requested datatype does not yet exist in the output file, copy it
* anonymously */
- if(dt_ret->id_out < 0)
+ if(dt_ret->id_out < 0)
{
if (options->use_native==1)
dt_ret->id_out = h5tools_get_native_type(type_in);
@@ -360,7 +360,7 @@ int named_datatype_free(named_dt_t **named_dt_head_p, int ignore_err)
{
named_dt_t *dt = *named_dt_head_p;
- while(dt)
+ while(dt)
{
/* Pop the datatype off the stack and free it */
if(H5Tclose(dt->id_out) < 0 && !ignore_err)
@@ -413,6 +413,8 @@ int copy_attr(hid_t loc_in,
H5O_info_t oinfo; /* object info */
int j;
unsigned u;
+ hbool_t is_ref=0;
+ H5T_class_t type_class = -1;
if(H5Oget_info(loc_in, &oinfo) < 0)
goto error;
@@ -446,7 +448,7 @@ int copy_attr(hid_t loc_in,
/* Copy named dt */
if((wtype_id = copy_named_datatype(ftype_id, fidout, named_dt_head_p,
- travt, options)) < 0)
+ travt, options)) < 0)
{
H5Fclose(fidout);
goto error;
@@ -462,6 +464,7 @@ int copy_attr(hid_t loc_in,
wtype_id = H5Tcopy(ftype_id);
} /* end else */
+
/* get the dataspace handle */
if((space_id = H5Aget_space(attr_id)) < 0)
goto error;
@@ -478,15 +481,37 @@ int copy_attr(hid_t loc_in,
goto error;
/*-------------------------------------------------------------------------
- * object references are a special case
- * we cannot just copy the buffers, but instead we recreate the reference
- * this is done on a second sweep of the file that just copies
- * the referenced objects
+ * object references are a special case. We cannot just copy the buffers,
+ * but instead we recreate the reference.
+ * This is done on a second sweep of the file that just copies the referenced
+ * objects at copy_refs_attr()
*-------------------------------------------------------------------------
*/
+ type_class = H5Tget_class(wtype_id);
+ is_ref = (type_class == H5T_REFERENCE);
+ if (type_class == H5T_VLEN ||type_class == H5T_ARRAY ) {
+ hid_t base_type = -1;
+ base_type = H5Tget_super(ftype_id);
+ is_ref = (is_ref || (H5Tget_class(base_type)==H5T_REFERENCE));
+ H5Tclose(base_type);
+ }
- if(H5T_REFERENCE == H5Tget_class(wtype_id)) {
- ;
+ if (type_class == H5T_COMPOUND) {
+ int nmembers = H5Tget_nmembers(wtype_id) ;
+ for (j=0; j<nmembers; j++) {
+ hid_t mtid = H5Tget_member_type( wtype_id, j );
+ H5T_class_t mtclass = H5Tget_class(mtid);
+ H5Tclose(mtid);
+
+ if (mtclass==H5T_REFERENCE) {
+ is_ref = 1;
+ break;
+ }
+ } /* for (j=0; i<nmembers; j++) */
+ } /* if (type_class == H5T_COMPOUND) */
+
+ if(is_ref) {
+ ; /* handled by copy_refs_attr() */
}
else {
/*-------------------------------------------------------------------------
@@ -602,20 +627,20 @@ static int check_options(pack_opt_t *options)
switch (options->layout_g)
{
case H5D_COMPACT:
- strcpy(slayout,"compact");
+ HDstrcpy(slayout,"compact");
break;
case H5D_CONTIGUOUS:
- strcpy(slayout,"contiguous");
+ HDstrcpy(slayout,"contiguous");
break;
case H5D_CHUNKED:
- strcpy(slayout,"chunked");
+ HDstrcpy(slayout,"chunked");
break;
case H5D_LAYOUT_ERROR:
case H5D_NLAYOUTS:
error_msg("invalid layout\n");
return -1;
default:
- strcpy(slayout,"invalid layout\n");
+ HDstrcpy(slayout,"invalid layout\n");
return -1;
}
printf(" Apply %s layout to all\n", slayout);
diff --git a/tools/h5repack/h5repack.sh.in b/tools/h5repack/h5repack.sh.in
index 9b31ffe..4164133 100755
--- a/tools/h5repack/h5repack.sh.in
+++ b/tools/h5repack/h5repack.sh.in
@@ -83,6 +83,7 @@ test -d $TESTDIR || mkdir $TESTDIR
# --------------------------------------------------------------------
LIST_HDF5_TEST_FILES="
$SRC_H5REPACK_TESTFILES/h5repack_attr.h5
+$SRC_H5REPACK_TESTFILES/h5repack_attr_refs.h5
$SRC_H5REPACK_TESTFILES/h5repack_deflate.h5
$SRC_H5REPACK_TESTFILES/h5repack_early.h5
$SRC_H5REPACK_TESTFILES/h5repack_ext.h5
@@ -795,6 +796,9 @@ TOOLTEST1 tfamily%05d.h5
# test various references (bug 1814 and 1726)
TOOLTEST h5repack_refs.h5
+# test attribute with various references (bug1797 / HDFFV-5932)
+# the references in attribute of compund or vlen datatype
+TOOLTEST h5repack_attr_refs.h5
if test $nerrors -eq 0 ; then
echo "All $TESTNAME tests passed."
diff --git a/tools/h5repack/h5repack_refs.c b/tools/h5repack/h5repack_refs.c
index 091133e..c6753c1 100644
--- a/tools/h5repack/h5repack_refs.c
+++ b/tools/h5repack/h5repack_refs.c
@@ -27,6 +27,8 @@
static const char* MapIdToName(hid_t refobj_id,trav_table_t *travt);
static int copy_refs_attr(hid_t loc_in, hid_t loc_out, pack_opt_t *options,
trav_table_t *travt, hid_t fidout);
+static herr_t update_ref_value(hid_t obj_id, H5R_type_t ref_type, void *ref_in,
+ hid_t fid_out, void *ref_out, trav_table_t *travt);
/*-------------------------------------------------------------------------
* Function: do_copy_refobjs
@@ -229,7 +231,7 @@ int do_copy_refobjs(hid_t fidin,
* dataset region references
*-------------------------------------------------------------------------
*/
- else if(H5Tequal(mtype_id, H5T_STD_REF_DSETREG))
+ else if(H5Tequal(mtype_id, H5T_STD_REF_DSETREG))
{
hid_t refobj_id;
hdset_reg_ref_t *refbuf = NULL; /* input buffer for region references */
@@ -390,7 +392,7 @@ int do_copy_refobjs(hid_t fidin,
} /* end switch */
} /* end for */
- /* Finalize (link) the stack of named datatypes (if any)
+ /* Finalize (link) the stack of named datatypes (if any)
* This function is paired with copy_named_datatype() which is called
* in copy_attr(), so need to free.
*/
@@ -429,6 +431,15 @@ error:
*
* Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu
*
+ * Modifier: xcao@hdfgroup.org, 9/12/2011
+ * Update values of references(object and region) for the following types:
+ * 1) References,
+ * 2) ARRAY of reference,
+ * 3) VLEN of references.
+ * 4) COMPOUND of references.
+ * This function does not handle references in other complicated structures,
+ * such as references in nested compound datatypes.
+ *
* Date: October, 28, 2003
*
*-------------------------------------------------------------------------
@@ -448,34 +459,95 @@ static int copy_refs_attr(hid_t loc_in,
hid_t mtype_id = -1; /* memory data type ID */
size_t msize; /* memory size of type */
hsize_t nelmts; /* number of elements in dataset */
- int rank; /* rank of dataset */
hsize_t dims[H5S_MAX_RANK];/* dimensions of dataset */
char name[255];
H5O_info_t oinfo; /* Object info */
- int j;
- unsigned u;
+ unsigned u, i, j;
+ int rank;
+ H5T_class_t type_class = -1;
+ hbool_t is_ref=0, is_ref_vlen=0, is_ref_array=0, is_ref_comp=0;
+ void *refbuf = NULL;
+ void *buf = NULL;
+ const char* refname;
+ int *ref_comp_index = NULL;
+ size_t *ref_comp_size = NULL;
+ int ref_comp_field_n = 0;
+
if(H5Oget_info(loc_in, &oinfo) < 0)
goto error;
for(u = 0; u < (unsigned)oinfo.num_attrs; u++)
{
- /*-------------------------------------------------------------------------
- * open
- *-------------------------------------------------------------------------
- */
+ is_ref = is_ref_vlen = is_ref_array = is_ref_comp = 0;
+
/* open attribute */
if((attr_id = H5Aopen_by_idx(loc_in, ".", H5_INDEX_CRT_ORDER, H5_ITER_INC, (hsize_t)u, H5P_DEFAULT, H5P_DEFAULT)) < 0)
goto error;
- /* get name */
- if(H5Aget_name(attr_id, 255, name) < 0)
- goto error;
-
/* get the file datatype */
if((ftype_id = H5Aget_type(attr_id)) < 0)
goto error;
+ type_class = H5Tget_class(ftype_id);
+
+ if((mtype_id = h5tools_get_native_type(ftype_id)) < 0)
+ goto error;
+
+ if((msize = H5Tget_size(mtype_id)) == 0)
+ goto error;
+
+ is_ref = (type_class == H5T_REFERENCE);
+
+ if (type_class == H5T_VLEN ) {
+ hid_t base_type = -1;
+ base_type = H5Tget_super(ftype_id);
+ is_ref_vlen = (H5Tget_class(base_type)==H5T_REFERENCE);
+ msize = H5Tget_size(base_type);
+ H5Tclose(base_type);
+ }
+
+ if (type_class == H5T_ARRAY ) {
+ hid_t base_type = -1;
+ base_type = H5Tget_super(ftype_id);
+ is_ref_array = (H5Tget_class(base_type)==H5T_REFERENCE);
+ msize = H5Tget_size(base_type);
+ H5Tclose(base_type);
+ }
+
+ if (type_class == H5T_COMPOUND) {
+ int nmembers = H5Tget_nmembers(ftype_id) ;
+ if (nmembers < 1)
+ goto error;
+
+ ref_comp_index = (int *)HDmalloc(nmembers*sizeof (int));
+ ref_comp_size = (size_t *)HDmalloc(nmembers*sizeof(ref_comp_size));
+ ref_comp_field_n = 0;
+
+ for (i=0; i<(unsigned)nmembers; i++) {
+ hid_t mtid = H5Tget_member_type( ftype_id, i );
+ if ((H5Tget_class(mtid)==H5T_REFERENCE)) {
+ ref_comp_index[ref_comp_field_n] = i;
+ ref_comp_size[ref_comp_field_n] = H5Tget_size(mtid);
+ ref_comp_field_n++;
+ }
+ H5Tclose(mtid);
+ }
+ }
+
+ is_ref_comp = (ref_comp_field_n > 0);
+
+ if (!(is_ref || is_ref_vlen || is_ref_array || is_ref_comp)) {
+ H5Tclose(mtype_id);
+ H5Tclose(ftype_id);
+ H5Aclose(attr_id);
+ continue;
+ }
+
+ /* get name */
+ if(H5Aget_name(attr_id, 255, name) < 0)
+ goto error;
+
/* get the dataspace handle */
if((space_id = H5Aget_space(attr_id)) < 0)
goto error;
@@ -490,35 +562,32 @@ static int copy_refs_attr(hid_t loc_in,
*-------------------------------------------------------------------------
*/
nelmts = 1;
- for(j = 0; j < rank; j++)
+ for(j = 0; j < (unsigned)rank; j++)
nelmts *= dims[j];
- if((mtype_id = h5tools_get_native_type(ftype_id)) < 0)
- goto error;
-
- if((msize = H5Tget_size(mtype_id)) == 0)
+ if (is_ref_array) {
+ unsigned array_rank = 0;
+ hsize_t array_size = 1;
+ hsize_t array_dims[H5S_MAX_RANK];
+ hid_t base_type = -1;
+ base_type = H5Tget_super(ftype_id);
+ msize = H5Tget_size(base_type);
+ H5Tclose(base_type);
+
+ array_rank = H5Tget_array_ndims(mtype_id);
+ H5Tget_array_dims2(mtype_id, array_dims);
+ for(j = 0; j <array_rank; j++)
+ array_size *= array_dims[j];
+ nelmts *= array_size;
+ }
+
+ if((attr_out = H5Acreate2(loc_out, name, ftype_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0)
goto error;
-
- /*-------------------------------------------------------------------------
- * object references are a special case
- * we cannot just copy the buffers, but instead we recreate the reference
- *-------------------------------------------------------------------------
- */
- if(H5Tequal(mtype_id, H5T_STD_REF_OBJ))
+ if (nelmts>0)
{
- hid_t refobj_id;
- hobj_ref_t *refbuf = NULL;
- unsigned k;
- const char* refname;
- hobj_ref_t *buf = NULL;
-
- /*-------------------------------------------------------------------------
- * read input to memory
- *-------------------------------------------------------------------------
- */
-
- if (nelmts)
+ /* handle object references */
+ if((is_ref || is_ref_array) && (H5R_OBJ_REF_BUF_SIZE==msize))
{
buf = (hobj_ref_t *)HDmalloc((unsigned)(nelmts * msize));
if(buf == NULL)
@@ -536,65 +605,16 @@ static int copy_refs_attr(hid_t loc_in,
goto error;
} /* end if */
- for(k = 0; k < nelmts; k++)
+ for(i = 0; i < (unsigned)nelmts; i++)
{
- H5E_BEGIN_TRY
- {
- if((refobj_id = H5Rdereference(attr_id, H5R_OBJECT, &buf[k])) < 0)
- goto error;
- } H5E_END_TRY;
-
- /* get the name. a valid name could only occur in the
- * second traversal of the file
- */
- if((refname = MapIdToName(refobj_id, travt)) != NULL)
- {
- /* create the reference */
- if(H5Rcreate(&refbuf[k], fidout, refname, H5R_OBJECT, -1) < 0)
- goto error;
- if(options->verbose)
- printf("object <%s> reference created to <%s>\n", name, refname);
- }
- H5Oclose(refobj_id);
+ if (update_ref_value(attr_id, H5R_OBJECT, &((hobj_ref_t *)buf)[i], fidout, &((hobj_ref_t *)refbuf)[i], travt)<0)
+ continue;
+ if(options->verbose)
+ printf("object <%s> reference created to <%s>\n", name, refname);
} /* k */
- } /*nelmts*/
-
- /*-------------------------------------------------------------------------
- * copy
- *-------------------------------------------------------------------------
- */
- if((attr_out = H5Acreate2(loc_out, name, ftype_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0)
- goto error;
- if(nelmts)
- if(H5Awrite(attr_out, mtype_id, refbuf) < 0)
- goto error;
-
- if(H5Aclose(attr_out) < 0)
- goto error;
-
- if(refbuf)
- HDfree(refbuf);
- if(buf)
- HDfree(buf);
- }/*H5T_STD_REF_OBJ*/
-
- /*-------------------------------------------------------------------------
- * dataset region references
- *-------------------------------------------------------------------------
- */
- else if(H5Tequal(mtype_id, H5T_STD_REF_DSETREG))
- {
- hid_t refobj_id;
- hdset_reg_ref_t *refbuf = NULL; /* input buffer for region references */
- hdset_reg_ref_t *buf = NULL; /* output buffer */
- const char* refname;
- unsigned k;
-
- /*-------------------------------------------------------------------------
- * read input to memory
- *-------------------------------------------------------------------------
- */
- if(nelmts)
+ }/*H5T_STD_REF_OBJ*/
+ /* handle region references */
+ else if((is_ref || is_ref_array) && (H5R_DSET_REG_REF_BUF_SIZE == msize))
{
buf = (hdset_reg_ref_t *)HDmalloc((unsigned)(nelmts * msize));
if(buf == NULL)
@@ -616,56 +636,119 @@ static int copy_refs_attr(hid_t loc_in,
goto error;
} /* end if */
- for(k = 0; k < nelmts; k++)
+ for(i = 0; i < (unsigned)nelmts; i++)
{
- H5E_BEGIN_TRY
- {
- if((refobj_id = H5Rdereference(attr_id, H5R_DATASET_REGION, &buf[k])) < 0)
- continue;
- } H5E_END_TRY;
-
- /* get the name. a valid name could only occur in the
- * second traversal of the file
- */
- if((refname = MapIdToName(refobj_id, travt)) != NULL)
- {
- hid_t region_id; /* region id of the referenced dataset */
+ if (update_ref_value(attr_id, H5R_DATASET_REGION, &((hdset_reg_ref_t *)buf)[i], fidout, &((hdset_reg_ref_t *)refbuf)[i], travt)<0)
+ continue;
+ if(options->verbose)
+ printf("object <%s> region reference created to <%s>\n", name, refname);
+ }
+ } /* H5T_STD_REF_DSETREG */
+ else if (is_ref_vlen) {
+ /* handle VLEN of references */
+
+ buf = (hvl_t *)HDmalloc((unsigned)(nelmts * sizeof(hvl_t)));
+ refbuf = buf; /* reuse the read buffer for write */
- if((region_id = H5Rget_region(attr_id, H5R_DATASET_REGION, &buf[k])) < 0)
- goto error;
+ if(buf == NULL)
+ {
+ printf( "cannot read into memory\n" );
+ goto error;
+ } /* end if */
- /* create the reference, we need the space_id */
- if(H5Rcreate(&refbuf[k], fidout, refname, H5R_DATASET_REGION, region_id) < 0)
- goto error;
- if(H5Sclose(region_id) < 0)
- goto error;
- if(options->verbose)
- printf("object <%s> region reference created to <%s>\n", name, refname);
- } /* end if */
- H5Oclose(refobj_id);
- } /* k */
- } /*nelmts */
+ if(H5Aread(attr_id, mtype_id, buf) < 0)
+ goto error;
- /*-------------------------------------------------------------------------
- * copy
- *-------------------------------------------------------------------------
- */
- if((attr_out = H5Acreate2(loc_out, name, ftype_id, space_id, H5P_DEFAULT, H5P_DEFAULT)) < 0)
- goto error;
- if(nelmts)
- {
- if(H5Awrite(attr_out, mtype_id, refbuf) < 0)
+ if (H5R_OBJ_REF_BUF_SIZE==msize) {
+ hobj_ref_t ref_out;
+ for (i=0; i<(unsigned)nelmts; i++) {
+ hobj_ref_t *ptr = (hobj_ref_t *)((hvl_t *)buf)[i].p;
+ for (j=0; j<((hvl_t *)buf)[i].len; j++ ) {
+ if (update_ref_value(attr_id, H5R_OBJECT, &(ptr[j]), fidout, &ref_out, travt)<0)
+ continue;
+ HDmemcpy(&(ptr[j]), &ref_out, msize);
+ }
+ } /* for (i=0; i<nelems; i++) */
+ } else if (H5R_DSET_REG_REF_BUF_SIZE == msize) {
+
+ hdset_reg_ref_t ref_out;
+ for (i=0; i<(unsigned)nelmts; i++) {
+ hdset_reg_ref_t *ptr = (hdset_reg_ref_t *)((hvl_t *)buf)[i].p;
+ for (j=0; j<((hvl_t *)buf)[i].len; j++ ) {
+ if (update_ref_value(attr_id, H5R_DATASET_REGION, &(ptr[j]), fidout, &ref_out, travt)<0)
+ continue;
+ HDmemcpy(&(ptr[j]), &ref_out, msize);
+ }
+ } /* for (i=0; i<nelems; i++) */
+ }
+ } /* else if (is_ref_vlen) */
+ else if (is_ref_comp) {
+ /* handle ref fields in a compound */
+
+ buf = HDmalloc((unsigned)(nelmts * msize));
+ refbuf = buf; /* reuse the read buffer for write */
+
+ if(buf == NULL)
+ {
+ printf( "cannot read into memory\n" );
goto error;
- }
+ } /* end if */
- if(H5Aclose(attr_out) < 0)
- goto error;
+ if(H5Aread(attr_id, mtype_id, buf) < 0)
+ goto error;
- if(refbuf)
- HDfree(refbuf);
- if(buf)
- HDfree(buf);
- } /* H5T_STD_REF_DSETREG */
+ for (i=0; i<(unsigned)nelmts; i++) {
+ for (j=0; j<(unsigned)ref_comp_field_n; j++) {
+ if (ref_comp_size[j] == H5R_OBJ_REF_BUF_SIZE) {
+ int idx = i*msize+H5Tget_member_offset( mtype_id, (unsigned)ref_comp_index[j]);
+ hobj_ref_t ref_out;
+ if (update_ref_value(attr_id, H5R_OBJECT, (hobj_ref_t *)(((char *)buf)+idx), fidout, &ref_out, travt)<0)
+ continue;
+ HDmemcpy(((char *)buf)+idx, &ref_out, ref_comp_size[j]);
+ } /* if */
+ else if (ref_comp_size[j] == H5R_DSET_REG_REF_BUF_SIZE) {
+ int idx = i*msize+H5Tget_member_offset( mtype_id, (unsigned)ref_comp_index[j]);
+ hdset_reg_ref_t ref_out;
+ if (update_ref_value(attr_id, H5R_DATASET_REGION, (hdset_reg_ref_t *)(((char *)buf)+idx), fidout, &ref_out, travt)<0)
+ continue;
+ HDmemcpy(((char *)buf)+idx, &ref_out, ref_comp_size[j]);
+ } /* else if */
+ } /* j */
+ } /* i */
+ } /* else if (is_ref_comp) */
+
+ if(H5Awrite(attr_out, mtype_id, refbuf) < 0)
+ goto error;
+
+ if (is_ref_vlen && buf)
+ H5Dvlen_reclaim (mtype_id, space_id, H5P_DEFAULT, buf);
+ } /* if (nelmts) */
+
+ if (refbuf == buf)
+ refbuf = NULL; /* set it to NULL to avoid double free since buf and refbuf are the same. */
+
+ if(buf) {
+ HDfree(buf);
+ buf = NULL;
+ }
+
+ if(refbuf) {
+ HDfree(refbuf);
+ refbuf = NULL;
+ }
+
+ if (ref_comp_index) {
+ HDfree(ref_comp_index);
+ ref_comp_index = NULL;
+ }
+
+ if (ref_comp_size) {
+ HDfree(ref_comp_size);
+ ref_comp_size = NULL;
+ }
+
+ if(H5Aclose(attr_out) < 0)
+ goto error;
/*-------------------------------------------------------------------------
* close
@@ -679,11 +762,22 @@ static int copy_refs_attr(hid_t loc_in,
goto error;
if(H5Aclose(attr_id) < 0)
goto error;
- } /* u */
+ } /* for(u = 0; u < (unsigned)oinfo.num_attrs; u++) */
return 0;
error:
+ if(refbuf)
+ HDfree(refbuf);
+ if(buf)
+ HDfree(buf);
+
+ if (ref_comp_index)
+ HDfree(ref_comp_index);
+
+ if (ref_comp_size)
+ HDfree(ref_comp_size);
+
H5E_BEGIN_TRY {
H5Tclose(ftype_id);
H5Tclose(mtype_id);
@@ -710,7 +804,7 @@ MapIdToName(hid_t refobj_id, trav_table_t *travt)
/* linear search */
for(u = 0; u < travt->nobjs; u++) {
- if(travt->objs[u].type == H5O_TYPE_DATASET ||
+ if(travt->objs[u].type == H5O_TYPE_DATASET ||
travt->objs[u].type == H5O_TYPE_GROUP ||
travt->objs[u].type == H5O_TYPE_NAMED_DATATYPE) {
H5O_info_t ref_oinfo; /* Stat for the refobj id */
@@ -730,3 +824,49 @@ out:
return ret;
}
+/*-------------------------------------------------------------------------
+ * Function: Update_Ref_value
+ *
+ * Purpose: Update a reference value
+ *
+ * Programmer: xcao@hdfgroup.org 9/12/2011
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t update_ref_value(hid_t obj_id, H5R_type_t ref_type, void *ref_in,
+ hid_t fid_out, void *ref_out, trav_table_t *travt)
+{
+ herr_t ret = -1;
+ const char* ref_obj_name;
+ hid_t space_id=-1, ref_obj_id=-1;
+
+ ref_obj_id = H5Rdereference(obj_id, ref_type, ref_in);
+ if (ref_obj_id<0)
+ goto done;
+
+ ref_obj_name = MapIdToName(ref_obj_id, travt);
+ if (ref_obj_name == NULL)
+ goto done;
+
+ if (ref_type == H5R_DATASET_REGION) {
+ space_id = H5Rget_region(obj_id, H5R_DATASET_REGION, ref_in);
+ if (space_id < 0)
+ goto done;
+ }
+
+ ret = H5Rcreate(ref_out, fid_out, ref_obj_name, ref_type, space_id);
+
+ if (ret < 0)
+ goto done;
+
+ ret = 0;
+
+done:
+ H5E_BEGIN_TRY {
+ H5Sclose(space_id);
+ H5Oclose(ref_obj_id);
+ } H5E_END_TRY;
+
+ return ret;
+}
+
diff --git a/tools/h5repack/testfiles/h5repack_attr_refs.h5 b/tools/h5repack/testfiles/h5repack_attr_refs.h5
new file mode 100644
index 0000000..56974a3
--- /dev/null
+++ b/tools/h5repack/testfiles/h5repack_attr_refs.h5
Binary files differ