summaryrefslogtreecommitdiffstats
path: root/src/H5T.c
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2003-08-11 12:43:04 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2003-08-11 12:43:04 (GMT)
commited92f54f9bae998ffe1f686f4f4ea61cd4bbdade (patch)
treef60eb3cc97b756e34c63a20f030dd981ea44df85 /src/H5T.c
parent8de0645dfa17c22f6a8ee58361f7d4b7ce2755ae (diff)
downloadhdf5-ed92f54f9bae998ffe1f686f4f4ea61cd4bbdade.zip
hdf5-ed92f54f9bae998ffe1f686f4f4ea61cd4bbdade.tar.gz
hdf5-ed92f54f9bae998ffe1f686f4f4ea61cd4bbdade.tar.bz2
[svn-r7334] Purpose:
Bug fix Description: Object references were not getting written out correctly to the file, with recent changes to their memory structure. Solution: Convert the object references correctly. Platforms tested: h5committested
Diffstat (limited to 'src/H5T.c')
-rw-r--r--src/H5T.c179
1 files changed, 168 insertions, 11 deletions
diff --git a/src/H5T.c b/src/H5T.c
index 91431ac..77e585a 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -315,6 +315,7 @@ H5T_init_interface(void)
H5T_t *enum_type=NULL; /* Datatype structure for enum objects */
H5T_t *vlen=NULL; /* Datatype structure for vlen objects */
H5T_t *array=NULL; /* Datatype structure for array objects */
+ H5T_t *objref=NULL; /* Datatype structure for object reference objects */
hsize_t dim[1]={1}; /* Dimension info for array datatype */
herr_t status;
unsigned copied_dtype=1; /* Flag to indicate whether datatype was copied or allocated (for error cleanup) */
@@ -1613,12 +1614,14 @@ H5T_init_interface(void)
dt->ent.header = HADDR_UNDEF;
dt->type = H5T_REFERENCE;
dt->size = H5R_OBJ_REF_BUF_SIZE;
+ dt->force_conv = TRUE;
dt->u.atomic.order = H5T_ORDER_NONE;
dt->u.atomic.offset = 0;
dt->u.atomic.prec = 8 * dt->size;
dt->u.atomic.lsb_pad = H5T_PAD_ZERO;
dt->u.atomic.msb_pad = H5T_PAD_ZERO;
dt->u.atomic.u.r.rtype = H5R_OBJECT;
+ dt->u.atomic.u.r.loc = H5T_LOC_MEMORY;
if ((H5T_STD_REF_OBJ_g = H5I_register(H5I_DATATYPE, dt)) < 0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize H5T layer");
@@ -1664,6 +1667,8 @@ H5T_init_interface(void)
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
if (NULL == (array = H5T_array_create(native_int,1,dim,NULL)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
+ if (NULL == (objref = H5I_object(H5T_STD_REF_OBJ_g)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
if (NULL==(std_u32le=H5I_object(H5T_STD_U32LE_g)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype");
if (NULL==(std_i32le=H5I_object(H5T_STD_I32LE_g)))
@@ -1685,6 +1690,7 @@ H5T_init_interface(void)
status |= H5T_register(H5T_PERS_SOFT, "enum", enum_type, enum_type, H5T_conv_enum, H5AC_dxpl_id);
status |= H5T_register(H5T_PERS_SOFT, "vlen", vlen, vlen, H5T_conv_vlen, H5AC_dxpl_id);
status |= H5T_register(H5T_PERS_SOFT, "array", array, array, H5T_conv_array, H5AC_dxpl_id);
+ status |= H5T_register(H5T_PERS_SOFT, "objref", objref, objref, H5T_conv_order_opt, H5AC_dxpl_id);
/* Custom conversion for 32-bit ints to 64-bit floats (undocumented) */
status |= H5T_register(H5T_PERS_HARD, "u32le_f64le", std_u32le, ieee_f64le, H5T_conv_i32le_f64le, H5AC_dxpl_id);
@@ -3690,10 +3696,11 @@ H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
break;
case H5T_VLEN:
+ case H5T_REFERENCE:
if(method==H5T_COPY_TRANSIENT || method==H5T_COPY_REOPEN) {
- /* H5T_copy converts any VL type into a memory VL type */
- if (H5T_vlen_mark(new_dt, NULL, H5T_VLEN_MEMORY)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location");
+ /* H5T_copy converts any type into a memory type */
+ if (H5T_set_loc(new_dt, NULL, H5T_LOC_MEMORY)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location");
}
break;
@@ -4047,8 +4054,8 @@ H5T_set_size(H5T_t *dt, size_t size)
dt->u.vlen.pad = tmp_strpad;
/* Set up VL information */
- if (H5T_vlen_mark(dt, NULL, H5T_VLEN_MEMORY)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location");
+ if (H5T_set_loc(dt, NULL, H5T_LOC_MEMORY)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location");
} else {
prec = 8 * size;
@@ -4313,8 +4320,8 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2)
case H5T_VLEN:
assert(dt1->u.vlen.type>H5T_VLEN_BADTYPE && dt1->u.vlen.type<H5T_VLEN_MAXTYPE);
assert(dt2->u.vlen.type>H5T_VLEN_BADTYPE && dt2->u.vlen.type<H5T_VLEN_MAXTYPE);
- assert(dt1->u.vlen.loc>H5T_VLEN_BADLOC && dt1->u.vlen.loc<H5T_VLEN_MAXLOC);
- assert(dt2->u.vlen.loc>H5T_VLEN_BADLOC && dt2->u.vlen.loc<H5T_VLEN_MAXLOC);
+ assert(dt1->u.vlen.loc>H5T_LOC_BADLOC && dt1->u.vlen.loc<H5T_LOC_MAXLOC);
+ assert(dt2->u.vlen.loc>H5T_LOC_BADLOC && dt2->u.vlen.loc<H5T_LOC_MAXLOC);
/* Arbitrarily sort sequence VL datatypes before string VL datatypes */
if (dt1->u.vlen.type==H5T_VLEN_SEQUENCE &&
@@ -4325,11 +4332,11 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2)
HGOTO_DONE(1);
}
/* Arbitrarily sort VL datatypes in memory before disk */
- if (dt1->u.vlen.loc==H5T_VLEN_MEMORY &&
- dt2->u.vlen.loc==H5T_VLEN_DISK) {
+ if (dt1->u.vlen.loc==H5T_LOC_MEMORY &&
+ dt2->u.vlen.loc==H5T_LOC_DISK) {
HGOTO_DONE(-1);
- } else if (dt1->u.vlen.loc==H5T_VLEN_DISK &&
- dt2->u.vlen.loc==H5T_VLEN_MEMORY) {
+ } else if (dt1->u.vlen.loc==H5T_LOC_DISK &&
+ dt2->u.vlen.loc==H5T_LOC_MEMORY) {
HGOTO_DONE(1);
}
/* Don't allow VL types in different files to compare as equal */
@@ -4462,6 +4469,12 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2)
switch(dt1->u.atomic.u.r.rtype) {
case H5R_OBJECT:
+ if (dt1->u.atomic.u.r.loc < dt2->u.atomic.u.r.loc)
+ HGOTO_DONE(-1);
+ if (dt1->u.atomic.u.r.loc > dt2->u.atomic.u.r.loc)
+ HGOTO_DONE(1);
+ break;
+
case H5R_DATASET_REGION:
/* Does this need more to distinguish it? -QAK 11/30/98 */
/*void */
@@ -5082,6 +5095,150 @@ done:
}
+/*--------------------------------------------------------------------------
+ NAME
+ H5T_set_loc
+ PURPOSE
+ Recursively mark any datatypes as on disk/in memory
+ USAGE
+ htri_t H5T_set_loc(dt,f,loc)
+ H5T_t *dt; IN/OUT: Pointer to the datatype to mark
+ H5F_t *dt; IN: Pointer to the file the datatype is in
+ H5T_vlen_type_t loc IN: location of type
+
+ RETURNS
+ One of two values on success:
+ TRUE - If the location of any vlen types changed
+ FALSE - If the location of any vlen types is the same
+ <0 is returned on failure
+ DESCRIPTION
+ Recursively descends any VL or compound datatypes to mark all VL datatypes
+ as either on disk or in memory.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+htri_t
+H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc)
+{
+ htri_t changed; /* Whether H5T_set_loc changed the type (even if the size didn't change) */
+ htri_t ret_value = 0; /* Indicate that success, but no location change */
+ int i; /* Local index variable */
+ int accum_change; /* Amount of change in the offset of the fields */
+ size_t old_size; /* Previous size of a field */
+
+ FUNC_ENTER_NOAPI(H5T_set_loc, FAIL);
+
+ assert(dt);
+ assert(loc>H5T_LOC_BADLOC && loc<H5T_LOC_MAXLOC);
+
+ /* Datatypes can't change in size if the force_conv flag is not set */
+ if(dt->force_conv) {
+ /* Check the datatype of this element */
+ switch(dt->type) {
+ case H5T_ARRAY: /* Recurse on VL, compound and array base element type */
+ /* Recurse if it's VL, compound or array */
+ /* (If the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */
+ if(dt->parent->force_conv && (dt->parent->type==H5T_COMPOUND || dt->parent->type==H5T_VLEN || dt->parent->type==H5T_ARRAY)) {
+ /* Keep the old base element size for later */
+ old_size=dt->parent->size;
+
+ /* Mark the VL, compound or array type */
+ if((changed=H5T_set_loc(dt->parent,f,loc))<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
+ if(changed>0)
+ ret_value=changed;
+
+ /* Check if the field changed size */
+ if(old_size != dt->parent->size) {
+ /* Adjust the size of the array */
+ dt->size = dt->u.array.nelem*dt->parent->size;
+ } /* end if */
+ } /* end if */
+ break;
+
+ case H5T_COMPOUND: /* Check each field and recurse on VL, compound and array type */
+ /* Sort the fields based on offsets */
+ H5T_sort_value(dt,NULL);
+
+ for (i=0,accum_change=0; i<dt->u.compnd.nmembs; i++) {
+ H5T_t *memb_type; /* Member's datatype pointer */
+
+ /* Apply the accumulated size change to the offset of the field */
+ dt->u.compnd.memb[i].offset += accum_change;
+
+ /* Set the member type pointer (for convenience) */
+ memb_type=dt->u.compnd.memb[i].type;
+
+ /* Recurse if it's VL, compound or array */
+ /* (If the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */
+ if(memb_type->force_conv && (memb_type->type==H5T_COMPOUND || memb_type->type==H5T_VLEN || memb_type->type==H5T_ARRAY)) {
+ /* Keep the old field size for later */
+ old_size=memb_type->size;
+
+ /* Mark the VL, compound or array type */
+ if((changed=H5T_set_loc(memb_type,f,loc))<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
+ if(changed>0)
+ ret_value=changed;
+
+ /* Check if the field changed size */
+ if(old_size != memb_type->size) {
+ /* Adjust the size of the member */
+ dt->u.compnd.memb[i].size = (dt->u.compnd.memb[i].size*memb_type->size)/old_size;
+
+ /* Add that change to the accumulated size change */
+ accum_change += (memb_type->size - (int)old_size);
+ } /* end if */
+ } /* end if */
+ } /* end for */
+
+ /* Apply the accumulated size change to the datatype */
+ dt->size += accum_change;
+ break;
+
+ case H5T_VLEN: /* Recurse on the VL information if it's VL, compound or array, then free VL sequence */
+ /* Recurse if it's VL, compound or array */
+ /* (If the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */
+ if(dt->parent->force_conv && (dt->parent->type==H5T_COMPOUND || dt->parent->type==H5T_VLEN || dt->parent->type==H5T_ARRAY)) {
+ if((changed=H5T_set_loc(dt->parent,f,loc))<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
+ if(changed>0)
+ ret_value=changed;
+ } /* end if */
+
+ /* Mark this VL sequence */
+ if((changed=H5T_vlen_set_loc(dt,f,loc))<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
+ if(changed>0)
+ ret_value=changed;
+ break;
+
+ case H5T_REFERENCE:
+ /* Only need to change location of object references */
+ if(dt->u.atomic.u.r.rtype==H5R_OBJECT) {
+ /* Mark this reference */
+ if(loc!=dt->u.atomic.u.r.loc) {
+ /* Set the location */
+ dt->u.atomic.u.r.loc = loc;
+
+ /* Indicate that the location changed */
+ ret_value=TRUE;
+ } /* end if */
+ } /* end if */
+ break;
+
+ default:
+ break;
+ } /* end switch */
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value);
+} /* end H5T_set_loc() */
+
+
/*-------------------------------------------------------------------------
* Function: H5T_print_stats
*