summaryrefslogtreecommitdiffstats
path: root/src
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
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')
-rw-r--r--src/H5A.c12
-rw-r--r--src/H5D.c12
-rw-r--r--src/H5Odtype.c25
-rw-r--r--src/H5R.c17
-rw-r--r--src/H5T.c179
-rw-r--r--src/H5Tconv.c38
-rw-r--r--src/H5Tpkg.h48
-rw-r--r--src/H5Tprivate.h14
-rw-r--r--src/H5Tvlen.c144
9 files changed, 276 insertions, 213 deletions
diff --git a/src/H5A.c b/src/H5A.c
index 110e099..4ee84ff 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -235,9 +235,9 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type,
/* Copy the attribute's datatype */
attr->dt=H5T_copy(type, H5T_COPY_ALL);
- /* Mark any VL datatypes as being on disk now */
- if (H5T_vlen_mark(attr->dt, ent->file, H5T_VLEN_DISK)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location")
+ /* Mark any datatypes as being on disk now */
+ if (H5T_set_loc(attr->dt, ent->file, H5T_LOC_DISK)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
/* Copy the dataspace for the attribute */
attr->ds=H5S_copy(space);
@@ -910,9 +910,9 @@ H5Aget_type(hid_t attr_id)
if (NULL==(dst=H5T_copy(attr->dt, H5T_COPY_REOPEN)))
HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, FAIL, "unable to copy datatype")
- /* Mark any VL datatypes as being in memory now */
- if (H5T_vlen_mark(dst, NULL, H5T_VLEN_MEMORY)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location")
+ /* Mark any datatypes as being in memory now */
+ if (H5T_set_loc(dst, NULL, H5T_LOC_MEMORY)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
if (H5T_lock(dst, FALSE)<0)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to lock transient data type")
diff --git a/src/H5D.c b/src/H5D.c
index cf6b9a3..06b8d53 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -1080,9 +1080,9 @@ H5Dget_type(hid_t dset_id)
if (NULL==(copied_type=H5T_copy (dset->type, H5T_COPY_REOPEN)))
HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL, "unable to copy the data type")
- /* Mark any VL datatypes as being in memory now */
- if (H5T_vlen_mark(copied_type, NULL, H5T_VLEN_MEMORY)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location")
+ /* Mark any datatypes as being in memory now */
+ if (H5T_set_loc(copied_type, NULL, H5T_LOC_MEMORY)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location")
/* Unlock copied type */
if (H5T_lock (copied_type, FALSE)<0)
@@ -1645,9 +1645,9 @@ H5D_create(H5G_entry_t *loc, const char *name, hid_t type_id, const H5S_t *space
if((new_dset->type = H5T_copy(type, H5T_COPY_ALL))==NULL)
HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCOPY, NULL, "can't copy datatype")
- /* Mark any VL datatypes as being on disk now */
- if (H5T_vlen_mark(new_dset->type, file, H5T_VLEN_DISK)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location")
+ /* Mark any datatypes as being on disk now */
+ if (H5T_set_loc(new_dset->type, file, H5T_LOC_DISK)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location")
/* Copy dataspace for dataset */
if((new_dset->space = H5S_copy(space))==NULL)
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index 5f814fe..98f2bc0 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -270,7 +270,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
* Set the "force conversion" flag if VL datatype fields exist in this
* type or any component types
*/
- if(temp_type->type==H5T_VLEN || temp_type->force_conv==TRUE)
+ if(temp_type->force_conv==TRUE)
dt->force_conv=TRUE;
/* Set the "has array" flag if array datatype fields exist in this type */
@@ -319,7 +319,18 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
dt->u.atomic.offset = 0;
dt->u.atomic.lsb_pad = H5T_PAD_ZERO;
dt->u.atomic.msb_pad = H5T_PAD_ZERO;
+
+ /* Set reference type */
dt->u.atomic.u.r.rtype = (H5R_type_t)(flags & 0x0f);
+
+ /* Set extra information for object references, so the hobj_ref_t gets swizzled correctly */
+ if(dt->u.atomic.u.r.rtype==H5R_OBJECT) {
+ /* This type is on disk */
+ dt->u.atomic.u.r.loc = H5T_LOC_DISK;
+
+ /* This type needs conversion */
+ dt->force_conv=TRUE;
+ } /* end if */
break;
case H5T_STRING:
@@ -353,8 +364,8 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
dt->force_conv=TRUE;
/* Mark this type as on disk */
- if (H5T_vlen_mark(dt, f, H5T_VLEN_DISK)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid VL location");
+ if (H5T_set_loc(dt, f, H5T_LOC_DISK)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "invalid datatype location");
break;
case H5T_TIME: /* Time datatypes */
@@ -393,7 +404,7 @@ H5O_dtype_decode_helper(H5F_t *f, const uint8_t **pp, H5T_t *dt)
* Set the "force conversion" flag if a VL base datatype is used or
* or if any components of the base datatype are VL types.
*/
- if(dt->parent->type==H5T_VLEN || dt->parent->force_conv==TRUE)
+ if(dt->parent->force_conv==TRUE)
dt->force_conv=TRUE;
break;
@@ -1285,14 +1296,14 @@ H5O_dtype_debug(H5F_t *f, hid_t dxpl_id, const void *mesg, FILE *stream,
"Vlen type:", s);
switch (dt->u.vlen.loc) {
- case H5T_VLEN_MEMORY:
+ case H5T_LOC_MEMORY:
s = "memory";
break;
- case H5T_VLEN_DISK:
+ case H5T_LOC_DISK:
s = "disk";
break;
default:
- sprintf(buf, "H5T_VLEN_%d", dt->u.vlen.loc);
+ sprintf(buf, "H5T_LOC_%d", dt->u.vlen.loc);
s = buf;
break;
}
diff --git a/src/H5R.c b/src/H5R.c
index a064210..52670e0 100644
--- a/src/H5R.c
+++ b/src/H5R.c
@@ -157,11 +157,8 @@ H5R_create(void *_ref, H5G_entry_t *loc, const char *name, H5R_type_t ref_type,
case H5R_OBJECT:
{
hobj_ref_t *ref=(hobj_ref_t *)_ref; /* Get pointer to correct type of reference struct */
- uint8_t *p; /* Pointer to OID to store */
- /* Set information for reference */
- p=(uint8_t *)ref;
- H5F_addr_encode(loc->file,&p,sb.objno);
+ *ref=sb.objno;
break;
}
@@ -351,13 +348,8 @@ H5R_dereference(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref)
case H5R_OBJECT:
{
hobj_ref_t *ref=(hobj_ref_t *)_ref; /* Only object references currently supported */
- /*
- * Switch on object type, when we implement that feature, always try to
- * open a dataset for now
- */
- /* Get the object oid */
- p=(uint8_t *)ref;
- H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header));
+
+ ent.header=*ref;
} /* end case */
break;
@@ -666,8 +658,7 @@ H5R_get_obj_type(H5F_t *file, hid_t dxpl_id, H5R_type_t ref_type, void *_ref)
hobj_ref_t *ref=(hobj_ref_t *)_ref; /* Only object references currently supported */
/* Get the object oid */
- p=(uint8_t *)ref;
- H5F_addr_decode(ent.file,(const uint8_t **)&p,&(ent.header));
+ ent.header=*ref;
} /* end case */
break;
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
*
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index c9329bd..08a181e 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -508,11 +508,14 @@ H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
if (src->size != dst->size ||
0 != src->u.atomic.offset ||
- 0 != dst->u.atomic.offset ||
- !((H5T_ORDER_BE == src->u.atomic.order &&
- H5T_ORDER_LE == dst->u.atomic.order) ||
- (H5T_ORDER_LE == src->u.atomic.order &&
- H5T_ORDER_BE == dst->u.atomic.order)))
+ 0 != dst->u.atomic.offset)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
+ if((src->type==H5T_REFERENCE && dst->type!=H5T_REFERENCE) ||
+ (dst->type==H5T_REFERENCE && src->type!=H5T_REFERENCE))
+ HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
+ if(src->type!=H5T_REFERENCE &&
+ !((H5T_ORDER_BE == src->u.atomic.order && H5T_ORDER_LE == dst->u.atomic.order) ||
+ (H5T_ORDER_LE == src->u.atomic.order && H5T_ORDER_BE == dst->u.atomic.order)))
HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported");
if (src->size!=1 && src->size!=2 && src->size!=4 &&
src->size!=8 && src->size!=16)
@@ -520,6 +523,7 @@ H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
switch (src->type) {
case H5T_INTEGER:
case H5T_BITFIELD:
+ case H5T_REFERENCE:
/* nothing to check */
break;
@@ -547,6 +551,30 @@ H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata,
NULL == (dst = H5I_object(dst_id)))
HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ /* Check for "no op" reference conversion */
+ if(src->type==H5T_REFERENCE) {
+ H5T_t *native_int; /* Native integer datatype */
+
+ /* Sanity check */
+ assert(dst->type==H5T_REFERENCE);
+
+ /* Get pointer to native integer type */
+ if (NULL==(native_int=H5I_object(H5T_NATIVE_INT_g)))
+ HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype object");
+
+ /* Check if we are on a little-endian machine (the order that
+ * the addresses in the file must be) and just get out now, there
+ * is no need to convert the object reference. Yes, this is
+ * icky and non-portable, but I can't think of a better way to
+ * support allowing the objno in the H5G_stat_t struct and the
+ * hobj_ref_t type to be compared directly without introducing a
+ * "native" hobj_ref_t datatype and I think that would break a
+ * lot of existing programs. -QAK
+ */
+ if(native_int->u.atomic.order == H5T_ORDER_LE)
+ break;
+ } /* end if */
+
buf_stride = buf_stride ? buf_stride : src->size;
switch (src->size) {
case 1:
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index 6fccdba..8a6b68d 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -65,14 +65,6 @@ struct H5T_path_t {
H5T_cdata_t cdata; /*data for this function */
};
-/* VL types */
-typedef enum {
- H5T_VLEN_BADTYPE = -1, /* invalid VL Type */
- H5T_VLEN_SEQUENCE=0, /* VL sequence */
- H5T_VLEN_STRING, /* VL string */
- H5T_VLEN_MAXTYPE /* highest type (Invalid as true type) */
-} H5T_vlen_type_t;
-
typedef struct H5T_atomic_t {
H5T_order_t order; /*byte order */
size_t prec; /*precision in bits */
@@ -102,6 +94,7 @@ typedef struct H5T_atomic_t {
struct {
H5R_type_t rtype; /*type of reference stored */
+ H5T_loc_t loc; /* Location of data in buffer */
} r; /*reference types */
} u;
} H5T_atomic_t;
@@ -117,20 +110,20 @@ typedef enum H5T_sort_t {
typedef struct H5T_compnd_t {
int nalloc; /*num entries allocated in MEMB array*/
int nmembs; /*number of members defined in struct*/
- H5T_sort_t sorted; /*how are members sorted? */
- hbool_t has_array; /* Set if this type has an array datatype member */
- /* and should be written with the new version of */
- /* the datatype object header message */
- struct H5T_cmemb_t *memb; /*array of struct members */
+ H5T_sort_t sorted; /*how are members sorted? */
+ hbool_t has_array; /* Set if this type has an array datatype member */
+ /* and should be written with the new version of */
+ /* the datatype object header message */
+ struct H5T_cmemb_t *memb; /*array of struct members */
} H5T_compnd_t;
/* An enumeration data type */
typedef struct H5T_enum_t {
int nalloc; /*num entries allocated */
int nmembs; /*number of members defined in enum */
- H5T_sort_t sorted; /*how are members sorted? */
- uint8_t *value; /*array of values */
- char **name; /*array of symbol names */
+ H5T_sort_t sorted; /*how are members sorted? */
+ uint8_t *value; /*array of values */
+ char **name; /*array of symbol names */
} H5T_enum_t;
/* VL function pointers */
@@ -138,10 +131,18 @@ typedef hssize_t (*H5T_vlen_getlenfunc_t)(H5F_t *f, void *vl_addr);
typedef herr_t (*H5T_vlen_readfunc_t)(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *buf, size_t len);
typedef herr_t (*H5T_vlen_writefunc_t)(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *buf, void *bg_addr, hsize_t seq_len, hsize_t base_size);
+/* VL types */
+typedef enum {
+ H5T_VLEN_BADTYPE = -1, /* invalid VL Type */
+ H5T_VLEN_SEQUENCE=0, /* VL sequence */
+ H5T_VLEN_STRING, /* VL string */
+ H5T_VLEN_MAXTYPE /* highest type (Invalid as true type) */
+} H5T_vlen_type_t;
+
/* A VL datatype */
typedef struct H5T_vlen_t {
H5T_vlen_type_t type; /* Type of VL data in buffer */
- H5T_vlen_loc_t loc; /* Location of VL data in buffer */
+ H5T_loc_t loc; /* Location of VL data in buffer */
H5T_cset_t cset; /* For VL string. character set */
H5T_str_t pad; /* For VL string. space or null padding of
* extra bytes */
@@ -158,9 +159,9 @@ typedef struct H5T_opaque_t {
/* An array datatype */
typedef struct H5T_array_t {
- size_t nelem; /* total number of elements in array */
+ size_t nelem; /* total number of elements in array */
int ndims; /* member dimensionality */
- size_t dim[H5S_MAX_RANK]; /* size in each dimension */
+ size_t dim[H5S_MAX_RANK]; /* size in each dimension */
int perm[H5S_MAX_RANK]; /* index permutation */
} H5T_array_t;
@@ -178,15 +179,15 @@ struct H5T_t {
H5F_t *sh_file;/*file pointer if this is a shared type */
H5T_class_t type; /*which class of type is this? */
size_t size; /*total size of an instance of this type */
- hbool_t force_conv; /* Set if this type always needs to be converted and H5T_conv_noop cannot be called */
+ hbool_t force_conv;/* Set if this type always needs to be converted and H5T_conv_noop cannot be called */
struct H5T_t *parent;/*parent type for derived data types */
union {
H5T_atomic_t atomic; /* an atomic data type */
H5T_compnd_t compnd; /* a compound data type (struct) */
- H5T_enum_t enumer; /* an enumeration type (enum) */
- H5T_vlen_t vlen; /* a variable-length datatype */
+ H5T_enum_t enumer; /* an enumeration type (enum) */
+ H5T_vlen_t vlen; /* a variable-length datatype */
H5T_opaque_t opaque; /* an opaque data type */
- H5T_array_t array; /* an array datatype */
+ H5T_array_t array; /* an array datatype */
} u;
};
@@ -854,6 +855,7 @@ H5_DLL herr_t H5T_vlen_str_mem_write(H5F_t *f, hid_t dxpl_id, void *vl_addr, voi
H5_DLL hssize_t H5T_vlen_disk_getlen(H5F_t *f, void *vl_addr);
H5_DLL herr_t H5T_vlen_disk_read(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *_buf, size_t len);
H5_DLL herr_t H5T_vlen_disk_write(H5F_t *f, hid_t dxpl_id, void *vl_addr, void *_buf, void *bg_addr, hsize_t seq_len, hsize_t base_size);
+H5_DLL htri_t H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc);
/* Array functions */
H5_DLL H5T_t * H5T_array_create(H5T_t *base, int ndims,
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index deccfc5..4fd78e6 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -37,13 +37,13 @@ typedef enum H5T_copy_t {
H5T_COPY_REOPEN
} H5T_copy_t;
-/* Location of VL information */
+/* Location of datatype information */
typedef enum {
- H5T_VLEN_BADLOC = 0, /* invalid VL Type */
- H5T_VLEN_MEMORY, /* VL data stored in memory */
- H5T_VLEN_DISK, /* VL data stored on disk */
- H5T_VLEN_MAXLOC /* highest type (Invalid as true type) */
-} H5T_vlen_loc_t;
+ H5T_LOC_BADLOC = 0, /* invalid datatype location */
+ H5T_LOC_MEMORY, /* data stored in memory */
+ H5T_LOC_DISK, /* data stored on disk */
+ H5T_LOC_MAXLOC /* highest value (Invalid as true value) */
+} H5T_loc_t;
/* Private functions */
H5_DLL herr_t H5TN_init_interface(void);
@@ -69,8 +69,8 @@ H5_DLL herr_t H5T_convert(H5T_path_t *tpath, hid_t src_id, hid_t dst_id,
hsize_t nelmts, size_t buf_stride, size_t bkg_stride,
void *buf, void *bkg, hid_t dset_xfer_plist);
H5_DLL herr_t H5T_vlen_reclaim(void *elem, hid_t type_id, hsize_t ndim, hssize_t *point, void *_op_data);
-H5_DLL htri_t H5T_vlen_mark(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc);
H5_DLL htri_t H5T_is_sensible(const H5T_t *dt);
+H5_DLL htri_t H5T_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc);
/* Reference specific functions */
H5_DLL H5R_type_t H5T_get_ref_type(const H5T_t *dt);
diff --git a/src/H5Tvlen.c b/src/H5Tvlen.c
index e0eddf5..ff9cfac 100644
--- a/src/H5Tvlen.c
+++ b/src/H5Tvlen.c
@@ -39,7 +39,6 @@ static herr_t H5T_init_vlen_interface(void);
H5FL_EXTERN(H5T_t);
/* Local functions */
-static htri_t H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc);
static herr_t H5T_vlen_reclaim_recurse(void *elem, H5T_t *dt, H5MM_free_t free_func, void *free_info);
@@ -154,8 +153,8 @@ H5T_vlen_create(H5T_t *base)
dt->u.vlen.type = H5T_VLEN_SEQUENCE;
/* Set up VL information */
- if (H5T_vlen_mark(dt, NULL, H5T_VLEN_MEMORY)<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid VL location");
+ if (H5T_set_loc(dt, NULL, H5T_LOC_MEMORY)<0)
+ HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "invalid datatype location");
/* Set return value */
ret_value=dt;
@@ -183,8 +182,8 @@ done:
*
*-------------------------------------------------------------------------
*/
-static htri_t
-H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc)
+htri_t
+H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_loc_t loc)
{
htri_t ret_value = 0; /* Indicate that success, but no location change */
@@ -192,7 +191,7 @@ H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc)
/* check parameters */
assert(dt);
- assert(loc>H5T_VLEN_BADLOC && loc<H5T_VLEN_MAXLOC);
+ assert(loc>H5T_LOC_BADLOC && loc<H5T_LOC_MAXLOC);
/* Only change the location if it's different */
if(loc!=dt->u.vlen.loc) {
@@ -200,11 +199,11 @@ H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc)
ret_value=TRUE;
switch(loc) {
- case H5T_VLEN_MEMORY: /* Memory based VL datatype */
+ case H5T_LOC_MEMORY: /* Memory based VL datatype */
assert(f==NULL);
/* Mark this type as being stored in memory */
- dt->u.vlen.loc=H5T_VLEN_MEMORY;
+ dt->u.vlen.loc=H5T_LOC_MEMORY;
if(dt->u.vlen.type==H5T_VLEN_SEQUENCE) {
/* size in memory, disk size is different */
@@ -230,11 +229,11 @@ H5T_vlen_set_loc(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc)
dt->u.vlen.f=NULL;
break;
- case H5T_VLEN_DISK: /* Disk based VL datatype */
+ case H5T_LOC_DISK: /* Disk based VL datatype */
assert(f);
/* Mark this type as being stored on disk */
- dt->u.vlen.loc=H5T_VLEN_DISK;
+ dt->u.vlen.loc=H5T_LOC_DISK;
/*
* Size of element on disk is 4 bytes for the length, plus the size
@@ -851,128 +850,3 @@ done:
FUNC_LEAVE_NOAPI(ret_value);
} /* end H5T_vlen_reclaim() */
-
-/*--------------------------------------------------------------------------
- NAME
- H5T_vlen_mark
- PURPOSE
- Recursively mark any VL datatypes as on disk/in memory
- USAGE
- htri_t H5T_vlen_mark(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 VL 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_vlen_mark(H5T_t *dt, H5F_t *f, H5T_vlen_loc_t loc)
-{
- htri_t vlen_changed; /* Whether H5T_vlen_mark 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=0; /* Amount of change in the offset of the fields */
- size_t old_size; /* Previous size of a field */
-
- FUNC_ENTER_NOAPI(H5T_vlen_mark, FAIL);
-
- assert(dt);
- assert(loc>H5T_VLEN_BADLOC && loc<H5T_VLEN_MAXLOC);
-
- /* 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 type is compound and the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */
- if((dt->parent->type==H5T_COMPOUND && dt->parent->force_conv) || 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((vlen_changed=H5T_vlen_mark(dt->parent,f,loc))<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
- if(vlen_changed>0)
- ret_value=vlen_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 */
- /* Compound datatypes can't change in size if the force_conv flag is not set */
- if(dt->force_conv) {
- /* Sort the fields based on offsets */
- H5T_sort_value(dt,NULL);
-
- for (i=0; i<dt->u.compnd.nmembs; i++) {
- /* Apply the accumulated size change to the offset of the field */
- dt->u.compnd.memb[i].offset += accum_change;
-
- /* Recurse if it's VL, compound or array */
- /* (If the type is compound and the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */
- if((dt->u.compnd.memb[i].type->type==H5T_COMPOUND && dt->u.compnd.memb[i].type->force_conv) || dt->u.compnd.memb[i].type->type==H5T_VLEN || dt->u.compnd.memb[i].type->type==H5T_ARRAY) {
- /* Keep the old field size for later */
- old_size=dt->u.compnd.memb[i].type->size;
-
- /* Mark the VL, compound or array type */
- if((vlen_changed=H5T_vlen_mark(dt->u.compnd.memb[i].type,f,loc))<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
- if(vlen_changed>0)
- ret_value=vlen_changed;
-
- /* Check if the field changed size */
- if(old_size != dt->u.compnd.memb[i].type->size) {
- /* Adjust the size of the member */
- dt->u.compnd.memb[i].size = (dt->u.compnd.memb[i].size*dt->u.compnd.memb[i].type->size)/old_size;
-
- /* Add that change to the accumulated size change */
- accum_change += (dt->u.compnd.memb[i].type->size - (int)old_size);
- } /* end if */
- } /* end if */
- } /* end for */
-
- /* Apply the accumulated size change to the datatype */
- dt->size += accum_change;
- } /* end if */
- 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 type is compound and the force_conv flag is _not_ set, the type cannot change in size, so don't recurse) */
- if((dt->parent->type==H5T_COMPOUND && dt->parent->force_conv) || dt->parent->type==H5T_VLEN || dt->parent->type==H5T_ARRAY) {
- if((vlen_changed=H5T_vlen_mark(dt->parent,f,loc))<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
- if(vlen_changed>0)
- ret_value=vlen_changed;
- } /* end if */
-
- /* Mark this VL sequence */
- if((vlen_changed=H5T_vlen_set_loc(dt,f,loc))<0)
- HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "Unable to set VL location");
- if(vlen_changed>0)
- ret_value=vlen_changed;
- break;
-
- default:
- break;
- } /* end switch */
-
-done:
- FUNC_LEAVE_NOAPI(ret_value);
-} /* end H5T_vlen_mark() */
-