diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2003-08-11 12:43:04 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2003-08-11 12:43:04 (GMT) |
commit | ed92f54f9bae998ffe1f686f4f4ea61cd4bbdade (patch) | |
tree | f60eb3cc97b756e34c63a20f030dd981ea44df85 /src | |
parent | 8de0645dfa17c22f6a8ee58361f7d4b7ce2755ae (diff) | |
download | hdf5-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.c | 12 | ||||
-rw-r--r-- | src/H5D.c | 12 | ||||
-rw-r--r-- | src/H5Odtype.c | 25 | ||||
-rw-r--r-- | src/H5R.c | 17 | ||||
-rw-r--r-- | src/H5T.c | 179 | ||||
-rw-r--r-- | src/H5Tconv.c | 38 | ||||
-rw-r--r-- | src/H5Tpkg.h | 48 | ||||
-rw-r--r-- | src/H5Tprivate.h | 14 | ||||
-rw-r--r-- | src/H5Tvlen.c | 144 |
9 files changed, 276 insertions, 213 deletions
@@ -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") @@ -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; } @@ -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; @@ -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() */ - |