diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/H5.c | 34 | ||||
-rw-r--r-- | src/H5A.c | 42 | ||||
-rw-r--r-- | src/H5D.c | 71 | ||||
-rw-r--r-- | src/H5F.c | 29 | ||||
-rw-r--r-- | src/H5Fprivate.h | 2 | ||||
-rw-r--r-- | src/H5Ofill.c | 21 | ||||
-rw-r--r-- | src/H5P.c | 31 | ||||
-rw-r--r-- | src/H5T.c | 2122 | ||||
-rw-r--r-- | src/H5Tconv.c | 258 | ||||
-rw-r--r-- | src/H5Tpkg.h | 19 | ||||
-rw-r--r-- | src/H5Tprivate.h | 55 | ||||
-rw-r--r-- | src/H5Tpublic.h | 17 | ||||
-rw-r--r-- | src/H5detect.c | 2 | ||||
-rw-r--r-- | src/H5private.h | 2 |
14 files changed, 1251 insertions, 1454 deletions
@@ -98,7 +98,7 @@ H5_init_library(void) * Initialize interfaces that might not be able to initialize themselves * soon enough. */ - if (H5T_init_interface() < 0) { + if (H5T_init()<0) { HRETURN_ERROR(H5E_FUNC, H5E_CANTINIT, FAIL, "unable to initialize type interface"); } @@ -931,7 +931,9 @@ H5_timer_begin (H5_timer_t *timer) #ifdef HAVE_GETRUSAGE struct rusage rusage; #endif +#ifdef HAVE_GETTIMEOFDAY struct timeval etime; +#endif assert (timer); @@ -947,8 +949,10 @@ H5_timer_begin (H5_timer_t *timer) #endif #ifdef HAVE_GETTIMEOFDAY gettimeofday (&etime, NULL); -#endif timer->etime = (double)etime.tv_sec + (double)etime.tv_usec/1e6; +#else + timer->etime = 0.0; +#endif } @@ -2037,6 +2041,32 @@ H5_trace (hbool_t returning, const char *func, const char *type, ...) } break; + case 'e': + if (ptr) { + if (vp) { + fprintf(out, "0x%lx", (unsigned long)vp); + } else { + fprintf(out, "NULL"); + } + } else { + H5T_pers_t pers = va_arg(ap, H5T_pers_t); + switch (pers) { + case H5T_PERS_DONTCARE: + fprintf(out, "H5T_PERS_DONTCARE"); + break; + case H5T_PERS_SOFT: + fprintf(out, "H5T_PERS_SOFT"); + break; + case H5T_PERS_HARD: + fprintf(out, "H5T_PERS_HARD"); + break; + default: + fprintf(out, "%ld", (long)pers); + break; + } + } + break; + case 'n': if (ptr) { if (vp) { @@ -604,17 +604,13 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf) { uint8_t *tconv_buf = NULL; /* data type conv buffer */ size_t nelmts; /* elements in attribute */ - H5T_conv_t tconv_func = NULL; /* conversion function */ - H5T_cdata_t *cdata = NULL; /* type conversion data */ + H5T_path_t *tpath = NULL; /* conversion information*/ hid_t src_id = -1, dst_id = -1;/* temporary type atoms */ size_t src_type_size; /* size of source type */ size_t dst_type_size; /* size of destination type*/ size_t buf_size; /* desired buffer size */ int idx; /* index of attribute in object header */ herr_t ret_value = FAIL; -#ifdef H5T_DEBUG - H5_timer_t timer; -#endif FUNC_ENTER(H5A_write, FAIL); @@ -641,11 +637,10 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf) /* Convert memory buffer into disk buffer */ /* Set up type conversion function */ - if (NULL == (tconv_func = H5T_find(mem_type, attr->dt, - H5T_BKG_NO, &cdata))) { + if (NULL == (tpath = H5T_path_find(mem_type, attr->dt, NULL, NULL))) { HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types"); - } else if (H5T_conv_noop!=tconv_func) { + } else if (!H5T_IS_NOOP(tpath)) { if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL)))<0 || (dst_id = H5I_register(H5I_DATATYPE, @@ -655,18 +650,11 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf) } } - /* Perform data type conversion. */ -#ifdef H5T_DEBUG - H5T_timer_begin (&timer, cdata); -#endif - cdata->command = H5T_CONV_CONV; - if ((tconv_func) (src_id, dst_id, cdata, nelmts, tconv_buf, NULL)<0) { + /* Perform data type conversion */ + if (H5T_convert(tpath, src_id, dst_id, nelmts, tconv_buf, NULL)<0) { HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "data type conversion failed"); } -#ifdef H5T_DEBUG - H5T_timer_end (&timer, cdata, nelmts); -#endif /* Free the previous attribute data buffer, if there is one */ if(attr->data) @@ -775,16 +763,12 @@ H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf) { uint8_t *tconv_buf = NULL; /* data type conv buffer*/ size_t nelmts; /* elements in attribute*/ - H5T_conv_t tconv_func = NULL; /* conversion function */ - H5T_cdata_t *cdata = NULL; /* type conversion data */ + H5T_path_t *tpath = NULL; /* type conversion info */ hid_t src_id = -1, dst_id = -1;/* temporary type atoms*/ size_t src_type_size; /* size of source type */ size_t dst_type_size; /* size of destination type */ size_t buf_size; /* desired buffer size */ herr_t ret_value = FAIL; -#ifdef H5T_DEBUG - H5_timer_t timer; -#endif FUNC_ENTER(H5A_read, FAIL); @@ -811,11 +795,10 @@ H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf) /* Convert memory buffer into disk buffer */ /* Set up type conversion function */ - if (NULL == (tconv_func = H5T_find(attr->dt, mem_type, - H5T_BKG_NO, &cdata))) { + if (NULL == (tpath = H5T_path_find(attr->dt, mem_type, NULL, NULL))) { HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types"); - } else if (H5T_conv_noop!=tconv_func) { + } else if (!H5T_IS_NOOP(tpath)) { if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(attr->dt, H5T_COPY_ALL)))<0 || (dst_id = H5I_register(H5I_DATATYPE, @@ -826,17 +809,10 @@ H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf) } /* Perform data type conversion. */ -#ifdef H5T_DEBUG - H5T_timer_begin (&timer, cdata); -#endif - cdata->command = H5T_CONV_CONV; - if ((tconv_func) (src_id, dst_id, cdata, nelmts, tconv_buf, NULL)<0) { + if (H5T_convert(tpath, src_id, dst_id, nelmts, tconv_buf, NULL)<0) { HGOTO_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, "data type conversion failed"); } -#ifdef H5T_DEBUG - H5T_timer_end (&timer, cdata, nelmts); -#endif /* Copy the converted data into the user's buffer */ HDmemcpy(buf,tconv_buf,dst_type_size*nelmts); @@ -1444,21 +1444,21 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, const H5S_t *file_space, const H5D_xfer_t *xfer_parms, void *buf/*out*/) { - hssize_t nelmts; /*number of elements */ + hssize_t nelmts; /*number of elements */ size_t smine_start; /*strip mine start loc */ size_t n, smine_nelmts; /*elements per strip */ - hid_t tconv_id=FAIL, bkg_id=FAIL; /* Conversion buffer IDs */ + hid_t tconv_id=FAIL; /*type conv buffer ID */ + hid_t bkg_id=FAIL; /*background buffer ID */ uint8_t *tconv_buf = NULL; /*data type conv buffer */ uint8_t *bkg_buf = NULL; /*background buffer */ - H5T_conv_t tconv_func = NULL; /*conversion function */ + H5T_path_t *tpath = NULL; /*type conversion info */ hid_t src_id = -1, dst_id = -1;/*temporary type atoms */ H5S_conv_t *sconv=NULL; /*space conversion funcs*/ H5S_sel_iter_t mem_iter; /* mem selection iteration info*/ H5S_sel_iter_t bkg_iter; /*background iteration info*/ H5S_sel_iter_t file_iter; /*file selection iter info*/ - H5T_cdata_t *cdata = NULL; /*type conversion data */ - herr_t ret_value = FAIL; - herr_t status; + herr_t ret_value = FAIL; /*return value */ + herr_t status; /*function return status*/ size_t src_type_size; /*size of source type */ size_t dst_type_size; /*size of destination type*/ size_t target_size; /*desired buffer size */ @@ -1522,11 +1522,10 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes"); } - if (NULL == (tconv_func = H5T_find(dataset->type, mem_type, - xfer_parms->need_bkg, &cdata))) { + if (NULL==(tpath=H5T_path_find(dataset->type, mem_type, NULL, NULL))) { HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types"); - } else if (H5T_conv_noop!=tconv_func) { + } else if (!H5T_IS_NOOP(tpath)) { if ((src_id=H5I_register(H5I_DATATYPE, H5T_copy(dataset->type, H5T_COPY_ALL)))<0 || (dst_id=H5I_register(H5I_DATATYPE, @@ -1556,7 +1555,7 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * If there is no type conversion then try reading directly into the * application's buffer. This saves at least one mem-to-mem copy. */ - if (H5T_conv_noop==tconv_func && sconv->read) { + if (H5T_IS_NOOP(tpath) && sconv->read) { status = (sconv->read)(dataset->ent.file, &(dataset->layout), &(dataset->create_parms->pline), &(dataset->create_parms->efl), @@ -1619,8 +1618,8 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * malloc() is usually less resource-intensive if we allocate/free the * same size over and over. */ - if (cdata->need_bkg) { - need_bkg = MAX (cdata->need_bkg, xfer_parms->need_bkg); + if (tpath->cdata.need_bkg) { + need_bkg = MAX(tpath->cdata.need_bkg, xfer_parms->need_bkg); } else { need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/ } @@ -1720,16 +1719,8 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, /* * Perform data type conversion. */ -#ifdef H5T_DEBUG - H5T_timer_begin (&timer, cdata); -#endif - cdata->command = H5T_CONV_CONV; - status = (tconv_func)(src_id, dst_id, cdata, smine_nelmts, tconv_buf, - bkg_buf); -#ifdef H5T_DEBUG - H5T_timer_end (&timer, cdata, smine_nelmts); -#endif - if (status<0) { + if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, tconv_buf, + bkg_buf)<0) { HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed"); } @@ -1803,27 +1794,28 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, const H5S_t *file_space, const H5D_xfer_t *xfer_parms, const void *buf) { - hssize_t nelmts; /*total number of elmts */ + hssize_t nelmts; /*total number of elmts */ size_t smine_start; /*strip mine start loc */ size_t n, smine_nelmts; /*elements per strip */ - hid_t tconv_id=FAIL, bkg_id=FAIL; /* Conversion buffer IDs */ + hid_t tconv_id=FAIL; /*type conv buffer ID */ + hid_t bkg_id=FAIL; /*background buffer ID */ uint8_t *tconv_buf = NULL; /*data type conv buffer */ uint8_t *bkg_buf = NULL; /*background buffer */ - H5T_conv_t tconv_func = NULL; /*conversion function */ + H5T_path_t *tpath = NULL; /*type conversion info */ hid_t src_id = -1, dst_id = -1;/*temporary type atoms */ H5S_conv_t *sconv=NULL; /*space conversion funcs*/ H5S_sel_iter_t mem_iter; /*memory selection iteration info*/ H5S_sel_iter_t bkg_iter; /*background iteration info*/ H5S_sel_iter_t file_iter; /*file selection iteration info*/ - H5T_cdata_t *cdata = NULL; /*type conversion data */ - herr_t ret_value = FAIL, status; + herr_t ret_value = FAIL; /*return value */ + herr_t status; /*function return status*/ size_t src_type_size; /*size of source type */ size_t dst_type_size; /*size of destination type*/ size_t target_size; /*desired buffer size */ size_t request_nelmts; /*requested strip mine */ H5T_bkg_t need_bkg; /*type of background buf*/ H5S_t *free_this_space=NULL; /*data space to free */ - hbool_t must_convert; /*have to xfer the slow way */ + hbool_t must_convert; /*have to xfer the slow way*/ #ifdef H5T_DEBUG H5_timer_t timer; #endif @@ -1889,11 +1881,10 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "src and dest data spaces have different sizes"); } - if (NULL == (tconv_func = H5T_find(mem_type, dataset->type, - xfer_parms->need_bkg, &cdata))) { + if (NULL==(tpath=H5T_path_find(mem_type, dataset->type, NULL, NULL))) { HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL, "unable to convert between src and dest data types"); - } else if (H5T_conv_noop!=tconv_func) { + } else if (!H5T_IS_NOOP(tpath)) { if ((src_id = H5I_register(H5I_DATATYPE, H5T_copy(mem_type, H5T_COPY_ALL)))<0 || (dst_id = H5I_register(H5I_DATATYPE, @@ -1926,7 +1917,7 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * If there is no type conversion then try writing directly from * application buffer to file. */ - if (H5T_conv_noop==tconv_func && sconv->write) { + if (H5T_IS_NOOP(tpath) && sconv->write) { status = (sconv->write)(dataset->ent.file, &(dataset->layout), &(dataset->create_parms->pline), &(dataset->create_parms->efl), @@ -1990,8 +1981,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, * malloc() is usually less resource-intensive if we allocate/free the * same size over and over. */ - if (cdata->need_bkg) { - need_bkg = MAX (cdata->need_bkg, xfer_parms->need_bkg); + if (tpath->cdata.need_bkg) { + need_bkg = MAX (tpath->cdata.need_bkg, xfer_parms->need_bkg); } else { need_bkg = H5T_BKG_NO; /*never needed even if app says yes*/ } @@ -2088,16 +2079,8 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space, /* * Perform data type conversion. */ -#ifdef H5T_DEBUG - H5T_timer_begin (&timer, cdata); -#endif - cdata->command = H5T_CONV_CONV; - status = (tconv_func) (src_id, dst_id, cdata, smine_nelmts, tconv_buf, - bkg_buf); -#ifdef H5T_DEBUG - H5T_timer_end (&timer, cdata, smine_nelmts); -#endif - if (status<0) { + if (H5T_convert(tpath, src_id, dst_id, smine_nelmts, tconv_buf, + bkg_buf)<0) { HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "data type conversion failed"); } @@ -100,6 +100,7 @@ const H5F_mprop_t H5F_mount_dflt = { /* Interface initialization */ static intn interface_initialize_g = 0; #define INTERFACE_INIT H5F_init_interface +static herr_t H5F_init_interface(void); /* PRIVATE PROTOTYPES */ static H5F_t *H5F_new(H5F_file_t *shared, const H5F_create_t *fcpl, @@ -112,6 +113,31 @@ static herr_t H5F_locate_signature(H5F_low_t *f_handle, /*------------------------------------------------------------------------- + * Function: H5F_init + * + * Purpose: Initialize the interface from some other layer. + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Robb Matzke + * Wednesday, December 16, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_init(void) +{ + FUNC_ENTER(H5F_init, FAIL); + /* FUNC_ENTER() does all the work */ + FUNC_LEAVE(SUCCEED); +} + + +/*------------------------------------------------------------------------- * Function: H5F_init_interface * * Purpose: Initialize interface-specific information. @@ -132,12 +158,11 @@ static herr_t H5F_locate_signature(H5F_low_t *f_handle, * Added .disp, .btype, .ftype to H5F_access_t. *------------------------------------------------------------------------- */ -herr_t +static herr_t H5F_init_interface(void) { herr_t ret_value = SUCCEED; - interface_initialize_g = TRUE; FUNC_ENTER(H5F_init_interface, FAIL); #ifdef HAVE_PARALLEL diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index 3014d1c..06b7e60 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -544,7 +544,7 @@ extern hbool_t H5_mpi_1_metawrite_g; #endif /* HAVE_PARALLEL */ /* Private functions, not part of the publicly documented API */ -herr_t H5F_init_interface(void); +herr_t H5F_init(void); void H5F_encode_length_unusual(const H5F_t *f, uint8_t **p, uint8_t *l); H5F_t *H5F_open(const char *name, uintn flags, const H5F_create_t *create_parms, diff --git a/src/H5Ofill.c b/src/H5Ofill.c index 840ea01..3bfff1a 100644 --- a/src/H5Ofill.c +++ b/src/H5Ofill.c @@ -308,15 +308,10 @@ H5O_fill_debug(H5F_t __unused__ *f, const void *_mesg, FILE *stream, herr_t H5O_fill_convert(H5O_fill_t *fill, H5T_t *dset_type) { - H5T_cdata_t *cdata=NULL; /*conversion data */ - H5T_conv_t cfunc=NULL; /*conversion function */ + H5T_path_t *tpath=NULL; /*type conversion info */ void *buf=NULL, *bkg=NULL; /*conversion buffers */ - herr_t status; /*conversion status */ hid_t src_id=-1, dst_id=-1; /*data type identifiers */ herr_t ret_value=FAIL; /*return value */ -#ifdef H5T_DEBUG - H5_timer_t timer; /*debugging timer */ -#endif FUNC_ENTER(H5O_fill_convert, FAIL); assert(fill); @@ -332,7 +327,7 @@ H5O_fill_convert(H5O_fill_t *fill, H5T_t *dset_type) /* * Can we convert between source and destination data types? */ - if (NULL==(cfunc=H5T_find(fill->type, dset_type, H5T_BKG_NO, &cdata))) { + if (NULL==(tpath=H5T_path_find(fill->type, dset_type, NULL, NULL))) { HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and dst data types"); } @@ -357,22 +352,14 @@ H5O_fill_convert(H5O_fill_t *fill, H5T_t *dset_type) } HDmemcpy(buf, fill->buf, H5T_get_size(fill->type)); } - if (cdata->need_bkg>=H5T_BKG_TEMP && + if (tpath->cdata.need_bkg>=H5T_BKG_TEMP && NULL==(bkg=H5MM_malloc(H5T_get_size(dset_type)))) { HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); } /* Do the conversion */ -#ifdef H5T_DEBUG - H5T_timer_begin(&timer, cdata); -#endif - cdata->command = H5T_CONV_CONV; - status = (cfunc)(src_id, dst_id, cdata, 1, buf, bkg); -#ifdef H5T_DEBUG - H5T_timer_end(&timer, cdata, 1); -#endif - if (status<0) { + if (H5T_convert(tpath, src_id, dst_id, 1, buf, bkg)<0) { HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed"); } @@ -58,7 +58,7 @@ H5P_init_interface(void) * initialized since this might be done at run-time instead of compile * time. */ - if (H5F_init_interface ()<0) { + if (H5F_init()<0) { HRETURN_ERROR (H5E_INTERNAL, H5E_CANTINIT, FAIL, "unable to initialize H5F and H5P interfaces"); } @@ -2643,18 +2643,13 @@ H5Pset_fill_value(hid_t plist_id, hid_t type_id, const void *value) herr_t H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/) { - H5D_create_t *plist = NULL; - H5T_t *type = NULL; - H5T_cdata_t *cdata = NULL; /*conversion data */ - H5T_conv_t cfunc = NULL; /*conversion function */ + H5D_create_t *plist = NULL; /*property list */ + H5T_t *type = NULL; /*data type */ + H5T_path_t *tpath = NULL; /*type conversion info */ void *buf = NULL; /*conversion buffer */ void *bkg = NULL; /*conversion buffer */ hid_t src_id = -1; /*source data type id */ - herr_t status; - herr_t ret_value = FAIL; -#ifdef H5T_DEBUG - H5_timer_t timer; /*conversion timer */ -#endif + herr_t ret_value = FAIL; /*return value */ FUNC_ENTER(H5Pget_fill_value, FAIL); H5TRACE3("e","iix",plist_id,type_id,value); @@ -2686,7 +2681,7 @@ H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/) /* * Can we convert between the source and destination data types? */ - if (NULL==(cfunc=H5T_find(plist->fill.type, type, H5T_BKG_NO, &cdata))) { + if (NULL==(tpath=H5T_path_find(plist->fill.type, type, NULL, NULL))) { HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and dst data types"); } @@ -2704,7 +2699,7 @@ H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/) */ if (H5T_get_size(type)>=H5T_get_size(plist->fill.type)) { buf = value; - if (cdata->need_bkg>=H5T_BKG_TEMP && + if (tpath->cdata.need_bkg>=H5T_BKG_TEMP && NULL==(bkg=H5MM_malloc(H5T_get_size(type)))) { HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); @@ -2714,20 +2709,12 @@ H5Pget_fill_value(hid_t plist_id, hid_t type_id, void *value/*out*/) HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for type conversion"); } - if (cdata->need_bkg>=H5T_BKG_TEMP) bkg = value; + if (tpath->cdata.need_bkg>=H5T_BKG_TEMP) bkg = value; } HDmemcpy(buf, plist->fill.buf, H5T_get_size(plist->fill.type)); /* Do the conversion */ -#ifdef H5T_DEBUG - H5T_timer_begin(&timer, cdata); -#endif - cdata->command = H5T_CONV_CONV; - status = (cfunc)(src_id, type_id, cdata, 1, buf, bkg); -#ifdef H5T_DEBUG - H5T_timer_end(&timer, cdata, 1); -#endif - if (status<0) { + if (H5T_convert(tpath, src_id, type_id, 1, buf, bkg)<0) { HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed"); } @@ -28,7 +28,12 @@ static char RcsId[] = "@(#)$Revision$"; /* Interface initialization */ static intn interface_initialize_g = 0; #define INTERFACE_INIT H5T_init_interface +static herr_t H5T_init_interface(void); +/* + * Predefined data types. These are initialized at runtime in H5Tinit.c and + * by H5T_init_interface() in this source file. + */ hid_t H5T_IEEE_F32BE_g = FAIL; hid_t H5T_IEEE_F32LE_g = FAIL; hid_t H5T_IEEE_F64BE_g = FAIL; @@ -93,6 +98,10 @@ hid_t H5T_NATIVE_HSSIZE_g = FAIL; hid_t H5T_NATIVE_HERR_g = FAIL; hid_t H5T_NATIVE_HBOOL_g = FAIL; +/* + * Alignment constraints for native types. These are initialized at run time + * in H5Tinit.c + */ size_t H5T_NATIVE_SCHAR_ALIGN_g = 0; size_t H5T_NATIVE_UCHAR_ALIGN_g = 0; size_t H5T_NATIVE_SHORT_ALIGN_g = 0; @@ -107,19 +116,49 @@ size_t H5T_NATIVE_FLOAT_ALIGN_g = 0; size_t H5T_NATIVE_DOUBLE_ALIGN_g = 0; size_t H5T_NATIVE_LDOUBLE_ALIGN_g = 0; -/* The path database */ -static intn H5T_npath_g = 0; /*num paths defined */ -static intn H5T_apath_g = 0; /*num slots allocated */ -static H5T_path_t **H5T_path_g = NULL; /*path array */ - -/* The soft conversion function master list */ -static intn H5T_nsoft_g = 0; /*num soft funcs defined */ -static intn H5T_asoft_g = 0; /*num slots allocated */ -static H5T_soft_t *H5T_soft_g = NULL; /*master soft list */ +/* + * The path database. Each path has a source and destination data type pair + * which is used as the key by which the `entries' array is sorted. + */ +static struct { + intn npaths; /*number of paths defined */ + intn apaths; /*number of paths allocated */ + H5T_path_t **path; /*sorted array of path pointers */ + intn nsoft; /*number of soft conversions defined */ + intn asoft; /*number of soft conversions allocated */ + H5T_soft_t *soft; /*unsorted array of soft conversions */ +} H5T_g; /* The overflow handler */ H5T_overflow_t H5T_overflow_g = NULL; +static herr_t H5T_print_stats(H5T_path_t *path, intn *nprint/*in,out*/); + + +/*------------------------------------------------------------------------- + * Function: H5T_init + * + * Purpose: Initialize the interface from some other package. + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Robb Matzke + * Wednesday, December 16, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_init(void) +{ + FUNC_ENTER(H5T_init, FAIL); + /* FUNC_ENTER() does all the work */ + FUNC_LEAVE(SUCCEED); +} + /*-------------------------------------------------------------------------- NAME H5T_init_interface -- Initialize interface-specific information @@ -132,19 +171,21 @@ DESCRIPTION Initializes any interface-specific data or routines. --------------------------------------------------------------------------*/ -herr_t +static herr_t H5T_init_interface(void) { H5T_t *dt = NULL; + hid_t fixedpt=-1, floatpt=-1, string=-1, compound=-1; + herr_t status; + herr_t ret_value=FAIL; - interface_initialize_g = TRUE; FUNC_ENTER(H5T_init_interface, FAIL); /* Initialize the atom group for the file IDs */ if (H5I_init_group(H5I_DATATYPE, H5I_DATATYPEID_HASHSIZE, H5T_RESERVED_ATOMS, (herr_t (*)(void *))H5T_close)<0) { - HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to initialize interface"); + HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to initialize interface"); } /* @@ -152,8 +193,8 @@ H5T_init_interface(void) * the library configuration by H5detect. */ if (H5T_native_open()<0) { - HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to initialize interface"); + HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to initialize interface"); } /*------------------------------------------------------------ @@ -191,8 +232,8 @@ H5T_init_interface(void) /* Opaque data */ if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); } dt->state = H5T_STATE_IMMUTABLE; H5F_addr_undef (&(dt->ent.header)); @@ -204,8 +245,8 @@ H5T_init_interface(void) dt->u.atomic.lsb_pad = H5T_PAD_ZERO; dt->u.atomic.msb_pad = H5T_PAD_ZERO; if ((H5T_NATIVE_OPAQUE_g = H5I_register(H5I_DATATYPE, dt)) < 0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to initialize H5T layer"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to initialize H5T layer"); } /* hsize_t */ @@ -570,8 +611,8 @@ H5T_init_interface(void) /* One-byte character string */ if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); } dt->state = H5T_STATE_IMMUTABLE; H5F_addr_undef (&(dt->ent.header)); @@ -585,8 +626,8 @@ H5T_init_interface(void) dt->u.atomic.u.s.cset = H5T_CSET_ASCII; dt->u.atomic.u.s.pad = H5T_STR_NULLTERM; if ((H5T_C_S1_g = H5I_register(H5I_DATATYPE, dt)) < 0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "can't initialize H5T layer"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "can't initialize H5T layer"); } /*------------------------------------------------------------ @@ -596,8 +637,8 @@ H5T_init_interface(void) /* One-byte character string */ if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); } dt->state = H5T_STATE_IMMUTABLE; H5F_addr_undef (&(dt->ent.header)); @@ -611,8 +652,8 @@ H5T_init_interface(void) dt->u.atomic.u.s.cset = H5T_CSET_ASCII; dt->u.atomic.u.s.pad = H5T_STR_SPACEPAD; if ((H5T_FORTRAN_S1_g = H5I_register(H5I_DATATYPE, dt)) < 0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "can't initialize H5T layer"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "can't initialize H5T layer"); } /*------------------------------------------------------------ @@ -621,8 +662,8 @@ H5T_init_interface(void) */ /* Object pointer (i.e. object header address in file) */ if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); } dt->state = H5T_STATE_IMMUTABLE; H5F_addr_undef (&(dt->ent.header)); @@ -635,13 +676,13 @@ H5T_init_interface(void) dt->u.atomic.msb_pad = H5T_PAD_ZERO; dt->u.atomic.u.r.rtype = H5R_OBJECT; if ((H5T_STD_REF_OBJ_g = H5I_register(H5I_DATATYPE, dt)) < 0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to initialize H5T layer"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to initialize H5T layer"); } /* Dataset Region pointer (i.e. selection inside a dataset) */ if (NULL==(dt = H5MM_calloc(sizeof(H5T_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); } dt->state = H5T_STATE_IMMUTABLE; H5F_addr_undef (&(dt->ent.header)); @@ -654,51 +695,44 @@ H5T_init_interface(void) dt->u.atomic.msb_pad = H5T_PAD_ZERO; dt->u.atomic.u.r.rtype = H5R_DATASET_REGION; if ((H5T_STD_REF_DSETREG_g = H5I_register(H5I_DATATYPE, dt)) < 0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to initialize H5T layer"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to initialize H5T layer"); } - + fixedpt = H5T_NATIVE_INT; + floatpt = H5T_NATIVE_FLOAT; + string = H5T_C_S1; + compound = H5Tcreate(H5T_COMPOUND, 1); + status = 0; /* * Register conversion functions beginning with the most general and * ending with the most specific. */ - if (H5Tregister_soft ("i_i", H5T_INTEGER, H5T_INTEGER, H5T_conv_i_i)<0) { - HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_soft ("f_f", H5T_FLOAT, H5T_FLOAT, H5T_conv_f_f)<0) { - HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_soft("s_s", H5T_STRING, H5T_STRING, H5T_conv_s_s)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_soft("ibo", H5T_INTEGER, H5T_INTEGER, H5T_conv_order)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_soft("fbo", H5T_FLOAT, H5T_FLOAT, H5T_conv_order)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_soft ("struct", H5T_COMPOUND, H5T_COMPOUND, - H5T_conv_struct)<0) { - HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } + status |= H5Tregister(H5T_PERS_SOFT, "i_i", + fixedpt, fixedpt, + H5T_conv_i_i); + status |= H5Tregister(H5T_PERS_SOFT, "f_f", + floatpt, floatpt, + H5T_conv_f_f); + status |= H5Tregister(H5T_PERS_SOFT, "s_s", + string, string, + H5T_conv_s_s); + status |= H5Tregister(H5T_PERS_SOFT, "ibo", + fixedpt, fixedpt, + H5T_conv_order); + status |= H5Tregister(H5T_PERS_SOFT, "fbo", + floatpt, floatpt, + H5T_conv_order); + status |= H5Tregister(H5T_PERS_SOFT, "struct", + compound, compound, + H5T_conv_struct); - if (H5Tregister_hard ("u32le_f64le", H5T_STD_U32LE_g, H5T_IEEE_F64LE_g, - H5T_conv_i32le_f64le)<0) { - HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard ("i32le_f64le", H5T_STD_I32LE_g, H5T_IEEE_F64LE_g, - H5T_conv_i32le_f64le)<0) { - HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } + status |= H5Tregister(H5T_PERS_HARD, "u32le_f64le", + H5T_STD_U32LE_g, H5T_IEEE_F64LE_g, + H5T_conv_i32le_f64le); + status |= H5Tregister(H5T_PERS_HARD, "i32le_f64le", + H5T_STD_I32LE_g, H5T_IEEE_F64LE_g, + H5T_conv_i32le_f64le); /* * Native conversions should be listed last since we can use hardware to @@ -707,478 +741,313 @@ H5T_init_interface(void) * diagnostics are printed we favor the usual names over the odd names * when two or more types are the same size. */ - if (H5Tregister_hard("flt_dbl", H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE, - H5T_conv_float_double)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("dbl_flt", H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT, - H5T_conv_double_float)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } + + /* floating point */ + status |= H5Tregister(H5T_PERS_HARD, "flt_dbl", + H5T_NATIVE_FLOAT, H5T_NATIVE_DOUBLE, + H5T_conv_float_double); + status |= H5Tregister(H5T_PERS_HARD, "dbl_flt", + H5T_NATIVE_DOUBLE, H5T_NATIVE_FLOAT, + H5T_conv_double_float); /* from long_long */ - if (H5Tregister_hard("llong_ullong", H5T_NATIVE_LLONG, H5T_NATIVE_ULLONG, - H5T_conv_llong_ullong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ullong_llong", H5T_NATIVE_ULLONG, H5T_NATIVE_LLONG, - H5T_conv_ullong_llong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("llong_long", H5T_NATIVE_LLONG, H5T_NATIVE_LONG, - H5T_conv_llong_long)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("llong_ulong", H5T_NATIVE_LLONG, H5T_NATIVE_ULONG, - H5T_conv_llong_ulong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ullong_long", H5T_NATIVE_ULLONG, H5T_NATIVE_LONG, - H5T_conv_ullong_long)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ullong_ulong", H5T_NATIVE_ULLONG, H5T_NATIVE_ULONG, - H5T_conv_ullong_ulong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("llong_short", H5T_NATIVE_LLONG, H5T_NATIVE_SHORT, - H5T_conv_llong_short)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("llong_ushort", H5T_NATIVE_LLONG, H5T_NATIVE_USHORT, - H5T_conv_llong_ushort)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ullong_short", H5T_NATIVE_ULLONG, H5T_NATIVE_SHORT, - H5T_conv_ullong_short)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ullong_ushort", H5T_NATIVE_ULLONG, H5T_NATIVE_USHORT, - H5T_conv_ullong_ushort)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("llong_int", H5T_NATIVE_LLONG, H5T_NATIVE_INT, - H5T_conv_llong_int)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("llong_uint", H5T_NATIVE_LLONG, H5T_NATIVE_UINT, - H5T_conv_llong_uint)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ullong_int", H5T_NATIVE_ULLONG, H5T_NATIVE_INT, - H5T_conv_ullong_int)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ullong_uint", H5T_NATIVE_ULLONG, H5T_NATIVE_UINT, - H5T_conv_ullong_uint)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("llong_schar", H5T_NATIVE_LLONG, H5T_NATIVE_SCHAR, - H5T_conv_llong_schar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("llong_uchar", H5T_NATIVE_LLONG, H5T_NATIVE_UCHAR, - H5T_conv_llong_uchar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ullong_schar", H5T_NATIVE_ULLONG, H5T_NATIVE_SCHAR, - H5T_conv_ullong_schar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ullong_uchar", H5T_NATIVE_ULLONG, H5T_NATIVE_UCHAR, - H5T_conv_ullong_uchar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } + status |= H5Tregister(H5T_PERS_HARD, "llong_ullong", + H5T_NATIVE_LLONG, H5T_NATIVE_ULLONG, + H5T_conv_llong_ullong); + status |= H5Tregister(H5T_PERS_HARD, "ullong_llong", + H5T_NATIVE_ULLONG, H5T_NATIVE_LLONG, + H5T_conv_ullong_llong); + status |= H5Tregister(H5T_PERS_HARD, "llong_long", + H5T_NATIVE_LLONG, H5T_NATIVE_LONG, + H5T_conv_llong_long); + status |= H5Tregister(H5T_PERS_HARD, "llong_ulong", + H5T_NATIVE_LLONG, H5T_NATIVE_ULONG, + H5T_conv_llong_ulong); + status |= H5Tregister(H5T_PERS_HARD, "ullong_long", + H5T_NATIVE_ULLONG, H5T_NATIVE_LONG, + H5T_conv_ullong_long); + status |= H5Tregister(H5T_PERS_HARD, "ullong_ulong", + H5T_NATIVE_ULLONG, H5T_NATIVE_ULONG, + H5T_conv_ullong_ulong); + status |= H5Tregister(H5T_PERS_HARD, "llong_short", + H5T_NATIVE_LLONG, H5T_NATIVE_SHORT, + H5T_conv_llong_short); + status |= H5Tregister(H5T_PERS_HARD, "llong_ushort", + H5T_NATIVE_LLONG, H5T_NATIVE_USHORT, + H5T_conv_llong_ushort); + status |= H5Tregister(H5T_PERS_HARD, "ullong_short", + H5T_NATIVE_ULLONG, H5T_NATIVE_SHORT, + H5T_conv_ullong_short); + status |= H5Tregister(H5T_PERS_HARD, "ullong_ushort", + H5T_NATIVE_ULLONG, H5T_NATIVE_USHORT, + H5T_conv_ullong_ushort); + status |= H5Tregister(H5T_PERS_HARD, "llong_int", + H5T_NATIVE_LLONG, H5T_NATIVE_INT, + H5T_conv_llong_int); + status |= H5Tregister(H5T_PERS_HARD, "llong_uint", + H5T_NATIVE_LLONG, H5T_NATIVE_UINT, + H5T_conv_llong_uint); + status |= H5Tregister(H5T_PERS_HARD, "ullong_int", + H5T_NATIVE_ULLONG, H5T_NATIVE_INT, + H5T_conv_ullong_int); + status |= H5Tregister(H5T_PERS_HARD, "ullong_uint", + H5T_NATIVE_ULLONG, H5T_NATIVE_UINT, + H5T_conv_ullong_uint); + status |= H5Tregister(H5T_PERS_HARD, "llong_schar", + H5T_NATIVE_LLONG, H5T_NATIVE_SCHAR, + H5T_conv_llong_schar); + status |= H5Tregister(H5T_PERS_HARD, "llong_uchar", + H5T_NATIVE_LLONG, H5T_NATIVE_UCHAR, + H5T_conv_llong_uchar); + status |= H5Tregister(H5T_PERS_HARD, "ullong_schar", + H5T_NATIVE_ULLONG, H5T_NATIVE_SCHAR, + H5T_conv_ullong_schar); + status |= H5Tregister(H5T_PERS_HARD, "ullong_uchar", + H5T_NATIVE_ULLONG, H5T_NATIVE_UCHAR, + H5T_conv_ullong_uchar); /* From long */ - if (H5Tregister_hard("long_llong", H5T_NATIVE_LONG, H5T_NATIVE_LLONG, - H5T_conv_long_llong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("long_ullong", H5T_NATIVE_LONG, H5T_NATIVE_ULLONG, - H5T_conv_long_ullong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ulong_llong", H5T_NATIVE_ULONG, H5T_NATIVE_LLONG, - H5T_conv_ulong_llong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ulong_ullong", H5T_NATIVE_ULONG, H5T_NATIVE_ULLONG, - H5T_conv_ulong_ullong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("long_ulong", H5T_NATIVE_LONG, H5T_NATIVE_ULONG, - H5T_conv_long_ulong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ulong_long", H5T_NATIVE_ULONG, H5T_NATIVE_LONG, - H5T_conv_ulong_long)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("long_short", H5T_NATIVE_LONG, H5T_NATIVE_SHORT, - H5T_conv_long_short)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("long_ushort", H5T_NATIVE_LONG, H5T_NATIVE_USHORT, - H5T_conv_long_ushort)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ulong_short", H5T_NATIVE_ULONG, H5T_NATIVE_SHORT, - H5T_conv_ulong_short)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ulong_ushort", H5T_NATIVE_ULONG, H5T_NATIVE_USHORT, - H5T_conv_ulong_ushort)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("long_int", H5T_NATIVE_LONG, H5T_NATIVE_INT, - H5T_conv_long_int)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("long_uint", H5T_NATIVE_LONG, H5T_NATIVE_UINT, - H5T_conv_long_uint)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ulong_int", H5T_NATIVE_ULONG, H5T_NATIVE_INT, - H5T_conv_ulong_int)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ulong_uint", H5T_NATIVE_ULONG, H5T_NATIVE_UINT, - H5T_conv_ulong_uint)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("long_schar", H5T_NATIVE_LONG, H5T_NATIVE_SCHAR, - H5T_conv_long_schar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("long_uchar", H5T_NATIVE_LONG, H5T_NATIVE_UCHAR, - H5T_conv_long_uchar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ulong_schar", H5T_NATIVE_ULONG, H5T_NATIVE_SCHAR, - H5T_conv_ulong_schar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ulong_uchar", H5T_NATIVE_ULONG, H5T_NATIVE_UCHAR, - H5T_conv_ulong_uchar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } + status |= H5Tregister(H5T_PERS_HARD, "long_llong", + H5T_NATIVE_LONG, H5T_NATIVE_LLONG, + H5T_conv_long_llong); + status |= H5Tregister(H5T_PERS_HARD, "long_ullong", + H5T_NATIVE_LONG, H5T_NATIVE_ULLONG, + H5T_conv_long_ullong); + status |= H5Tregister(H5T_PERS_HARD, "ulong_llong", + H5T_NATIVE_ULONG, H5T_NATIVE_LLONG, + H5T_conv_ulong_llong); + status |= H5Tregister(H5T_PERS_HARD, "ulong_ullong", + H5T_NATIVE_ULONG, H5T_NATIVE_ULLONG, + H5T_conv_ulong_ullong); + status |= H5Tregister(H5T_PERS_HARD, "long_ulong", + H5T_NATIVE_LONG, H5T_NATIVE_ULONG, + H5T_conv_long_ulong); + status |= H5Tregister(H5T_PERS_HARD, "ulong_long", + H5T_NATIVE_ULONG, H5T_NATIVE_LONG, + H5T_conv_ulong_long); + status |= H5Tregister(H5T_PERS_HARD, "long_short", + H5T_NATIVE_LONG, H5T_NATIVE_SHORT, + H5T_conv_long_short); + status |= H5Tregister(H5T_PERS_HARD, "long_ushort", + H5T_NATIVE_LONG, H5T_NATIVE_USHORT, + H5T_conv_long_ushort); + status |= H5Tregister(H5T_PERS_HARD, "ulong_short", + H5T_NATIVE_ULONG, H5T_NATIVE_SHORT, + H5T_conv_ulong_short); + status |= H5Tregister(H5T_PERS_HARD, "ulong_ushort", + H5T_NATIVE_ULONG, H5T_NATIVE_USHORT, + H5T_conv_ulong_ushort); + status |= H5Tregister(H5T_PERS_HARD, "long_int", + H5T_NATIVE_LONG, H5T_NATIVE_INT, + H5T_conv_long_int); + status |= H5Tregister(H5T_PERS_HARD, "long_uint", + H5T_NATIVE_LONG, H5T_NATIVE_UINT, + H5T_conv_long_uint); + status |= H5Tregister(H5T_PERS_HARD, "ulong_int", + H5T_NATIVE_ULONG, H5T_NATIVE_INT, + H5T_conv_ulong_int); + status |= H5Tregister(H5T_PERS_HARD, "ulong_uint", + H5T_NATIVE_ULONG, H5T_NATIVE_UINT, + H5T_conv_ulong_uint); + status |= H5Tregister(H5T_PERS_HARD, "long_schar", + H5T_NATIVE_LONG, H5T_NATIVE_SCHAR, + H5T_conv_long_schar); + status |= H5Tregister(H5T_PERS_HARD, "long_uchar", + H5T_NATIVE_LONG, H5T_NATIVE_UCHAR, + H5T_conv_long_uchar); + status |= H5Tregister(H5T_PERS_HARD, "ulong_schar", + H5T_NATIVE_ULONG, H5T_NATIVE_SCHAR, + H5T_conv_ulong_schar); + status |= H5Tregister(H5T_PERS_HARD, "ulong_uchar", + H5T_NATIVE_ULONG, H5T_NATIVE_UCHAR, + H5T_conv_ulong_uchar); /* From short */ - if (H5Tregister_hard("short_llong", H5T_NATIVE_SHORT, H5T_NATIVE_LLONG, - H5T_conv_short_llong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("short_ullong", H5T_NATIVE_SHORT, H5T_NATIVE_ULLONG, - H5T_conv_short_ullong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ushort_llong", H5T_NATIVE_USHORT, H5T_NATIVE_LLONG, - H5T_conv_ushort_llong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ushort_ullong", H5T_NATIVE_USHORT, H5T_NATIVE_ULLONG, - H5T_conv_ushort_ullong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("short_long", H5T_NATIVE_SHORT, H5T_NATIVE_LONG, - H5T_conv_short_long)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("short_ulong", H5T_NATIVE_SHORT, H5T_NATIVE_ULONG, - H5T_conv_short_ulong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ushort_long", H5T_NATIVE_USHORT, H5T_NATIVE_LONG, - H5T_conv_ushort_long)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ushort_ulong", H5T_NATIVE_USHORT, H5T_NATIVE_ULONG, - H5T_conv_ushort_ulong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("short_ushort", H5T_NATIVE_SHORT, H5T_NATIVE_USHORT, - H5T_conv_short_ushort)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ushort_short", H5T_NATIVE_USHORT, H5T_NATIVE_SHORT, - H5T_conv_ushort_short)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("short_int", H5T_NATIVE_SHORT, H5T_NATIVE_INT, - H5T_conv_short_int)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("short_uint", H5T_NATIVE_SHORT, H5T_NATIVE_UINT, - H5T_conv_short_uint)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ushort_int", H5T_NATIVE_USHORT, H5T_NATIVE_INT, - H5T_conv_ushort_int)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ushort_uint", H5T_NATIVE_USHORT, H5T_NATIVE_UINT, - H5T_conv_ushort_uint)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("short_schar", H5T_NATIVE_SHORT, H5T_NATIVE_SCHAR, - H5T_conv_short_schar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("short_uchar", H5T_NATIVE_SHORT, H5T_NATIVE_UCHAR, - H5T_conv_short_uchar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ushort_schar", H5T_NATIVE_USHORT, H5T_NATIVE_SCHAR, - H5T_conv_ushort_schar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("ushort_uchar", H5T_NATIVE_USHORT, H5T_NATIVE_UCHAR, - H5T_conv_ushort_uchar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } + status |= H5Tregister(H5T_PERS_HARD, "short_llong", + H5T_NATIVE_SHORT, H5T_NATIVE_LLONG, + H5T_conv_short_llong); + status |= H5Tregister(H5T_PERS_HARD, "short_ullong", + H5T_NATIVE_SHORT, H5T_NATIVE_ULLONG, + H5T_conv_short_ullong); + status |= H5Tregister(H5T_PERS_HARD, "ushort_llong", + H5T_NATIVE_USHORT, H5T_NATIVE_LLONG, + H5T_conv_ushort_llong); + status |= H5Tregister(H5T_PERS_HARD, "ushort_ullong", + H5T_NATIVE_USHORT, H5T_NATIVE_ULLONG, + H5T_conv_ushort_ullong); + status |= H5Tregister(H5T_PERS_HARD, "short_long", + H5T_NATIVE_SHORT, H5T_NATIVE_LONG, + H5T_conv_short_long); + status |= H5Tregister(H5T_PERS_HARD, "short_ulong", + H5T_NATIVE_SHORT, H5T_NATIVE_ULONG, + H5T_conv_short_ulong); + status |= H5Tregister(H5T_PERS_HARD, "ushort_long", + H5T_NATIVE_USHORT, H5T_NATIVE_LONG, + H5T_conv_ushort_long); + status |= H5Tregister(H5T_PERS_HARD, "ushort_ulong", + H5T_NATIVE_USHORT, H5T_NATIVE_ULONG, + H5T_conv_ushort_ulong); + status |= H5Tregister(H5T_PERS_HARD, "short_ushort", + H5T_NATIVE_SHORT, H5T_NATIVE_USHORT, + H5T_conv_short_ushort); + status |= H5Tregister(H5T_PERS_HARD, "ushort_short", + H5T_NATIVE_USHORT, H5T_NATIVE_SHORT, + H5T_conv_ushort_short); + status |= H5Tregister(H5T_PERS_HARD, "short_int", + H5T_NATIVE_SHORT, H5T_NATIVE_INT, + H5T_conv_short_int); + status |= H5Tregister(H5T_PERS_HARD, "short_uint", + H5T_NATIVE_SHORT, H5T_NATIVE_UINT, + H5T_conv_short_uint); + status |= H5Tregister(H5T_PERS_HARD, "ushort_int", + H5T_NATIVE_USHORT, H5T_NATIVE_INT, + H5T_conv_ushort_int); + status |= H5Tregister(H5T_PERS_HARD, "ushort_uint", + H5T_NATIVE_USHORT, H5T_NATIVE_UINT, + H5T_conv_ushort_uint); + status |= H5Tregister(H5T_PERS_HARD, "short_schar", + H5T_NATIVE_SHORT, H5T_NATIVE_SCHAR, + H5T_conv_short_schar); + status |= H5Tregister(H5T_PERS_HARD, "short_uchar", + H5T_NATIVE_SHORT, H5T_NATIVE_UCHAR, + H5T_conv_short_uchar); + status |= H5Tregister(H5T_PERS_HARD, "ushort_schar", + H5T_NATIVE_USHORT, H5T_NATIVE_SCHAR, + H5T_conv_ushort_schar); + status |= H5Tregister(H5T_PERS_HARD, "ushort_uchar", + H5T_NATIVE_USHORT, H5T_NATIVE_UCHAR, + H5T_conv_ushort_uchar); /* From int */ - if (H5Tregister_hard("int_llong", H5T_NATIVE_INT, H5T_NATIVE_LLONG, - H5T_conv_int_llong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("int_ullong", H5T_NATIVE_INT, H5T_NATIVE_ULLONG, - H5T_conv_int_ullong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uint_llong", H5T_NATIVE_UINT, H5T_NATIVE_LLONG, - H5T_conv_uint_llong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uint_ullong", H5T_NATIVE_UINT, H5T_NATIVE_ULLONG, - H5T_conv_uint_ullong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("int_long", H5T_NATIVE_INT, H5T_NATIVE_LONG, - H5T_conv_int_long)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("int_ulong", H5T_NATIVE_INT, H5T_NATIVE_ULONG, - H5T_conv_int_ulong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uint_long", H5T_NATIVE_UINT, H5T_NATIVE_LONG, - H5T_conv_uint_long)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uint_ulong", H5T_NATIVE_UINT, H5T_NATIVE_ULONG, - H5T_conv_uint_ulong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("int_short", H5T_NATIVE_INT, H5T_NATIVE_SHORT, - H5T_conv_int_short)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("int_ushort", H5T_NATIVE_INT, H5T_NATIVE_USHORT, - H5T_conv_int_ushort)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uint_short", H5T_NATIVE_UINT, H5T_NATIVE_SHORT, - H5T_conv_uint_short)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uint_ushort", H5T_NATIVE_UINT, H5T_NATIVE_USHORT, - H5T_conv_uint_ushort)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("int_uint", H5T_NATIVE_INT, H5T_NATIVE_UINT, - H5T_conv_int_uint)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uint_int", H5T_NATIVE_UINT, H5T_NATIVE_INT, - H5T_conv_uint_int)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("int_schar", H5T_NATIVE_INT, H5T_NATIVE_SCHAR, - H5T_conv_int_schar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("int_uchar", H5T_NATIVE_INT, H5T_NATIVE_UCHAR, - H5T_conv_int_uchar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uint_schar", H5T_NATIVE_UINT, H5T_NATIVE_SCHAR, - H5T_conv_uint_schar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uint_uchar", H5T_NATIVE_UINT, H5T_NATIVE_UCHAR, - H5T_conv_uint_uchar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } + status |= H5Tregister(H5T_PERS_HARD, "int_llong", + H5T_NATIVE_INT, H5T_NATIVE_LLONG, + H5T_conv_int_llong); + status |= H5Tregister(H5T_PERS_HARD, "int_ullong", + H5T_NATIVE_INT, H5T_NATIVE_ULLONG, + H5T_conv_int_ullong); + status |= H5Tregister(H5T_PERS_HARD, "uint_llong", + H5T_NATIVE_UINT, H5T_NATIVE_LLONG, + H5T_conv_uint_llong); + status |= H5Tregister(H5T_PERS_HARD, "uint_ullong", + H5T_NATIVE_UINT, H5T_NATIVE_ULLONG, + H5T_conv_uint_ullong); + status |= H5Tregister(H5T_PERS_HARD, "int_long", + H5T_NATIVE_INT, H5T_NATIVE_LONG, + H5T_conv_int_long); + status |= H5Tregister(H5T_PERS_HARD, "int_ulong", + H5T_NATIVE_INT, H5T_NATIVE_ULONG, + H5T_conv_int_ulong); + status |= H5Tregister(H5T_PERS_HARD, "uint_long", + H5T_NATIVE_UINT, H5T_NATIVE_LONG, + H5T_conv_uint_long); + status |= H5Tregister(H5T_PERS_HARD, "uint_ulong", + H5T_NATIVE_UINT, H5T_NATIVE_ULONG, + H5T_conv_uint_ulong); + status |= H5Tregister(H5T_PERS_HARD, "int_short", + H5T_NATIVE_INT, H5T_NATIVE_SHORT, + H5T_conv_int_short); + status |= H5Tregister(H5T_PERS_HARD, "int_ushort", + H5T_NATIVE_INT, H5T_NATIVE_USHORT, + H5T_conv_int_ushort); + status |= H5Tregister(H5T_PERS_HARD, "uint_short", + H5T_NATIVE_UINT, H5T_NATIVE_SHORT, + H5T_conv_uint_short); + status |= H5Tregister(H5T_PERS_HARD, "uint_ushort", + H5T_NATIVE_UINT, H5T_NATIVE_USHORT, + H5T_conv_uint_ushort); + status |= H5Tregister(H5T_PERS_HARD, "int_uint", + H5T_NATIVE_INT, H5T_NATIVE_UINT, + H5T_conv_int_uint); + status |= H5Tregister(H5T_PERS_HARD, "uint_int", + H5T_NATIVE_UINT, H5T_NATIVE_INT, + H5T_conv_uint_int); + status |= H5Tregister(H5T_PERS_HARD, "int_schar", + H5T_NATIVE_INT, H5T_NATIVE_SCHAR, + H5T_conv_int_schar); + status |= H5Tregister(H5T_PERS_HARD, "int_uchar", + H5T_NATIVE_INT, H5T_NATIVE_UCHAR, + H5T_conv_int_uchar); + status |= H5Tregister(H5T_PERS_HARD, "uint_schar", + H5T_NATIVE_UINT, H5T_NATIVE_SCHAR, + H5T_conv_uint_schar); + status |= H5Tregister(H5T_PERS_HARD, "uint_uchar", + H5T_NATIVE_UINT, H5T_NATIVE_UCHAR, + H5T_conv_uint_uchar); /* From char */ - if (H5Tregister_hard("schar_llong", H5T_NATIVE_SCHAR, H5T_NATIVE_LLONG, - H5T_conv_schar_llong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("schar_ullong", H5T_NATIVE_SCHAR, H5T_NATIVE_ULLONG, - H5T_conv_schar_ullong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uchar_llong", H5T_NATIVE_UCHAR, H5T_NATIVE_LLONG, - H5T_conv_uchar_llong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uchar_ullong", H5T_NATIVE_UCHAR, H5T_NATIVE_ULLONG, - H5T_conv_uchar_ullong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("schar_long", H5T_NATIVE_SCHAR, H5T_NATIVE_LONG, - H5T_conv_schar_long)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("schar_ulong", H5T_NATIVE_SCHAR, H5T_NATIVE_ULONG, - H5T_conv_schar_ulong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uchar_long", H5T_NATIVE_UCHAR, H5T_NATIVE_LONG, - H5T_conv_uchar_long)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uchar_ulong", H5T_NATIVE_UCHAR, H5T_NATIVE_ULONG, - H5T_conv_uchar_ulong)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("schar_short", H5T_NATIVE_SCHAR, H5T_NATIVE_SHORT, - H5T_conv_schar_short)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("schar_ushort", H5T_NATIVE_SCHAR, H5T_NATIVE_USHORT, - H5T_conv_schar_ushort)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uchar_short", H5T_NATIVE_UCHAR, H5T_NATIVE_SHORT, - H5T_conv_uchar_short)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uchar_ushort", H5T_NATIVE_UCHAR, H5T_NATIVE_USHORT, - H5T_conv_uchar_ushort)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("schar_int", H5T_NATIVE_SCHAR, H5T_NATIVE_INT, - H5T_conv_schar_int)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("schar_uint", H5T_NATIVE_SCHAR, H5T_NATIVE_UINT, - H5T_conv_schar_uint)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uchar_int", H5T_NATIVE_UCHAR, H5T_NATIVE_INT, - H5T_conv_uchar_int)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uchar_uint", H5T_NATIVE_UCHAR, H5T_NATIVE_UINT, - H5T_conv_uchar_uint)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("schar_uchar", H5T_NATIVE_SCHAR, H5T_NATIVE_UCHAR, - H5T_conv_schar_uchar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); - } - if (H5Tregister_hard("uchar_schar", H5T_NATIVE_UCHAR, H5T_NATIVE_SCHAR, - H5T_conv_uchar_schar)<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to register conversion function"); + status |= H5Tregister(H5T_PERS_HARD, "schar_llong", + H5T_NATIVE_SCHAR, H5T_NATIVE_LLONG, + H5T_conv_schar_llong); + status |= H5Tregister(H5T_PERS_HARD, "schar_ullong", + H5T_NATIVE_SCHAR, H5T_NATIVE_ULLONG, + H5T_conv_schar_ullong); + status |= H5Tregister(H5T_PERS_HARD, "uchar_llong", + H5T_NATIVE_UCHAR, H5T_NATIVE_LLONG, + H5T_conv_uchar_llong); + status |= H5Tregister(H5T_PERS_HARD, "uchar_ullong", + H5T_NATIVE_UCHAR, H5T_NATIVE_ULLONG, + H5T_conv_uchar_ullong); + status |= H5Tregister(H5T_PERS_HARD, "schar_long", + H5T_NATIVE_SCHAR, H5T_NATIVE_LONG, + H5T_conv_schar_long); + status |= H5Tregister(H5T_PERS_HARD, "schar_ulong", + H5T_NATIVE_SCHAR, H5T_NATIVE_ULONG, + H5T_conv_schar_ulong); + status |= H5Tregister(H5T_PERS_HARD, "uchar_long", + H5T_NATIVE_UCHAR, H5T_NATIVE_LONG, + H5T_conv_uchar_long); + status |= H5Tregister(H5T_PERS_HARD, "uchar_ulong", + H5T_NATIVE_UCHAR, H5T_NATIVE_ULONG, + H5T_conv_uchar_ulong); + status |= H5Tregister(H5T_PERS_HARD, "schar_short", + H5T_NATIVE_SCHAR, H5T_NATIVE_SHORT, + H5T_conv_schar_short); + status |= H5Tregister(H5T_PERS_HARD, "schar_ushort", + H5T_NATIVE_SCHAR, H5T_NATIVE_USHORT, + H5T_conv_schar_ushort); + status |= H5Tregister(H5T_PERS_HARD, "uchar_short", + H5T_NATIVE_UCHAR, H5T_NATIVE_SHORT, + H5T_conv_uchar_short); + status |= H5Tregister(H5T_PERS_HARD, "uchar_ushort", + H5T_NATIVE_UCHAR, H5T_NATIVE_USHORT, + H5T_conv_uchar_ushort); + status |= H5Tregister(H5T_PERS_HARD, "schar_int", + H5T_NATIVE_SCHAR, H5T_NATIVE_INT, + H5T_conv_schar_int); + status |= H5Tregister(H5T_PERS_HARD, "schar_uint", + H5T_NATIVE_SCHAR, H5T_NATIVE_UINT, + H5T_conv_schar_uint); + status |= H5Tregister(H5T_PERS_HARD, "uchar_int", + H5T_NATIVE_UCHAR, H5T_NATIVE_INT, + H5T_conv_uchar_int); + status |= H5Tregister(H5T_PERS_HARD, "uchar_uint", + H5T_NATIVE_UCHAR, H5T_NATIVE_UINT, + H5T_conv_uchar_uint); + status |= H5Tregister(H5T_PERS_HARD, "schar_uchar", + H5T_NATIVE_SCHAR, H5T_NATIVE_UCHAR, + H5T_conv_schar_uchar); + status |= H5Tregister(H5T_PERS_HARD, "uchar_schar", + H5T_NATIVE_UCHAR, H5T_NATIVE_SCHAR, + H5T_conv_uchar_schar); + + /* + * The special no-op conversion is the fastest, so we list it last. The + * data types we use are not important as long as the source and + * destination are equal. + */ + status |= H5Tregister(H5T_PERS_HARD, "no-op", + H5T_NATIVE_INT, H5T_NATIVE_INT, + H5T_conv_noop); + + if (status<0) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to register conversion function(s)"); } - FUNC_LEAVE(SUCCEED); + ret_value = SUCCEED; + done: + if (compound>=0) H5Tclose(compound); + FUNC_LEAVE(ret_value); } @@ -1231,118 +1100,43 @@ H5T_unlock_cb (void *_dt, const void __unused__ *key) void H5T_term_interface(intn status) { - intn i; + intn i, nprint=0; H5T_path_t *path = NULL; - H5T_cdata_t *pcdata = NULL; - H5T_conv_t cfunc = NULL; -#ifdef H5T_DEBUG - intn nprint=0; - hsize_t nbytes; - H5T_cdata_t *cdata; - char bandwidth[32]; -#endif if (interface_initialize_g>0) { + /* Unregister all conversion functions */ - for (i=0; i<H5T_npath_g; i++) { - path = H5T_path_g[i]; + for (i=0; i<H5T_g.npaths; i++) { + path = H5T_g.path[i]; assert (path); if (path->func) { + H5T_print_stats(path, &nprint/*in,out*/); path->cdata.command = H5T_CONV_FREE; - if ((path->func)(FAIL, FAIL, &(path->cdata), 0, NULL, - NULL)<0) { + if ((path->func)(FAIL, FAIL, &(path->cdata), + 0, NULL, NULL)<0) { #ifdef H5T_DEBUG if (H5DEBUG(T)) { - fprintf (H5DEBUG(T), "H5T: conversion function failed " - "to free private data for %s\n", path->name); + fprintf (H5DEBUG(T), "H5T: conversion function " + "0x%08lx failed to free private data for %s " + "(ignored)\n", + (unsigned long)(path->func), path->name); } #endif H5E_clear(); /*ignore the error*/ } -#ifdef H5T_DEBUG - if (H5DEBUG(T) && path->cdata.stats->ncalls>0) { - if (0==nprint++) { - HDfprintf (H5DEBUG(T), - "H5T: type conversion statistics:\n"); - HDfprintf (H5DEBUG(T), - " %-16s %10s %10s %8s %8s %8s %10s\n", - "Conversion", "Elmts", "Calls", "User", - "System", "Elapsed", "Bandwidth"); - HDfprintf (H5DEBUG(T), - " %-16s %10s %10s %8s %8s %8s %10s\n", - "----------", "-----", "-----", "----", - "------", "-------", "---------"); - } - nbytes = MAX (H5T_get_size (path->src), - H5T_get_size (path->dst)); - nbytes *= path->cdata.stats->nelmts; - H5_bandwidth(bandwidth, (double)nbytes, - path->cdata.stats->timer.etime); - HDfprintf (H5DEBUG(T), - " %-16s %10Hd %10d %8.2f %8.2f %8.2f %10s\n", - path->name, - path->cdata.stats->nelmts, - path->cdata.stats->ncalls, - path->cdata.stats->timer.utime, - path->cdata.stats->timer.stime, - path->cdata.stats->timer.etime, - bandwidth); - } -#endif - H5T_close (path->src); - H5T_close (path->dst); - H5MM_xfree (path->cdata.stats); } + H5T_close (path->src); + H5T_close (path->dst); H5MM_xfree (path); - H5T_path_g[i] = NULL; + H5T_g.path[i] = NULL; } -#ifdef H5T_DEBUG - /* Print debugging infor for the `noop' conversion */ - if (H5DEBUG(T) && - H5T_conv_noop==H5T_find(NULL, NULL, H5T_BKG_NO, &cdata)) { - if (cdata->stats->ncalls>0) { - if (0==nprint++) { - HDfprintf (H5DEBUG(T), - "H5T: type conversion statistics\n"); - HDfprintf (H5DEBUG(T), " %-16s %10s %10s %8s %8s %8s " - "%10s\n", "Conversion", "Elmts", "Calls", - "User", "System", "Elapsed", "Bandwidth"); - HDfprintf (H5DEBUG(T), " %-16s %10s %10s %8s %8s %8s " - "%10s\n", "----------", "-----", "-----", - "----", "------", "-------", "---------"); - } - nbytes = cdata->stats->nelmts; - H5_bandwidth(bandwidth, (double)nbytes, - cdata->stats->timer.etime); - HDfprintf (H5DEBUG(T), - " %-16s %10Hd %10d %8.2f %8.2f %8.2f %10s\n", - "no-op", - cdata->stats->nelmts, - cdata->stats->ncalls, - cdata->stats->timer.utime, - cdata->stats->timer.stime, - cdata->stats->timer.etime, - bandwidth); - } - } -#endif - /* Clear conversion tables */ - H5T_apath_g = 0; - H5T_npath_g = 0; - H5T_path_g = H5MM_xfree (H5T_path_g); - - H5T_asoft_g = 0; - H5T_nsoft_g = 0; - H5T_soft_g = H5MM_xfree (H5T_soft_g); - - /* Clear noop function */ - if ((cfunc=H5T_find (NULL, NULL, H5T_BKG_NO, &pcdata))) { - pcdata->command = H5T_CONV_FREE; - (cfunc)(FAIL, FAIL, pcdata, 0, NULL, NULL); - } + H5T_g.path = H5MM_xfree(H5T_g.path); + H5T_g.npaths = H5T_g.apaths = 0; + H5T_g.soft = H5MM_xfree(H5T_g.soft); + H5T_g.nsoft = H5T_g.asoft = 0; /* Unlock all datatypes, then free them */ H5I_search (H5I_DATATYPE, H5T_unlock_cb, NULL); @@ -3418,18 +3212,16 @@ H5Tpack(hid_t type_id) /*------------------------------------------------------------------------- - * Function: H5Tregister_hard + * Function: H5Tregister * - * Purpose: Register a hard conversion function for a data type + * Purpose: Register a hard or soft conversion function for a data type * conversion path. The path is specified by the source and - * destination data types SRC_ID and DST_ID. A conversion path - * can only have one hard function, so FUNC replaces any - * previous hard function. - * - * If FUNC is the null pointer then any hard function registered - * for this path is removed from this path. The soft functions - * are then used when determining which conversion function is - * appropriate for this path. + * destination data types SRC_ID and DST_ID (for soft functions + * only the class of these types is important). If FUNC is a + * hard function then it replaces any previous path; if it's a + * soft function then it replaces all existing paths to which it + * applies and is used for any new path to which it applies as + * long as that path doesn't have a hard function. * * Return: Non-negative on success/Negative on failure * @@ -3441,231 +3233,187 @@ H5Tpack(hid_t type_id) *------------------------------------------------------------------------- */ herr_t -H5Tregister_hard(const char *name, hid_t src_id, hid_t dst_id, - H5T_conv_t func) +H5Tregister(H5T_pers_t pers, const char *name, hid_t src_id, hid_t dst_id, + H5T_conv_t func) { - H5T_t *src = NULL; - H5T_t *dst = NULL; - H5T_path_t *path = NULL; - intn i; - hsize_t nbytes; - char bandwidth[32]; - - FUNC_ENTER(H5Tregister_hard, FAIL); - H5TRACE4("e","siix",name,src_id,dst_id,func); + H5T_t *src=NULL; /*source data type descriptor */ + H5T_t *dst=NULL; /*destination data type desc */ + hid_t tmp_sid=-1, tmp_did=-1;/*temporary data type IDs */ + H5T_path_t *old_path=NULL; /*existing conversion path */ + H5T_path_t *new_path=NULL; /*new conversion path */ + H5T_cdata_t cdata; /*temporary conversion data */ + intn nprint=0; /*number of paths shut down */ + intn i; /*counter */ + herr_t ret_value=FAIL; /*return value */ + + FUNC_ENTER(H5Tregister, FAIL); + H5TRACE5("e","Tesiix",pers,name,src_id,dst_id,func); /* Check args */ - if (!name || !*name) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, - "conversion must have a name for debugging"); - } - if (H5I_DATATYPE != H5I_get_type(src_id) || - NULL == (src = H5I_object(src_id)) || - H5I_DATATYPE != H5I_get_type(dst_id) || - NULL == (dst = H5I_object(dst_id))) { - HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); - } - - if (!func && (path=H5T_path_find(NULL, src, dst, FALSE, NULL))) { - /* Free the private data for the function */ - path->cdata.command = H5T_CONV_FREE; - if ((func)(FAIL, FAIL, &(path->cdata), 0, NULL, NULL)<0) { -#ifdef H5T_DEBUG - if (H5DEBUG(T)) { - fprintf(H5DEBUG(T), "H5T: conversion function free failed " - "for %s\n", path->name); - } -#endif - H5E_clear(); /*ignore the failure*/ - } - -#ifdef H5T_DEBUG - /* - * Print statistics about the function we're removing because we - * won't get a chance to do it later. - */ - if (H5DEBUG(T) && path->cdata.stats->ncalls>0) { - HDfprintf(H5DEBUG(T), "H5T: conversion statistics accumulated " - "over life of function:\n"); - nbytes = MAX(H5T_get_size(path->src), H5T_get_size(path->dst)); - nbytes *= path->cdata.stats->nelmts; - H5_bandwidth(bandwidth, (double)nbytes, - path->cdata.stats->timer.etime); - HDfprintf(H5DEBUG(T), - " %-16s %10Hd %10d %8.2f %8.2f %8.2f %10s\n", - path->name, - path->cdata.stats->nelmts, - path->cdata.stats->ncalls, - path->cdata.stats->timer.utime, - path->cdata.stats->timer.stime, - path->cdata.stats->timer.etime, - bandwidth); - } -#endif - - /* Clear the path */ - path->name[0] = '\0'; - path->func = NULL; - path->is_hard = FALSE; - path->cdata.stats = H5MM_xfree(path->cdata.stats); - } - - /* Locate or create a new conversion path */ - if (NULL == (path = H5T_path_find(name, src, dst, TRUE, func))) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, - "unable to locate/allocate conversion path"); + if (H5T_PERS_HARD!=pers && H5T_PERS_SOFT!=pers) { + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "invalid function persistence"); } - - - /* - * Notify all other functions to recalculate private data since some - * functions might cache a list of conversion functions. For instance, - * the compound type converter caches a list of conversion functions for - * the members, so adding a new function should cause the list to be - * recalculated to use the new function. - */ - for (i=0; i<H5T_npath_g; i++) { - if (path != H5T_path_g[i]) { - H5T_path_g[i]->cdata.recalc = TRUE; - } - } - - FUNC_LEAVE(SUCCEED); -} - -/*------------------------------------------------------------------------- - * Function: H5Tregister_soft - * - * Purpose: Registers a soft conversion function by adding it to the end - * of the master soft list and replacing the soft function in - * all applicable existing conversion paths. - * - * Return: Non-negative on success/Negative on failure - * - * Programmer: Robb Matzke - * Tuesday, January 13, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -herr_t -H5Tregister_soft(const char *name, H5T_class_t src_cls, H5T_class_t dst_cls, - H5T_conv_t func) -{ - intn i; - hid_t src_id, dst_id; - H5T_cdata_t cdata; - - FUNC_ENTER(H5Tregister_soft, FAIL); - H5TRACE4("e","sTtTtx",name,src_cls,dst_cls,func); - - /* Check args */ if (!name || !*name) { - HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, - "conversion must have a name for debugging"); + HGOTO_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, + "conversion must have a name for debugging"); } - if (src_cls < 0 || src_cls >= H5T_NCLASSES || - dst_cls < 0 || dst_cls >= H5T_NCLASSES) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "illegal source or destination data type class"); + if (H5I_DATATYPE!=H5I_get_type(src_id) || + NULL==(src=H5I_object(src_id)) || + H5I_DATATYPE!=H5I_get_type(dst_id) || + NULL==(dst=H5I_object(dst_id))) { + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type"); } if (!func) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, - "no soft conversion function specified"); + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, + "no conversion function specified"); } - /* Add function to end of master list */ - if (H5T_nsoft_g >= H5T_asoft_g) { - size_t na = MAX (32, 2*H5T_asoft_g); - H5T_soft_t *x = H5MM_realloc (H5T_soft_g, na*sizeof(H5T_soft_t)); - if (!x) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); + if (H5T_PERS_HARD==pers) { + /* Locate or create a new conversion path */ + if (NULL==(new_path=H5T_path_find(src, dst, name, func))) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to locate/allocate conversion path"); } - H5T_asoft_g = (intn)na; - H5T_soft_g = x; - } - HDstrncpy (H5T_soft_g[H5T_nsoft_g].name, name, H5T_NAMELEN); - H5T_soft_g[H5T_nsoft_g].name[H5T_NAMELEN-1] = '\0'; - H5T_soft_g[H5T_nsoft_g].src = src_cls; - H5T_soft_g[H5T_nsoft_g].dst = dst_cls; - H5T_soft_g[H5T_nsoft_g].func = func; - H5T_nsoft_g++; - - /* Replace soft functions of all appropriate paths */ - for (i=0; i<H5T_npath_g; i++) { - H5T_path_t *path = H5T_path_g[i]; - assert (path); - path->cdata.recalc = TRUE; - - if (path->is_hard || - path->src->type!=src_cls || path->dst->type!=dst_cls) { - continue; + + /* + * Notify all other functions to recalculate private data since some + * functions might cache a list of conversion functions. For + * instance, the compound type converter caches a list of conversion + * functions for the members, so adding a new function should cause + * the list to be recalculated to use the new function. + */ + for (i=0; i<H5T_g.npaths; i++) { + if (new_path != H5T_g.path[i]) { + H5T_g.path[i]->cdata.recalc = TRUE; + } } + + } else { + /* Add function to end of soft list */ + if (H5T_g.nsoft>=H5T_g.asoft) { + size_t na = MAX(32, 2*H5T_g.asoft); + H5T_soft_t *x = H5MM_realloc(H5T_g.soft, na*sizeof(H5T_soft_t)); + if (!x) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); + } + H5T_g.asoft = (intn)na; + H5T_g.soft = x; + } + HDstrncpy (H5T_g.soft[H5T_g.nsoft].name, name, H5T_NAMELEN); + H5T_g.soft[H5T_g.nsoft].name[H5T_NAMELEN-1] = '\0'; + H5T_g.soft[H5T_g.nsoft].src = src->type; + H5T_g.soft[H5T_g.nsoft].dst = dst->type; + H5T_g.soft[H5T_g.nsoft].func = func; + H5T_g.nsoft++; /* - * Type conversion functions are app-level, so we need to convert the - * data type temporarily to an object id before we query the functions - * capabilities. + * Any existing path (except the no-op path) to which this new soft + * conversion function applies should be replaced by a new path that + * uses this function. */ - if ((src_id = H5I_register(H5I_DATATYPE, - H5T_copy(path->src, H5T_COPY_ALL))) < 0 || - (dst_id = H5I_register(H5I_DATATYPE, - H5T_copy(path->dst, H5T_COPY_ALL))) < 0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, - "unable to register data types for conv query"); - } + for (i=1; i<H5T_g.npaths; i++) { + old_path = H5T_g.path[i]; + assert(old_path); + + /* Does the new soft conversion function apply to this path? */ + if (old_path->is_hard || + old_path->src->type!=src->type || + old_path->dst->type!=dst->type) { + continue; + } + if ((tmp_sid = H5I_register(H5I_DATATYPE, + H5T_copy(old_path->src, + H5T_COPY_ALL)))<0 || + (tmp_did = H5I_register(H5I_DATATYPE, + H5T_copy(old_path->dst, + H5T_COPY_ALL)))<0) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, + "unable to register data types for conv query"); + } + HDmemset(&cdata, 0, sizeof cdata); + cdata.command = H5T_CONV_INIT; + if ((func)(tmp_sid, tmp_did, &cdata, 0, NULL, NULL)<0) { + H5I_dec_ref(tmp_sid); + H5I_dec_ref(tmp_did); + tmp_sid = tmp_did = -1; + H5E_clear(); + continue; + } - HDmemset (&cdata, 0, sizeof cdata); - cdata.command = H5T_CONV_INIT; - if (NULL==(cdata.stats = H5MM_calloc (sizeof(H5T_stats_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); - } - if ((func) (src_id, dst_id, &cdata, 0, NULL, NULL) >= 0) { - /* - * Free resources used by the previous conversion function. We - * don't really care if this fails since at worst we'll just leak - * some memory. Then initialize the path with new info. - */ - if (path->func) { - path->cdata.command = H5T_CONV_FREE; - if ((path->func)(src_id, dst_id, &(path->cdata), + /* Create a new conversion path */ + if (NULL==(new_path=H5MM_calloc(sizeof(H5T_path_t)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); + } + HDstrncpy(new_path->name, name, H5T_NAMELEN); + new_path->name[H5T_NAMELEN-1] = '\0'; + if (NULL==(new_path->src=H5T_copy(old_path->src, H5T_COPY_ALL)) || + NULL==(new_path->dst=H5T_copy(old_path->dst, H5T_COPY_ALL))) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to copy data types"); + } + new_path->func = func; + new_path->is_hard = FALSE; + new_path->cdata = cdata; + + /* Replace previous path */ + H5T_g.path[i] = new_path; + new_path = NULL; /*so we don't free it on error*/ + + /* Free old path */ + H5T_print_stats(old_path, &nprint); + old_path->cdata.command = H5T_CONV_FREE; + if ((old_path->func)(tmp_sid, tmp_did, &(old_path->cdata), 0, NULL, NULL)<0) { #ifdef H5T_DEBUG - if (H5DEBUG(T)) { - fprintf (H5DEBUG(T), "H5T: conversion function failed " - "to free private data.\n"); - } -#endif - H5E_clear(); + if (H5DEBUG(T)) { + fprintf (H5DEBUG(T), "H5T: conversion function 0x%08lx " + "failed to free private data for %s (ignored)\n", + (unsigned long)(old_path->func), old_path->name); } - H5MM_xfree (path->cdata.stats); +#endif } - HDstrncpy (path->name, name, H5T_NAMELEN); - path->name[H5T_NAMELEN-1] = '\0'; - path->func = func; - path->cdata = cdata; - } else { - H5MM_xfree (cdata.stats); - } + H5T_close(old_path->src); + H5T_close(old_path->dst); + H5MM_xfree(old_path); - /* Release temporary atoms */ - H5I_dec_ref(src_id); - H5I_dec_ref(dst_id); - H5E_clear(); + /* Release temporary atoms */ + H5I_dec_ref(tmp_sid); + H5I_dec_ref(tmp_did); + tmp_sid = tmp_did = -1; + + /* We don't care about any failures during the freeing process */ + H5E_clear(); + } } + + ret_value = SUCCEED; - FUNC_LEAVE(SUCCEED); + done: + if (ret_value<0) { + if (new_path) { + if (new_path->src) H5T_close(new_path->src); + if (new_path->dst) H5T_close(new_path->dst); + H5MM_xfree(new_path); + } + if (tmp_sid>=0) H5I_dec_ref(tmp_sid); + if (tmp_did>=0) H5I_dec_ref(tmp_did); + } + FUNC_LEAVE(ret_value); } /*------------------------------------------------------------------------- * Function: H5Tunregister * - * Purpose: Removes FUNC from all conversion paths. + * Purpose: Removes conversion paths that match the specified criteria. + * All arguments are optional. Missing arguments are wild cards. + * The special no-op path cannot be removed. * - * Return: Non-negative on success/Negative on failure + * Return: Succeess: non-negative + * + * Failure: negative * * Programmer: Robb Matzke * Tuesday, January 13, 1998 @@ -3675,102 +3423,78 @@ H5Tregister_soft(const char *name, H5T_class_t src_cls, H5T_class_t dst_cls, *------------------------------------------------------------------------- */ herr_t -H5Tunregister(H5T_conv_t func) +H5Tunregister(H5T_pers_t pers, const char *name, hid_t src_id, hid_t dst_id, + H5T_conv_t func) { - intn i, j; - H5T_path_t *path = NULL; - hid_t src_id, dst_id; + H5T_path_t *path = NULL; /*conversion path */ + H5T_soft_t *soft = NULL; /*soft conversion information */ + H5T_t *src=NULL, *dst=NULL; /*data type descriptors */ + intn nprint=0; /*number of paths shut down */ + intn i; /*counter */ FUNC_ENTER(H5Tunregister, FAIL); - H5TRACE1("e","x",func); + H5TRACE5("e","Tesiix",pers,name,src_id,dst_id,func); - /* Check args */ - if (!func) { - HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no conversion function"); - } - - /* Remove function from master soft list */ - for (i=H5T_nsoft_g-1; i>=0; --i) { - if (H5T_soft_g[i].func == func) { - HDmemmove(H5T_soft_g+i, H5T_soft_g+i+1, - (H5T_nsoft_g - (i+1)) * sizeof(H5T_soft_t)); - --H5T_nsoft_g; + /* Check arguments */ + if (src_id>0 && + (H5I_DATATYPE!=H5I_get_type(src_id) || + NULL==(src=H5I_object(src_id)))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "src is not a data type"); + } + if (dst_id>0 && + (H5I_DATATYPE!=H5I_get_type(dst_id) || + NULL==(dst=H5I_object(dst_id)))) { + HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "dst is not a data type"); + } + + /* Remove matching entries from the soft list */ + if (H5T_PERS_DONTCARE==pers || H5T_PERS_SOFT==pers) { + for (i=H5T_g.nsoft-1; i>=0; --i) { + soft = H5T_g.soft+i; + assert(soft); + if (name && *name && HDstrcmp(name, soft->name)) continue; + if (src && src->type!=soft->src) continue; + if (dst && dst->type!=soft->dst) continue; + if (func && func!=soft->func) continue; + + HDmemmove(H5T_g.soft+i, H5T_g.soft+i+1, + (H5T_g.nsoft-(i+1)) * sizeof(H5T_soft_t)); + --H5T_g.nsoft; } } - /* Remove function from all conversion paths */ - for (i=0; i<H5T_npath_g; i++) { - path = H5T_path_g[i]; - assert (path); - - if (path->func == func) { - path->func = NULL; - path->is_hard = FALSE; + /* Remove matching conversion paths, except no-op path */ + for (i=H5T_g.npaths-1; i>0; --i) { + path = H5T_g.path[i]; + assert(path); + if ((H5T_PERS_SOFT==pers && path->is_hard) || + (H5T_PERS_HARD==pers && !path->is_hard)) continue; + if (name && *name && HDstrcmp(name, path->name)) continue; + if (src && H5T_cmp(src, path->src)) continue; + if (dst && H5T_cmp(dst, path->dst)) continue; + if (func && func!=path->func) continue; + + /* Remove from table */ + HDmemmove(H5T_g.path+i, H5T_g.path+i+1, + (H5T_g.npaths-(i+1))*sizeof(H5T_path_t*)); + --H5T_g.npaths; - /* - * Reset cdata. - */ - path->cdata.command = H5T_CONV_FREE; - if ((func)(FAIL, FAIL, &(path->cdata), 0, NULL, NULL)<0) { + /* Shut down path */ + H5T_print_stats(path, &nprint); + path->cdata.command = H5T_CONV_FREE; + if ((path->func)(FAIL, FAIL, &(path->cdata), 0, NULL, NULL)<0) { #ifdef H5T_DEBUG - if (H5DEBUG(T)) { - fprintf (H5DEBUG(T), "H5T: conversion function failed to " - "free private data.\n"); - } -#endif - H5E_clear(); - } - H5MM_xfree (path->cdata.stats); - HDmemset (&(path->cdata), 0, sizeof(H5T_cdata_t)); - - /* - * Choose a new function. - */ - for (j=H5T_nsoft_g-1; j>=0 && !path->func; --j) { - - if (path->src->type != H5T_soft_g[j].src || - path->dst->type != H5T_soft_g[j].dst) { - continue; - } - - /* - * Conversion functions are app-level, so temporarily create - * object id's for the data types. - */ - if ((src_id = H5I_register(H5I_DATATYPE, - H5T_copy(path->src, - H5T_COPY_ALL))) < 0 || - (dst_id = H5I_register(H5I_DATATYPE, - H5T_copy(path->dst, - H5T_COPY_ALL))) < 0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, - "unable to register conv types for query"); - } - - path->cdata.command = H5T_CONV_INIT; - path->cdata.stats = H5MM_calloc (sizeof(H5T_stats_t)); - if (NULL==path->cdata.stats) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); - } - if ((H5T_soft_g[j].func)(src_id, dst_id, &(path->cdata), - 0, NULL, NULL) >= 0) { - HDstrcpy (path->name, H5T_soft_g[j].name); - path->func = H5T_soft_g[j].func; - } else { - H5E_clear(); - HDmemset (&(path->cdata), 0, sizeof(H5T_cdata_t)); - } - H5I_dec_ref(src_id); - H5I_dec_ref(dst_id); + if (H5DEBUG(T)) { + fprintf(H5DEBUG(T), "H5T: conversion function 0x%08lx failed " + "to free private data for %s (ignored)\n", + (unsigned long)(path->func), path->name); } - } else { - /* - * If the soft function didn't change then make sure it - * recalculates its private data at the next opportunity. - */ - path->cdata.recalc = TRUE; +#endif } + H5T_close(path->src); + H5T_close(path->dst); + H5MM_xfree(path); + H5E_clear(); /*ignore all shutdown errors*/ } FUNC_LEAVE(SUCCEED); @@ -3782,7 +3506,7 @@ H5Tunregister(H5T_conv_t func) * Purpose: Finds a conversion function that can handle a conversion from * type SRC_ID to type DST_ID. The PCDATA argument is a pointer * to a pointer to type conversion data which was created and - * initialized by the soft type conversion function of this path + * initialized by the type conversion function of this path * when the conversion function was installed on the path. * * Return: Success: A pointer to a suitable conversion function. @@ -3801,6 +3525,7 @@ H5Tfind(hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata) { H5T_conv_t ret_value = NULL; H5T_t *src = NULL, *dst = NULL; + H5T_path_t *path = NULL; FUNC_ENTER(H5Tfind, NULL); H5TRACE3("x","iix",src_id,dst_id,pcdata); @@ -3818,11 +3543,12 @@ H5Tfind(hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata) } /* Find it */ - *pcdata = NULL; - if (NULL == (ret_value = H5T_find(src, dst, H5T_BKG_NO, pcdata))) { + if (NULL==(path=H5T_path_find(src, dst, NULL, NULL))) { HRETURN_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL, "conversion function not found"); } + if (pcdata) *pcdata = &(path->cdata); + ret_value = path->func; FUNC_LEAVE(ret_value); } @@ -3854,13 +3580,8 @@ herr_t H5Tconvert(hid_t src_id, hid_t dst_id, size_t nelmts, void *buf, void *background) { - H5T_cdata_t *cdata = NULL; /*conversion data */ - H5T_conv_t tconv_func = NULL; /*conversion function */ - herr_t status; /*func return status */ + H5T_path_t *tpath=NULL; /*type conversion info */ H5T_t *src=NULL, *dst=NULL; /*unatomized types */ -#ifdef H5T_DEBUG - H5_timer_t timer; /*conversion timer */ -#endif FUNC_ENTER (H5Tconvert, FAIL); H5TRACE5("e","iizxx",src_id,dst_id,nelmts,buf,background); @@ -3874,20 +3595,12 @@ H5Tconvert(hid_t src_id, hid_t dst_id, size_t nelmts, void *buf, } /* Find the conversion function */ - if (NULL==(tconv_func=H5T_find (src, dst, H5T_BKG_NO, &cdata))) { + if (NULL==(tpath=H5T_path_find(src, dst, NULL, NULL))) { HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert between src and dst data types"); } - -#ifdef H5T_DEBUG - H5T_timer_begin (&timer, cdata); -#endif - cdata->command = H5T_CONV_CONV; - status = (tconv_func)(src_id, dst_id, cdata, nelmts, buf, background); -#ifdef H5T_DEBUG - H5T_timer_end (&timer, cdata, nelmts); -#endif - if (status<0) { + + if (H5T_convert(tpath, src_id, dst_id, nelmts, buf, background)<0) { HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "data type conversion failed"); } @@ -4886,7 +4599,8 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2) switch(dt1->u.atomic.u.r.rtype) { case H5R_OBJECT: - case H5R_DATASET_REGION: /* Does this need more to distinguish it? -QAK 11/30/98 */ + case H5R_DATASET_REGION: + /* Does this need more to distinguish it? -QAK 11/30/98 */ /*void */ break; @@ -4907,84 +4621,27 @@ H5T_cmp(const H5T_t *dt1, const H5T_t *dt2) FUNC_LEAVE(ret_value); } - -/*------------------------------------------------------------------------- - * Function: H5T_find - * - * Purpose: Finds a conversion function for the specified path. If the - * source and destination types are the same and NEED_BKG is not - * H5T_BKG_YES then a pointer to the H5T_conv_noop() function is - * returned. - * - * NAME is assigned to the conversion path if the path is - * created. The name is only for debugging. - * - * Return: Success: A pointer to an appropriate conversion - * function. The PCDATA argument is initialized - * to point to type conversion data which should - * be passed to the type conversion function. - * - * Failure: NULL - * - * Programmer: Robb Matzke - * Wednesday, January 14, 1998 - * - * Modifications: - * - *------------------------------------------------------------------------- - */ -H5T_conv_t -H5T_find(const H5T_t *src, const H5T_t *dst, H5T_bkg_t need_bkg, - H5T_cdata_t **pcdata/*out*/) -{ - H5T_path_t *path = NULL; - H5T_conv_t ret_value = NULL; - static H5T_cdata_t noop_cdata; - - FUNC_ENTER(H5T_find, NULL); - - if (!noop_cdata.stats && - NULL==(noop_cdata.stats = H5MM_calloc (sizeof(H5T_stats_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - - /* No-op case */ - if (need_bkg<H5T_BKG_YES && 0==H5T_cmp(src, dst)) { - *pcdata = &noop_cdata; - HRETURN(H5T_conv_noop); - } - - /* Find it */ - if (NULL == (path = H5T_path_find(NULL, src, dst, TRUE, NULL))) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, - "unable to create conversion path"); - } - - if ((ret_value=path->func)) { - *pcdata = &(path->cdata); - } else { - HRETURN_ERROR(H5E_DATATYPE, H5E_NOTFOUND, NULL, - "no conversion function for that path"); - } - - FUNC_LEAVE(ret_value); -} - /*------------------------------------------------------------------------- * Function: H5T_path_find * - * Purpose: Finds the path which converts type SRC_ID to type DST_ID. If - * the path isn't found and CREATE is non-zero then a new path - * is created. If FUNC is non-null then it is registered as the - * hard function for that path. + * Purpose: Finds the path which converts type SRC_ID to type DST_ID, + * creating a new path if necessary. If FUNC is non-zero then + * it is set as the hard conversion function for that path + * regardless of whether the path previously existed. Changing + * the conversion function of a path causes statistics to be + * reset to zero after printing them. The NAME is used only + * when creating a new path and is just for debugging. * - * If a path is created then NAME is used for debugging. + * If SRC and DST are both null pointers then the special no-op + * conversion path is used. This path is always stored as the + * first path in the path table. * * Return: Success: Pointer to the path, valid until the path * database is modified. * - * Failure: NULL + * Failure: NULL if the path does not exist and no + * function can be found to apply to the new + * path. * * Programmer: Robb Matzke * Tuesday, January 13, 1998 @@ -4994,190 +4651,273 @@ H5T_find(const H5T_t *src, const H5T_t *dst, H5T_bkg_t need_bkg, *------------------------------------------------------------------------- */ H5T_path_t * -H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst, - hbool_t create, H5T_conv_t func) +H5T_path_find(const H5T_t *src, const H5T_t *dst, const char *name, + H5T_conv_t func) { - intn lt = 0; /*left edge (inclusive) */ - intn rt = H5T_npath_g; /*right edge (exclusive) */ - intn md = 0; /*middle */ - intn cmp = -1; /*comparison result */ - H5T_path_t *path = NULL; /*path found */ - int i; - hid_t src_id, dst_id; - hsize_t nbytes; - char bandwidth[32]; + intn lt, rt; /*left and right edges */ + intn md; /*middle */ + intn cmp; /*comparison result */ + H5T_path_t *table=NULL; /*path existing in the table */ + H5T_path_t *path=NULL; /*new path */ + H5T_path_t *ret_value=NULL; /*return value */ + hid_t src_id=-1, dst_id=-1; /*src and dst type identifiers */ + intn i; /*counter */ + intn nprint=0; /*lines of output printed */ FUNC_ENTER(H5T_path_find, NULL); - - /* Check args */ - assert(src); - assert(dst); - - /* Binary search */ - while (cmp && lt<rt) { - md = (lt+rt) / 2; - assert (H5T_path_g[md]); - - cmp = H5T_cmp(src, H5T_path_g[md]->src); - if (0==cmp) cmp = H5T_cmp(dst, H5T_path_g[md]->dst); - - if (cmp<0) { - rt = md; - } else if (cmp>0) { - lt = md+1; - } - } - - /* Return if the path is not found and we're not creating a new one */ - if (cmp && !create) HRETURN(NULL); - - /* - * If we found it then remember the path structure, otherwise create a - * new entry with a new path struct. - */ - if (!cmp) { - path = H5T_path_g[md]; - } else { - if (H5T_npath_g >= H5T_apath_g) { - size_t na = MAX(128, 2 * H5T_apath_g); - H5T_path_t **x = H5MM_realloc (H5T_path_g, - na*sizeof(H5T_path_t*)); - if (!x) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - H5T_apath_g = (intn)na; - H5T_path_g = x; - } - if (cmp > 0) md++; - HDmemmove(H5T_path_g + md + 1, H5T_path_g + md, - (H5T_npath_g - md) * sizeof(H5T_path_t*)); - H5T_npath_g++; - if (NULL==(path=H5T_path_g[md]=H5MM_calloc (sizeof(H5T_path_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - path->src = H5T_copy(src, H5T_COPY_ALL); - path->dst = H5T_copy(dst, H5T_COPY_ALL); - } + assert((!src && !dst) || (src && dst)); /* - * If a hard function is specified and the function doesn't match the one - * registered for the path then remove the one from the path. + * Make sure the first entry in the table is the no-op conversion path. */ - if (func && path->func && func!=path->func) { - - /* Free the private data for the function */ - path->cdata.command = H5T_CONV_FREE; - if ((func)(FAIL, FAIL, &(path->cdata), 0, NULL, NULL)<0) { + if (0==H5T_g.npaths) { + if (NULL==(H5T_g.path=H5MM_malloc(128*sizeof(H5T_path_t*)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for type conversion path " + "table"); + } + H5T_g.apaths = 128; + if (NULL==(H5T_g.path[0]=H5MM_calloc(sizeof(H5T_path_t)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for no-op conversion path"); + } + HDstrcpy(H5T_g.path[0]->name, "no-op"); + H5T_g.path[0]->func = H5T_conv_noop; + H5T_g.path[0]->cdata.command = H5T_CONV_INIT; + if (H5T_conv_noop(FAIL, FAIL, &(H5T_g.path[0]->cdata), 0, + NULL, NULL)<0) { #ifdef H5T_DEBUG if (H5DEBUG(T)) { - fprintf(H5DEBUG(T), "H5T: conversion function free failed " - "for %s\n", path->name); + fprintf(H5DEBUG(T), "H5T: unable to initialize no-op " + "conversion function (ignored)\n"); } #endif - H5E_clear(); /*ignore the failure*/ + H5E_clear(); /*ignore the error*/ } + H5T_g.npaths = 1; + } -#ifdef H5T_DEBUG - /* - * Print statistics about the function we're removing because we - * won't get a chance to do it later. - */ - if (H5DEBUG(T) && path->cdata.stats->ncalls>0) { - HDfprintf(H5DEBUG(T), "H5T: conversion statistics accumulated " - "over life of function:\n"); - nbytes = MAX(H5T_get_size(path->src), H5T_get_size(path->dst)); - nbytes *= path->cdata.stats->nelmts; - H5_bandwidth(bandwidth, (double)nbytes, - path->cdata.stats->timer.etime); - HDfprintf(H5DEBUG(T), - " %-16s %10Hd %10d %8.2f %8.2f %8.2f %10s\n", - path->name, - path->cdata.stats->nelmts, - path->cdata.stats->ncalls, - path->cdata.stats->timer.utime, - path->cdata.stats->timer.stime, - path->cdata.stats->timer.etime, - bandwidth); + /* + * Find the conversion path. If source and destination types are equal + * then use entry[0], otherwise do a binary search over the + * remaining entries. + */ + if (0==H5T_cmp(src, dst)) { + table = H5T_g.path[0]; + cmp = 0; + md = 0; + } else { + lt = md = 1; + rt = H5T_g.npaths; + cmp = -1; + + while (cmp && lt<rt) { + md = (lt+rt) / 2; + assert(H5T_g.path[md]); + cmp = H5T_cmp(src, H5T_g.path[md]->src); + if (0==cmp) cmp = H5T_cmp(dst, H5T_g.path[md]->dst); + if (cmp<0) { + rt = md; + } else if (cmp>0) { + lt = md+1; + } else { + table = H5T_g.path[md]; + } } -#endif - - /* Clear the path */ - path->name[0] = '\0'; - path->func = NULL; - path->is_hard = FALSE; - path->cdata.stats = H5MM_xfree(path->cdata.stats); } - /* If a hard function is specified then add it to the path */ + /* + * If we didn't find the path or if the caller is specifying a new hard + * conversion function then create a new path and add the new function to + * the path. + */ + if (!table || func) { + if (NULL==(path=H5MM_calloc(sizeof(H5T_path_t)))) { + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed for type conversion path"); + } + if (name && *name) { + strncpy(path->name, name, H5T_NAMELEN); + path->name[H5T_NAMELEN-1] = '\0'; + } else { + strcpy(path->name, "NONAME"); + } + if ((src && NULL==(path->src=H5T_copy(src, H5T_COPY_ALL))) || + (dst && NULL==(path->dst=H5T_copy(dst, H5T_COPY_ALL)))) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, + "unable to copy data type for conversion path"); + } + } else { + path = table; + } + + /* + * If a hard conversion function is specified and none is defined for the + * path then add it to the path and initialize its conversion data. + */ if (func) { - HDstrncpy(path->name, name && *name?name:"NONAME", H5T_NAMELEN); - path->name[H5T_NAMELEN-1] = '\0'; - path->func = func; - path->is_hard = TRUE; - path->cdata.command = H5T_CONV_INIT; - if (NULL==(path->cdata.stats=H5MM_calloc(sizeof(H5T_stats_t)))) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); + assert(path!=table); + assert(NULL==path->func); + if (path->src && (src_id=H5I_register(H5I_DATATYPE, + H5T_copy(path->src, + H5T_COPY_ALL)))<0) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, + "unable to register source conversion type for query"); } - if ((src_id=H5I_register(H5I_DATATYPE, - H5T_copy(path->src, H5T_COPY_ALL)))<0 || - (dst_id=H5I_register(H5I_DATATYPE, - H5T_copy(path->dst, H5T_COPY_ALL)))<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, - "unable to register conv types for query"); + if (path->dst && (dst_id=H5I_register(H5I_DATATYPE, + H5T_copy(path->dst, + H5T_COPY_ALL)))<0) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, + "unable to register destination conversion type for " + "query"); } + path->cdata.command = H5T_CONV_INIT; if ((func)(src_id, dst_id, &(path->cdata), 0, NULL, NULL)<0) { -#ifdef H5T_DEBUG - if (H5DEBUG(T)) { - fprintf (H5DEBUG(T), "H5T: conversion function init failed " - "for %s\n", path->name); - } -#endif - H5E_clear(); /*ignore the failure*/ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, + "unable to initialize conversion function"); } - H5I_dec_ref(src_id); - H5I_dec_ref(dst_id); + if (src_id>=0) H5I_dec_ref(src_id); + if (dst_id>=0) H5I_dec_ref(dst_id); + src_id = dst_id = -1; + path->func = func; + path->is_hard = TRUE; } - + /* * If the path doesn't have a function by now (because it's a new path * and the caller didn't supply a hard function) then scan the soft list - * for an applicable function and add it to the path. + * for an applicable function and add it to the path. This can't happen + * for the no-op conversion path. */ - for (i=H5T_nsoft_g-1; i>=0 && !path->func; --i) { - if (src->type!=H5T_soft_g[i].src || - dst->type!=H5T_soft_g[i].dst) { + assert(path->func || (src && dst)); + for (i=H5T_g.nsoft-1; i>=0 && !path->func; --i) { + if (src->type!=H5T_g.soft[i].src || + dst->type!=H5T_g.soft[i].dst) { continue; } if ((src_id=H5I_register(H5I_DATATYPE, H5T_copy(path->src, H5T_COPY_ALL)))<0 || (dst_id=H5I_register(H5I_DATATYPE, H5T_copy(path->dst, H5T_COPY_ALL)))<0) { - HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, - "unable to register conv types for query"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL, + "unable to register conversion types for query"); } path->cdata.command = H5T_CONV_INIT; - path->cdata.stats = H5MM_calloc (sizeof(H5T_stats_t)); - if (NULL==path->cdata.stats) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, - "memory allocation failed"); - } - if ((H5T_soft_g[i].func) (src_id, dst_id, &(path->cdata), - H5T_CONV_INIT, NULL, NULL)<0) { - H5MM_xfree(path->cdata.stats); + if ((H5T_g.soft[i].func) (src_id, dst_id, &(path->cdata), + 0, NULL, NULL)<0) { HDmemset (&(path->cdata), 0, sizeof(H5T_cdata_t)); H5E_clear(); /*ignore the error*/ } else { - HDstrcpy (path->name, H5T_soft_g[i].name); - path->func = H5T_soft_g[i].func; + HDstrcpy (path->name, H5T_g.soft[i].name); + path->func = H5T_g.soft[i].func; + path->is_hard = FALSE; } H5I_dec_ref(src_id); H5I_dec_ref(dst_id); + src_id = dst_id = -1; + } + if (!path->func) { + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, + "no appropriate function for conversion path"); } - FUNC_LEAVE(path); + /* Replace an existing table entry or add a new entry */ + if (table && path!=table) { + assert(table==H5T_g.path[md]); + H5T_print_stats(table, &nprint/*in,out*/); + table->cdata.command = H5T_CONV_FREE; + if ((table->func)(FAIL, FAIL, &(table->cdata), 0, NULL, NULL)<0) { +#ifdef H5T_DEBUG + if (H5DEBUG(T)) { + fprintf(H5DEBUG(T), "H5T: conversion function 0x%08lx free " + "failed for %s (ignored)\n", + (unsigned long)(path->func), path->name); + } +#endif + H5E_clear(); /*ignore the failure*/ + } + if (table->src) H5T_close(table->src); + if (table->dst) H5T_close(table->dst); + H5MM_xfree(table); + table = path; + H5T_g.path[md] = path; + } else if (path!=table) { + assert(cmp); + if (H5T_g.npaths >= H5T_g.apaths) { + size_t na = MAX(128, 2 * H5T_g.apaths); + H5T_path_t **x = H5MM_realloc (H5T_g.path, + na*sizeof(H5T_path_t*)); + if (!x) { + HGOTO_ERROR (H5E_RESOURCE, H5E_NOSPACE, NULL, + "memory allocation failed"); + } + H5T_g.apaths = (intn)na; + H5T_g.path = x; + } + if (cmp>0) md++; + HDmemmove(H5T_g.path+md+1, H5T_g.path+md, + (H5T_g.npaths-md) * sizeof(H5T_path_t*)); + H5T_g.npaths++; + H5T_g.path[md] = path; + table = path; + } + ret_value = path; + + done: + if (!ret_value && path && path!=table) { + if (path->src) H5T_close(path->src); + if (path->dst) H5T_close(path->dst); + H5MM_xfree(path); + } + if (src_id>=0) H5I_dec_ref(src_id); + if (dst_id>=0) H5I_dec_ref(dst_id); + + FUNC_LEAVE(ret_value); +} + + +/*------------------------------------------------------------------------- + * Function: H5T_convert + * + * Purpose: Call a conversion function to convert from source to + * destination data type and accumulate timing statistics. + * + * Return: Success: non-negative + * + * Failure: negative + * + * Programmer: Robb Matzke + * Tuesday, December 15, 1998 + * + * Modifications: + * + *------------------------------------------------------------------------- + */ +herr_t +H5T_convert(H5T_path_t *tpath, hid_t src_id, hid_t dst_id, size_t nelmts, + void *buf, void *bkg) +{ +#ifdef H5T_DEBUG + H5_timer_t timer; +#endif + + FUNC_ENTER(H5T_convert, FAIL); + +#ifdef H5T_DEBUG + H5_timer_begin(&timer); +#endif + tpath->cdata.command = H5T_CONV_CONV; + if ((tpath->func)(src_id, dst_id, &(tpath->cdata), nelmts, buf, bkg)<0) { + HRETURN_ERROR(H5E_ATTR, H5E_CANTENCODE, FAIL, + "data type conversion failed"); + } +#ifdef H5T_DEBUG + H5_timer_end(&(tpath->stats.timer), &timer); + tpath->stats.ncalls++; + tpath->stats.nelmts += nelmts; +#endif + + FUNC_LEAVE(SUCCEED); } @@ -5222,60 +4962,70 @@ H5T_entof (H5T_t *dt) /*------------------------------------------------------------------------- - * Function: H5T_timer_begin + * Function: H5T_print_stats * - * Purpose: Start a timer for a data type conversion. + * Purpose: Print statistics about a conversion path. Statistics are + * printed only if all the following conditions are true: * - * Return: void + * 1. The library was compiled with H5T_DEBUG defined. + * 2. Data type debugging is turned on at run time. + * 3. The path was called at least one time. * - * Programmer: Robb Matzke - * Friday, April 17, 1998 + * The optional NPRINT argument keeps track of the number of + * conversions paths for which statistics have been shown. If + * its value is zero then table headers are printed before the + * first line of output. * - * Modifications: + * Return: Success: non-negative * - *------------------------------------------------------------------------- - */ -void -H5T_timer_begin (H5_timer_t __unused__ *timer, H5T_cdata_t __unused__ *cdata) -{ -#ifdef H5T_DEBUG - assert (timer); - assert (cdata); - assert (cdata->stats); - H5_timer_begin (timer); -#endif -} - - -/*------------------------------------------------------------------------- - * Function: H5T_timer_end - * - * Purpose: Ends a timer for a data type conversion - * - * Return: void + * Failure: negative * * Programmer: Robb Matzke - * Friday, April 17, 1998 + * Monday, December 14, 1998 * * Modifications: * *------------------------------------------------------------------------- */ -void -H5T_timer_end (H5_timer_t __unused__ *timer, H5T_cdata_t __unused__ *cdata, - size_t __unused__ nelmts) +static herr_t +H5T_print_stats(H5T_path_t __unused__ *path, intn *nprint/*in,out*/) { #ifdef H5T_DEBUG - assert (timer); - assert (cdata); - assert (cdata->stats); - H5_timer_end (&(cdata->stats->timer), timer); - cdata->stats->ncalls++; - cdata->stats->nelmts += nelmts; + hsize_t nbytes; + char bandwidth[32]; +#endif + + FUNC_ENTER(H5T_print_stats, FAIL); + +#ifdef H5T_DEBUG + if (H5DEBUG(T) && path->stats.ncalls>0) { + if (nprint && 0==(*nprint)++) { + HDfprintf (H5DEBUG(T), "H5T: type conversion statistics:\n"); + HDfprintf (H5DEBUG(T), " %-16s %10s %10s %8s %8s %8s %10s\n", + "Conversion", "Elmts", "Calls", "User", + "System", "Elapsed", "Bandwidth"); + HDfprintf (H5DEBUG(T), " %-16s %10s %10s %8s %8s %8s %10s\n", + "----------", "-----", "-----", "----", + "------", "-------", "---------"); + } + nbytes = MAX (H5T_get_size (path->src), + H5T_get_size (path->dst)); + nbytes *= path->stats.nelmts; + H5_bandwidth(bandwidth, (double)nbytes, + path->stats.timer.etime); + HDfprintf (H5DEBUG(T), " %-16s %10Hd %10d %8.2f %8.2f %8.2f %10s\n", + path->name, + path->stats.nelmts, + path->stats.ncalls, + path->stats.timer.utime, + path->stats.timer.stime, + path->stats.timer.etime, + bandwidth); + } #endif + FUNC_LEAVE(SUCCEED); } - /*------------------------------------------------------------------------- * Function: H5T_debug * diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 05187b9..2ba0e32 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -17,14 +17,19 @@ /* Conversion data for H5T_conv_struct() */ typedef struct H5T_conv_struct_t { - intn *src2dst; /*mapping from src to dst memb ID */ + intn *src2dst; /*mapping from src to dst member num */ hid_t *src_memb_id; /*source member type ID's */ hid_t *dst_memb_id; /*destination member type ID's */ - H5T_conv_t *memb_conv; /*array of membr conversion functions*/ - H5T_cdata_t **memb_cdata; /*array of member cdata pointers */ + H5T_path_t **memb_path; /*conversion path for each member */ size_t *memb_nelmts; /*member element count */ } H5T_conv_struct_t; +/* Conversion data for the hardware conversion functions */ +typedef struct H5T_conv_hw_t { + hsize_t s_aligned; /*number source elements aligned */ + hsize_t d_aligned; /*number destination elements aligned*/ +} H5T_conv_hw_t; + /* Interface initialization */ static intn interface_initialize_g = 0; #define INTERFACE_INIT NULL @@ -253,33 +258,47 @@ static intn interface_initialize_g = 0; size_t elmtno; /*element number */ \ ST *src, *s; /*source buffer */ \ DT *dst, *d; /*destination buffer */ \ - H5T_t *st, *dt; /*src and dest data types */ \ + H5T_t *st, *dt; /*data type descriptors */ \ long_long aligned; /*largest integer type, aligned */ \ hbool_t s_mv, d_mv; /*move data to align it? */ \ + size_t dt_size=sizeof(DT); /*needed by CI_END macro */ \ + H5T_conv_hw_t *priv = cdata->priv; /*private data */ \ \ switch (cdata->command) { \ case H5T_CONV_INIT: \ cdata->need_bkg = H5T_BKG_NO; \ + if (NULL==(st=H5I_object(src_id)) || \ + NULL==(dt=H5I_object(dst_id))) { \ + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \ + "unable to dereference data type object ID"); \ + } \ + if (st->size!=sizeof(ST) || dt->size!=sizeof(DT)) { \ + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \ + "disagreement about data type size"); \ + } \ + if (NULL==(cdata->priv=H5MM_calloc(sizeof(H5T_conv_hw_t)))) { \ + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, \ + "memory allocation failed"); \ + } \ break; \ case H5T_CONV_FREE: \ + CI_PRINT_STATS(STYPE,DTYPE); \ + cdata->priv = H5MM_xfree(cdata->priv); \ break; \ case H5T_CONV_CONV: \ src = (ST*)buf+(STRT); \ dst = (DT*)buf+(STRT); \ - st = H5I_object(src_id); \ - dt = H5I_object(dst_id); \ - assert(st && dt); \ s_mv = H5T_NATIVE_##STYPE##_ALIGN_g>1 && \ ((size_t)buf%H5T_NATIVE_##STYPE##_ALIGN_g || \ - st->size%H5T_NATIVE_##STYPE##_ALIGN_g); \ + sizeof(ST)%H5T_NATIVE_##STYPE##_ALIGN_g); \ d_mv = H5T_NATIVE_##DTYPE##_ALIGN_g>1 && \ ((size_t)buf%H5T_NATIVE_##DTYPE##_ALIGN_g || \ - dt->size%H5T_NATIVE_##DTYPE##_ALIGN_g); \ - CI_DEBUG(s_mv, STYPE, ST); \ - CI_DEBUG(d_mv, DTYPE, DT); \ + sizeof(DT)%H5T_NATIVE_##DTYPE##_ALIGN_g); \ + if (s_mv) priv->s_aligned += nelmts; \ + if (d_mv) priv->d_aligned += nelmts; \ for (elmtno=0; elmtno<nelmts; elmtno++, DIR src, DIR dst) { \ if (s_mv) { \ - memcpy(&aligned, src, st->size); \ + memcpy(&aligned, src, sizeof(ST)); \ s = (ST*)&aligned; \ } else { \ s = src; \ @@ -291,7 +310,7 @@ static intn interface_initialize_g = 0; } /* ... user-defined stuff here ... */ #define CI_END \ - if (d_mv) memcpy(dst, &aligned, dt->size); \ + if (d_mv) memcpy(dst, &aligned, dt_size); \ } \ break; \ default: \ @@ -300,16 +319,24 @@ static intn interface_initialize_g = 0; } \ } -/* Print alignment information */ +/* Print alignment statistics */ #ifdef H5T_DEBUG -# define CI_DEBUG(MV,HDF_TYPE,C_TYPE) { \ - if (MV && H5DEBUG(T)) { \ - fprintf(H5DEBUG(T), "<%d-byte alignment for %s>", \ - H5T_NATIVE_##HDF_TYPE##_ALIGN_g, #C_TYPE); \ +# define CI_PRINT_STATS(STYPE,DTYPE) { \ + if (H5DEBUG(T) && priv->s_aligned) { \ + HDfprintf(H5DEBUG(T), \ + " %Hu src elements aligned on %lu-byte boundaries\n", \ + priv->s_aligned, \ + (unsigned long)H5T_NATIVE_##STYPE##_ALIGN_g); \ + } \ + if (H5DEBUG(T) && priv->d_aligned) { \ + HDfprintf(H5DEBUG(T), \ + " %Hu dst elements aligned on %lu-byte boundaries\n", \ + priv->d_aligned, \ + (unsigned long)H5T_NATIVE_##DTYPE##_ALIGN_g); \ } \ } #else -# define CI_DEBUG(MV,HDF_TYPE,C_TYPE) /*void*/ +# define CI_PRINT_STATS /*void*/ #endif /*------------------------------------------------------------------------- @@ -344,7 +371,6 @@ H5T_conv_noop(hid_t __unused__ src_id, hid_t __unused__ dst_id, break; case H5T_CONV_FREE: - cdata->stats = H5MM_xfree (cdata->stats); break; default: @@ -467,6 +493,16 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * already initialized then the member conversion functions * are recalculated. * + * Priv fields are indexed by source member number or + * destination member number depending on whether the field + * contains information about the source data type or the + * destination data type (fields that contains the same + * information for both source and destination are indexed by + * source member number). The src2dst[] priv array maps source + * member numbers to destination member numbers, but if the + * source member doesn't have a corresponding destination member + * then the src2dst[i]=-1. + * * Return: Non-negative on success/Negative on failure * * Programmer: Robb Matzke @@ -488,26 +524,21 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) if (!priv) { /* - * Notice: the thing marked with `!' below really is `dst' and not - * `src' because we're only interested in the members of the - * source type that are also in the destination type. + * Allocate private data structure and arrays. */ - cdata->priv = priv = H5MM_calloc (sizeof(H5T_conv_struct_t)); - if (NULL==priv) { - HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, - "memory allocation failed"); - } - priv->src2dst = H5MM_malloc (src->u.compnd.nmembs * sizeof(intn)); - priv->src_memb_id = H5MM_malloc (/*!*/dst->u.compnd.nmembs * - sizeof(hid_t)); - priv->dst_memb_id = H5MM_malloc (dst->u.compnd.nmembs * - sizeof(hid_t)); - if (NULL==priv->src2dst || - NULL==priv->src_memb_id || - NULL==priv->dst_memb_id) { + if (NULL==(priv=cdata->priv=H5MM_calloc(sizeof(H5T_conv_struct_t))) || + NULL==(priv->src2dst=H5MM_malloc(src->u.compnd.nmembs * + sizeof(intn))) || + NULL==(priv->src_memb_id=H5MM_malloc(src->u.compnd.nmembs * + sizeof(hid_t))) || + NULL==(priv->dst_memb_id=H5MM_malloc(dst->u.compnd.nmembs * + sizeof(hid_t))) || + NULL==(priv->memb_nelmts=H5MM_malloc(src->u.compnd.nmembs * + sizeof(size_t)))) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } + src2dst = priv->src2dst; /* * Insure that members are sorted. @@ -523,25 +554,25 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) * member data type conversion functions later. */ for (i=0; i<src->u.compnd.nmembs; i++) { - priv->src2dst[i] = -1; + src2dst[i] = -1; for (j=0; j<dst->u.compnd.nmembs; j++) { if (!HDstrcmp (src->u.compnd.memb[i].name, - dst->u.compnd.memb[j].name)) { - priv->src2dst[i] = j; + dst->u.compnd.memb[j].name)) { + src2dst[i] = j; break; } } - if (priv->src2dst[i]>=0) { + if (src2dst[i]>=0) { type = H5T_copy (src->u.compnd.memb[i].type, H5T_COPY_ALL); tid = H5I_register (H5I_DATATYPE, type); assert (tid>=0); - priv->src_memb_id[priv->src2dst[i]] = tid; + priv->src_memb_id[i] = tid; - type = H5T_copy (dst->u.compnd.memb[priv->src2dst[i]].type, + type = H5T_copy (dst->u.compnd.memb[src2dst[i]].type, H5T_COPY_ALL); tid = H5I_register (H5I_DATATYPE, type); assert (tid>=0); - priv->dst_memb_id[priv->src2dst[i]] = tid; + priv->dst_memb_id[src2dst[i]] = tid; } } @@ -550,9 +581,9 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) * the same size and shape arrays. */ for (i=0; i<src->u.compnd.nmembs; i++) { - if (priv->src2dst[i]>=0) { + if (src2dst[i]>=0) { H5T_member_t *src_memb = src->u.compnd.memb + i; - H5T_member_t *dst_memb = dst->u.compnd.memb + priv->src2dst[i]; + H5T_member_t *dst_memb = dst->u.compnd.memb + src2dst[i]; if (src_memb->ndims != dst_memb->ndims) { HRETURN_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "source and dest members have incompatible " @@ -576,7 +607,6 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) } /* Calculate number of elements of each member */ - priv->memb_nelmts = H5MM_malloc(src->u.compnd.nmembs*sizeof(size_t)); for (i=0; i<src->u.compnd.nmembs; i++) { priv->memb_nelmts[i] = 1; for (j=0; j<src->u.compnd.memb[i].ndims; j++) { @@ -589,34 +619,30 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) * (Re)build the cache of member conversion functions and pointers to * their cdata entries. */ - priv->memb_conv = H5MM_xfree (priv->memb_conv); - priv->memb_cdata = H5MM_xfree (priv->memb_cdata); - priv->memb_conv = H5MM_malloc (dst->u.compnd.nmembs * - sizeof(H5T_conv_t)); - priv->memb_cdata = H5MM_calloc (dst->u.compnd.nmembs * - sizeof(H5T_cdata_t*)); - if (NULL==priv->memb_conv || NULL==priv->memb_cdata) { + src2dst = priv->src2dst; + H5MM_xfree(priv->memb_path); + if (NULL==(priv->memb_path=H5MM_malloc(src->u.compnd.nmembs * + sizeof(H5T_path_t*)))) { HRETURN_ERROR (H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); } - src2dst = priv->src2dst; for (i=0; i<src->u.compnd.nmembs; i++) { - if (priv->src2dst[i]>=0) { - H5T_conv_t tconv_func; - tconv_func = H5T_find(src->u.compnd.memb[i].type, + if (src2dst[i]>=0) { + H5T_path_t *tpath; + tpath = H5T_path_find(src->u.compnd.memb[i].type, dst->u.compnd.memb[src2dst[i]].type, - H5T_BKG_NO, priv->memb_cdata+src2dst[i]); - if (!tconv_func) { - H5MM_xfree (priv->src2dst); - H5MM_xfree (priv->src_memb_id); - H5MM_xfree (priv->dst_memb_id); - H5MM_xfree (priv->memb_conv); + NULL, NULL); + if (NULL==(priv->memb_path[i] = tpath)) { + H5MM_xfree(priv->src2dst); + H5MM_xfree(priv->src_memb_id); + H5MM_xfree(priv->dst_memb_id); + H5MM_xfree(priv->memb_path); + H5MM_xfree(priv->memb_nelmts); cdata->priv = priv = H5MM_xfree (priv); HRETURN_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member data type"); } - priv->memb_conv[src2dst[i]] = tconv_func; } } @@ -701,8 +727,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, H5MM_xfree(priv->src2dst); H5MM_xfree(priv->src_memb_id); H5MM_xfree(priv->dst_memb_id); - H5MM_xfree(priv->memb_conv); - H5MM_xfree(priv->memb_cdata); + H5MM_xfree(priv->memb_path); H5MM_xfree(priv->memb_nelmts); cdata->priv = priv = H5MM_xfree (priv); break; @@ -761,20 +786,21 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, dst_memb = dst->u.compnd.memb + src2dst[i]; if (dst_memb->size <= src_memb->size) { - H5T_conv_t tconv_func = priv->memb_conv[src2dst[i]]; - H5T_cdata_t *memb_cdata = priv->memb_cdata[src2dst[i]]; - memb_cdata->command = H5T_CONV_CONV; - (tconv_func)(priv->src_memb_id[src2dst[i]], - priv->dst_memb_id[src2dst[i]], - memb_cdata, priv->memb_nelmts[i], - buf + src_memb->offset, - bkg + dst_memb->offset); - - HDmemmove (buf + offset, buf + src_memb->offset, + if (H5T_convert(priv->memb_path[i], + priv->src_memb_id[i], + priv->dst_memb_id[src2dst[i]], + priv->memb_nelmts[i], + buf + src_memb->offset, + bkg + dst_memb->offset)<0) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to convert compound data type " + "member"); + } + HDmemmove (buf+offset, buf+src_memb->offset, dst_memb->size); offset += dst_memb->size; } else { - HDmemmove (buf + offset, buf + src_memb->offset, + HDmemmove (buf+offset, buf+src_memb->offset, src_memb->size); offset += src_memb->size; } @@ -793,14 +819,16 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, dst_memb = dst->u.compnd.memb + src2dst[i]; if (dst_memb->size > src_memb->size) { - H5T_conv_t tconv_func = priv->memb_conv[src2dst[i]]; - H5T_cdata_t *memb_cdata = priv->memb_cdata[src2dst[i]]; offset -= src_memb->size; - memb_cdata->command = H5T_CONV_CONV; - (tconv_func)(priv->src_memb_id[src2dst[i]], - priv->dst_memb_id[src2dst[i]], - memb_cdata, priv->memb_nelmts[i], - buf+offset, bkg+dst_memb->offset); + if (H5T_convert(priv->memb_path[i], + priv->src_memb_id[i], + priv->dst_memb_id[src2dst[i]], + priv->memb_nelmts[i], + buf+offset, bkg+dst_memb->offset)<0) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to convert compound data type " + "member"); + } } else { offset -= dst_memb->size; } @@ -4327,44 +4355,57 @@ H5T_conv_float_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, H5T_t *st, *dt; /*type descriptors */ hbool_t src_mv, dst_mv; /*align data? */ double aligned; /*aligned data */ + H5T_conv_hw_t *priv = cdata->priv; /*private data */ FUNC_ENTER (H5T_conv_float_double, FAIL); switch (cdata->command) { case H5T_CONV_INIT: cdata->need_bkg = H5T_BKG_NO; + if (NULL==(st=H5I_object(src_id)) || + NULL==(dt=H5I_object(dst_id))) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to dereference data type object ID"); + } + if (st->size!=sizeof(float) || dt->size!=sizeof(double)) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "disagreement about data type size"); + } + if (NULL==(cdata->priv=H5MM_calloc(sizeof(H5T_conv_hw_t)))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); + } break; case H5T_CONV_FREE: + CI_PRINT_STATS(FLOAT, DOUBLE); + cdata->priv = H5MM_xfree(cdata->priv); break; case H5T_CONV_CONV: src = (float*)buf + nelmts-1; dst = (double*)buf + nelmts-1; - st = H5I_object(src_id); - dt = H5I_object(dst_id); - assert(st && dt); /* Need alignment? */ if (H5T_NATIVE_FLOAT_ALIGN_g>1) { src_mv = ((size_t)buf % H5T_NATIVE_FLOAT_ALIGN_g) || - (st->size % H5T_NATIVE_FLOAT_ALIGN_g); + (sizeof(float) % H5T_NATIVE_FLOAT_ALIGN_g); } else { src_mv = FALSE; } if (H5T_NATIVE_DOUBLE_ALIGN_g>1) { dst_mv = ((size_t)buf % H5T_NATIVE_DOUBLE_ALIGN_g) || - (dt->size % H5T_NATIVE_DOUBLE_ALIGN_g); + (sizeof(double) % H5T_NATIVE_DOUBLE_ALIGN_g); } else { dst_mv = FALSE; } - CI_DEBUG(src_mv, FLOAT, float); - CI_DEBUG(dst_mv, DOUBLE, double); + if (src_mv) priv->s_aligned += nelmts; + if (dst_mv) priv->d_aligned += nelmts; for (elmtno=0; elmtno<nelmts; elmtno++, --src, --dst) { /* Align source and/or destination */ if (src_mv) { - memcpy(&aligned, src, st->size); + memcpy(&aligned, src, sizeof(float)); s = (float*)&aligned; } else { s = src; @@ -4376,7 +4417,7 @@ H5T_conv_float_double (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, *d = *s; /* Unalign destination */ - if (dst_mv) memcpy(dst, &aligned, dt->size); + if (dst_mv) memcpy(dst, &aligned, sizeof(double)); } break; @@ -4417,44 +4458,57 @@ H5T_conv_double_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, H5T_t *st, *dt; /*type descriptors */ hbool_t src_mv, dst_mv; /*align data? */ double aligned; /*aligned data */ + H5T_conv_hw_t *priv = cdata->priv; /*private data */ FUNC_ENTER (H5T_conv_double_float, FAIL); switch (cdata->command) { case H5T_CONV_INIT: cdata->need_bkg = H5T_BKG_NO; + if (NULL==(st=H5I_object(src_id)) || + NULL==(dt=H5I_object(dst_id))) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "unable to dereference data type object ID"); + } + if (st->size!=sizeof(double) || dt->size!=sizeof(float)) { + HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, + "disagreement about data type size"); + } + if (NULL==(cdata->priv=H5MM_calloc(sizeof(H5T_conv_hw_t)))) { + HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, + "memory allocation failed"); + } break; case H5T_CONV_FREE: + CI_PRINT_STATS(DOUBLE, FLOAT); + cdata->priv = H5MM_xfree(cdata->priv); break; case H5T_CONV_CONV: src = (double*)buf; dst = (float*)buf; - st = H5I_object(src_id); - dt = H5I_object(dst_id); - assert(st && dt); /* Need alignment? */ if (H5T_NATIVE_DOUBLE_ALIGN_g>1) { src_mv = ((size_t)buf % H5T_NATIVE_DOUBLE_ALIGN_g) || - (st->size % H5T_NATIVE_DOUBLE_ALIGN_g); + (sizeof(double) % H5T_NATIVE_DOUBLE_ALIGN_g); } else { src_mv = FALSE; } if (H5T_NATIVE_FLOAT_ALIGN_g>1) { dst_mv = ((size_t)buf % H5T_NATIVE_FLOAT_ALIGN_g) || - (dt->size % H5T_NATIVE_FLOAT_ALIGN_g); + (sizeof(float) % H5T_NATIVE_FLOAT_ALIGN_g); } else { dst_mv = FALSE; } - CI_DEBUG(src_mv, DOUBLE, double); - CI_DEBUG(dst_mv, FLOAT, float); + if (src_mv) priv->s_aligned += nelmts; + if (dst_mv) priv->d_aligned += nelmts; for (elmtno=0; elmtno<nelmts; elmtno++, src++, dst++) { /* Align source and/or destination */ if (src_mv) { - memcpy(&aligned, src, st->size); + memcpy(&aligned, src, sizeof(double)); s = (double*)&aligned; } else { s = src; @@ -4478,7 +4532,7 @@ H5T_conv_double_float (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, } /* Unalign destination */ - if (dst_mv) memcpy(dst, &aligned, dt->size); + if (dst_mv) memcpy(dst, &aligned, sizeof(float)); } break; diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h index d31e6ff..a390897 100644 --- a/src/H5Tpkg.h +++ b/src/H5Tpkg.h @@ -28,8 +28,6 @@ #include <H5Rpublic.h> /* Publicly accessible reference information needed also */ #include <H5Tprivate.h> -#define H5T_NAMELEN 10 /*length of debugging name buffer */ - typedef struct H5T_atomic_t { H5T_order_t order; /*byte order */ size_t prec; /*precision in bits */ @@ -99,16 +97,6 @@ typedef struct H5T_member_t { struct H5T_t *type; /*type of this member */ } H5T_member_t; -/* The data type conversion database */ -typedef struct H5T_path_t { - char name[H5T_NAMELEN]; /*name for debugging only */ - H5T_t *src; /*source data type ID */ - H5T_t *dst; /*destination data type ID */ - H5T_conv_t func; /*data conversion function */ - hbool_t is_hard; /*is it a hard function? */ - H5T_cdata_t cdata; /*data for this function */ -} H5T_path_t; - /* The master list of soft conversion functions */ typedef struct H5T_soft_t { char name[H5T_NAMELEN]; /*name for debugging only */ @@ -126,10 +114,6 @@ typedef enum H5T_sdir_t { /* The overflow handler */ extern H5T_overflow_t H5T_overflow_g; -/* Function prototypes for H5T package scope */ -H5T_path_t *H5T_path_find (const char *name, const H5T_t *src, - const H5T_t *dst, hbool_t create, H5T_conv_t func); - /* * Alignment information for native types. A value of N indicates that the * data must be aligned on an address ADDR such that 0 == ADDR mod N. When @@ -151,6 +135,9 @@ extern size_t H5T_NATIVE_DOUBLE_ALIGN_g; extern size_t H5T_NATIVE_LDOUBLE_ALIGN_g; /* Conversion functions */ +herr_t H5T_conv_noop (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, + size_t nelmts, void *buf, void *bkg); + herr_t H5T_conv_order (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void *_buf, void *bkg); herr_t H5T_conv_struct (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h index 8cdc4f1..a78d303 100644 --- a/src/H5Tprivate.h +++ b/src/H5Tprivate.h @@ -22,17 +22,10 @@ #include <H5private.h> #include <H5Gprivate.h> /*for H5G_entry_t */ -#define H5T_RESERVED_ATOMS 8 -typedef struct H5T_t H5T_t; +#define H5T_RESERVED_ATOMS 8 +#define H5T_NAMELEN 32 /*length of debugging name buffer */ -/* Statistics about a conversion function */ -typedef struct H5T_stats_t { - uintn ncalls; /*num calls to conversion function */ -#ifdef H5T_DEBUG - hsize_t nelmts; /*total data points converted */ - H5_timer_t timer; /*total time for conversion */ -#endif -} H5T_stats_t; +typedef struct H5T_t H5T_t; /* How to copy a data type */ typedef enum H5T_copy_t { @@ -41,9 +34,35 @@ typedef enum H5T_copy_t { H5T_COPY_REOPEN } H5T_copy_t; +/* Statistics about a conversion function */ +typedef struct H5T_stats_t { + unsigned ncalls; /*num calls to conversion function */ + hsize_t nelmts; /*total data points converted */ + H5_timer_t timer; /*total time for conversion */ +} H5T_stats_t; + +/* The data type conversion database */ +typedef struct H5T_path_t { + char name[H5T_NAMELEN]; /*name for debugging only */ + H5T_t *src; /*source data type ID */ + H5T_t *dst; /*destination data type ID */ + H5T_conv_t func; /*data conversion function */ + hbool_t is_hard; /*is it a hard function? */ + H5T_stats_t stats; /*statistics for the conversion */ + H5T_cdata_t cdata; /*data for this function */ +} H5T_path_t; + +/* + * Is the path the special no-op path? The no-op function can be set by the + * application and there might be more than one no-op path in a + * multi-threaded application if one thread is using the no-op path when some + * other thread changes its definition. + */ +#define H5T_IS_NOOP(P) ((P)->is_hard && 0==H5T_cmp((P)->src, (P)->dst)) + /* Private functions */ herr_t H5T_native_open(void); -herr_t H5T_init_interface (void); +herr_t H5T_init(void); htri_t H5T_isa(H5G_entry_t *ent); H5T_t *H5T_open (H5G_entry_t *loc, const char *name); H5T_t *H5T_create (H5T_class_t type, size_t size); @@ -60,16 +79,10 @@ herr_t H5T_insert (H5T_t *parent, const char *name, size_t offset, herr_t H5T_sort_by_offset (H5T_t *dt); herr_t H5T_pack (H5T_t *dt); herr_t H5T_debug (H5T_t *dt, FILE * stream); -H5T_conv_t H5T_find (const H5T_t *src, const H5T_t *dst, H5T_bkg_t need_bkg, - H5T_cdata_t **pcdata/*out*/); H5G_entry_t *H5T_entof (H5T_t *dt); -void H5T_timer_begin (H5_timer_t *timer, H5T_cdata_t *cdata); -void H5T_timer_end (H5_timer_t *timer, H5T_cdata_t *cdata, size_t nelmts); +H5T_path_t *H5T_path_find (const H5T_t *src, const H5T_t *dst, + const char *name, H5T_conv_t func); +herr_t H5T_convert(H5T_path_t *tpath, hid_t src_id, hid_t dst_id, + size_t nelmts, void *buf, void *bkg); -/* - * This conversion function is here so we can determine whether a conversion - * is a no-op or not. The other conversion functions can go in H5Tpkg.h - */ -herr_t H5T_conv_noop (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, - size_t nelmts, void *buf, void *bkg); #endif diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h index e301d72..2f3048f 100644 --- a/src/H5Tpublic.h +++ b/src/H5Tpublic.h @@ -145,9 +145,15 @@ typedef struct H5T_cdata_t { H5T_bkg_t need_bkg;/*is the background buffer needed? */ hbool_t recalc; /*recalculate private data */ void *priv; /*private data */ - struct H5T_stats_t *stats; /*statistics for the conversion */ } H5T_cdata_t; +/* Conversion function persistence */ +typedef enum H5T_pers_t { + H5T_PERS_DONTCARE = -1, /*wild card */ + H5T_PERS_HARD = 0, /*hard conversion function */ + H5T_PERS_SOFT = 1 /*soft conversion function */ +} H5T_pers_t; + /* All data type conversion functions are... */ typedef herr_t (*H5T_conv_t) (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void *buf, void *bkg); @@ -433,11 +439,10 @@ herr_t H5Tset_cset (hid_t type_id, H5T_cset_t cset); herr_t H5Tset_strpad (hid_t type_id, H5T_str_t strpad); /* Type conversion database */ -herr_t H5Tregister_hard (const char *name, hid_t src_id, hid_t dst_id, - H5T_conv_t func); -herr_t H5Tregister_soft (const char *name, H5T_class_t src, H5T_class_t dst, - H5T_conv_t func); -herr_t H5Tunregister (H5T_conv_t func); +herr_t H5Tregister(H5T_pers_t pers, const char *name, hid_t src_id, + hid_t dst_id, H5T_conv_t func); +herr_t H5Tunregister (H5T_pers_t pers, const char *name, hid_t src_id, + hid_t dst_id, H5T_conv_t func); H5T_conv_t H5Tfind (hid_t src_id, hid_t dst_id, H5T_cdata_t **pcdata); herr_t H5Tconvert (hid_t src_id, hid_t dst_id, size_t nelmts, void *buf, void *background); diff --git a/src/H5detect.c b/src/H5detect.c index ae1ecb2..9220915 100644 --- a/src/H5detect.c +++ b/src/H5detect.c @@ -475,7 +475,7 @@ iprint(detected_t *d) } else if (1==d->align) { printf(" * Alignment: none\n"); } else { - printf(" * Alignemtn: %lu\n", (unsigned long)(d->align)); + printf(" * Alignment: %lu\n", (unsigned long)(d->align)); } } diff --git a/src/H5private.h b/src/H5private.h index e0b349e..1a4afd6 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -850,7 +850,7 @@ extern hbool_t library_initialize_g; /*good thing C's lazy about extern! */ \ /* Initialize this interface or bust */ \ if (!interface_initialize_g) { \ - interface_initialize_g = TRUE; \ + interface_initialize_g = 1; \ if (interface_init_func && \ ((herr_t(*)(void))interface_init_func)()<0) { \ HRETURN_ERROR (H5E_FUNC, H5E_CANTINIT, err, \ |