diff options
Diffstat (limited to 'src')
39 files changed, 2636 insertions, 1204 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3ba37c1..9279481 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -149,6 +149,7 @@ SET (H5F_SRCS ${HDF5_SRC_DIR}/H5Faccum.c ${HDF5_SRC_DIR}/H5Fdbg.c ${HDF5_SRC_DIR}/H5Fdeprec.c + ${HDF5_SRC_DIR}/H5Fefc.c ${HDF5_SRC_DIR}/H5Ffake.c ${HDF5_SRC_DIR}/H5Fio.c ${HDF5_SRC_DIR}/H5Fmount.c diff --git a/src/H5Ddeprec.c b/src/H5Ddeprec.c index b06bce1..b31f23b 100644 --- a/src/H5Ddeprec.c +++ b/src/H5Ddeprec.c @@ -366,7 +366,8 @@ H5D_extend(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id) HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL, "unable to initialize dataset with fill value") /* Mark the dataspace as dirty, for later writing to the file */ - dataset->shared->space_dirty = TRUE; + if(H5D_mark(dataset, dxpl_id, H5D_MARK_SPACE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to mark dataspace as dirty") } /* end if */ done: diff --git a/src/H5Dint.c b/src/H5Dint.c index 3120b86..e8dc976 100644 --- a/src/H5Dint.c +++ b/src/H5Dint.c @@ -1814,7 +1814,9 @@ H5D_alloc_storage(H5D_t *dset/*in,out*/, hid_t dxpl_id, H5D_time_alloc_t time_al * operation just sets the address and makes it constant) */ if(time_alloc != H5D_ALLOC_CREATE && addr_set) - dset->shared->layout_dirty = TRUE; + /* Mark the layout as dirty, for later writing to the file */ + if(H5D_mark(dset, dxpl_id, H5D_MARK_LAYOUT) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to mark dataspace as dirty") } /* end if */ done: @@ -2330,7 +2332,8 @@ H5D_set_extent(H5D_t *dset, const hsize_t *size, hid_t dxpl_id) } /* end if */ /* Mark the dataspace as dirty, for later writing to the file */ - dset->shared->space_dirty = TRUE; + if(H5D_mark(dset, dxpl_id, H5D_MARK_SPACE) < 0) + HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "unable to mark dataspace as dirty") } /* end if */ done: @@ -2451,6 +2454,41 @@ done: /*------------------------------------------------------------------------- + * Function: H5D_mark + * + * Purpose: Mark some aspect of a dataset as dirty + * + * Return: Success: Non-negative + * Failure: Negative + * + * Programmer: Quincey Koziol + * July 4, 2008 + * + *------------------------------------------------------------------------- + */ +herr_t +H5D_mark(H5D_t *dataset, hid_t dxpl_id, unsigned flags) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5D_mark) + + /* Check args */ + HDassert(dataset); + HDassert(!(flags & (unsigned)~(H5D_MARK_SPACE | H5D_MARK_LAYOUT))); + + /* Mark aspects of the dataset as dirty */ + if(flags & H5D_MARK_SPACE) + dataset->shared->space_dirty = TRUE; + if(flags & H5D_MARK_LAYOUT) + dataset->shared->layout_dirty = TRUE; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5D_mark() */ + + +/*------------------------------------------------------------------------- * Function: H5D_flush_cb * * Purpose: Flush any dataset information cached in memory diff --git a/src/H5Dpkg.h b/src/H5Dpkg.h index 5dc728f..daf8ca8 100644 --- a/src/H5Dpkg.h +++ b/src/H5Dpkg.h @@ -66,6 +66,10 @@ #define H5D_CHUNK_HASH(D, ADDR) H5F_addr_hash(ADDR, (D)->cache.chunk.nslots) +/* Flags for marking aspects of a dataset dirty */ +#define H5D_MARK_SPACE 0x01 +#define H5D_MARK_LAYOUT 0x02 + /* Default creation parameters for chunk index data structures */ /* See H5O_layout_chunk_t */ @@ -87,6 +91,7 @@ #define H5D_BT2_SPLIT_PERC 100 #define H5D_BT2_MERGE_PERC 40 + /****************************/ /* Package Private Typedefs */ /****************************/ @@ -599,6 +604,7 @@ H5_DLL herr_t H5D_check_filters(H5D_t *dataset); H5_DLL herr_t H5D_set_extent(H5D_t *dataset, const hsize_t *size, hid_t dxpl_id); H5_DLL herr_t H5D_get_dxpl_cache(hid_t dxpl_id, H5D_dxpl_cache_t **cache); H5_DLL herr_t H5D_flush_sieve_buf(H5D_t *dataset, hid_t dxpl_id); +H5_DLL herr_t H5D_mark(H5D_t *dataset, hid_t dxpl_id, unsigned flags); /* Functions that perform direct serial I/O operations */ H5_DLL herr_t H5D_select_read(const H5D_io_info_t *io_info, @@ -292,6 +292,7 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref) H5P_genplist_t *new_plist; /* New property list */ H5P_genplist_t *old_plist; /* Old property list */ void *driver_info=NULL; + unsigned efc_size = 0; hid_t ret_value = SUCCEED; FUNC_ENTER_NOAPI(H5F_get_access_plist, FAIL) @@ -330,6 +331,10 @@ H5F_get_access_plist(H5F_t *f, hbool_t app_ref) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'small data' cache size") if(H5P_set(new_plist, H5F_ACS_LATEST_FORMAT_NAME, &(f->shared->latest_format)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set 'latest format' flag") + if(f->shared->efc) + efc_size = H5F_efc_max_nfiles(f->shared->efc); + if(H5P_set(new_plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't set elink file cache size") /* * Since we're resetting the driver ID and info, close them if they @@ -840,6 +845,7 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) } /* end if */ else { H5P_genplist_t *plist; /* Property list */ + unsigned efc_size; /* External file cache size */ size_t u; /* Local index variable */ HDassert(lf != NULL); @@ -902,6 +908,11 @@ H5F_new(H5F_file_t *shared, hid_t fcpl_id, hid_t fapl_id, H5FD_t *lf) if(H5P_get(plist, H5F_ACS_SDATA_BLOCK_SIZE_NAME, &(f->shared->sdata_aggr.alloc_size)) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get 'small data' cache size") f->shared->sdata_aggr.feature_flag = H5FD_FEAT_AGGREGATE_SMALLDATA; + if(H5P_get(plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, NULL, "can't get elink file cache size") + if(efc_size > 0) + if(NULL == (f->shared->efc = H5F_efc_create(efc_size))) + HGOTO_ERROR(H5E_FILE, H5E_CANTINIT, NULL, "can't create external file cache") /* Get the VFD values to cache */ f->shared->maxaddr = H5FD_get_maxaddr(lf); @@ -998,6 +1009,13 @@ H5F_dest(H5F_t *f, hid_t dxpl_id, hbool_t flush) if(H5F_flush(f, dxpl_id) < 0) HDONE_ERROR(H5E_CACHE, H5E_CANTFLUSH, FAIL, "unable to flush cache") + /* Release the external file cache */ + if(f->shared->efc) { + if(H5F_efc_destroy(f->shared->efc) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't destroy external file cache") + f->shared->efc = NULL; + } /* end if */ + /* Release objects that depend on the superblock being initialized */ if(f->shared->sblock) { /* Shutdown file free space manager(s) */ @@ -1916,6 +1934,13 @@ H5F_try_close(H5F_t *f) if(H5F_close_mounts(f) < 0) HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't unmount child files") + /* If there is more than one reference to the shared file struct and the + * file has an external file cache, we should see if it can be closed. This + * can happen if a cycle is formed with external file caches */ + if(f->shared->efc && (f->shared->nrefs > 1)) + if(H5F_efc_try_close(f) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't attempt to close EFC") + /* Delay flush until the shared file struct is closed, in H5F_dest. If the * application called H5Fclose, it would have been flushed in that function * (unless it will have been flushed in H5F_dest anyways). */ @@ -2952,3 +2977,40 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Fget_free_sections() */ + +/*------------------------------------------------------------------------- + * Function: H5Frelease_file_cache + * + * Purpose: Releases the external file cache associated with the + * provided file, potentially closing any cached files + * unless they are held open from somewhere\ else. + * + * Return: Success: non-negative + * Failure: negative + * + * Programmer: Neil Fortner; December 30, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Frelease_file_cache(hid_t file_id) +{ + H5F_t *file; /* File */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_API(H5Frelease_file_cache, FAIL) + H5TRACE1("e", "i", file_id); + + /* Check args */ + if(NULL == (file = (H5F_t *)H5I_object_verify(file_id, H5I_FILE))) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "not a file ID") + + /* Release the EFC */ + if(file->shared->efc) + if(H5F_efc_release(file->shared->efc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Frelease_file_cache() */ + diff --git a/src/H5FDdirect.c b/src/H5FDdirect.c index c6868e0..214dd8d 100644 --- a/src/H5FDdirect.c +++ b/src/H5FDdirect.c @@ -123,7 +123,7 @@ typedef struct H5FD_direct_t { # define file_offset_t off64_t # define file_seek lseek64 # define file_truncate ftruncate64 -#elif defined (_WIN32) && !defined(__MWERKS__) +#elif defined (_WIN32) # /*MSVC*/ # define file_offset_t __int64 # define file_seek _lseeki64 diff --git a/src/H5FDlog.c b/src/H5FDlog.c index 373f064..565e935 100644 --- a/src/H5FDlog.c +++ b/src/H5FDlog.c @@ -35,27 +35,18 @@ #include "H5Fprivate.h" /* File access */ #include "H5FDprivate.h" /* File drivers */ #include "H5FDlog.h" /* Logging file driver */ +#include "H5FLprivate.h" /* Free Lists */ #include "H5Iprivate.h" /* IDs */ #include "H5MMprivate.h" /* Memory management */ #include "H5Pprivate.h" /* Property lists */ -#ifdef MAX -#undef MAX -#define MAX(X,Y) ((X)>(Y)?(X):(Y)) -#endif /* MAX */ - /* The driver identification number, initialized at runtime */ static hid_t H5FD_LOG_g = 0; -/* File operations */ -#define OP_UNKNOWN 0 -#define OP_READ 1 -#define OP_WRITE 2 - /* Driver-specific file access properties */ typedef struct H5FD_log_fapl_t { char *logfile; /* Allocated log file name */ - unsigned flags; /* Flags for logging behavior */ + unsigned long long flags; /* Flags for logging behavior */ size_t buf_size; /* Size of buffers for track flavor and number of times each byte is accessed */ } H5FD_log_fapl_t; @@ -88,20 +79,19 @@ typedef struct H5FD_log_t { haddr_t eoa; /*end of allocated region */ haddr_t eof; /*end of file; current file size*/ haddr_t pos; /*current file I/O position */ - int op; /*last operation */ - unsigned char *nread; /* Number of reads from a file location */ - unsigned char *nwrite; /* Number of write to a file location */ - unsigned char *flavor; /* Flavor of information written to file location */ - size_t iosize; /* Size of I/O information buffers */ - FILE *logfp; /* Log file pointer */ - H5FD_log_fapl_t fa; /*driver-specific file access properties*/ + H5FD_file_op_t op; /*last operation */ + char filename[H5FD_MAX_FILENAME_LEN]; /* Copy of file name from open operation */ #ifndef _WIN32 /* * On most systems the combination of device and i-node number uniquely * identify a file. */ dev_t device; /*file device number */ +#ifdef H5_VMS + ino_t inode[3]; /*file i-node number */ +#else ino_t inode; /*file i-node number */ +#endif /*H5_VMS*/ #else /* * On _WIN32 the low-order word of a unique identifier associated with the @@ -118,6 +108,25 @@ typedef struct H5FD_log_t { /* Information from file open flags, for SWMR access */ hbool_t swmr_read; /* Whether the file is open for SWMR read access */ + + /* Information from properties set by 'h5repart' tool */ + hbool_t fam_to_sec2; /* Whether to eliminate the family driver info + * and convert this file to a single file */ + + /* Fields for tracking I/O operations */ + unsigned char *nread; /* Number of reads from a file location */ + unsigned char *nwrite; /* Number of write to a file location */ + unsigned char *flavor; /* Flavor of information written to file location */ + unsigned long long total_read_ops; /* Total number of read operations */ + unsigned long long total_write_ops; /* Total number of write operations */ + unsigned long long total_seek_ops; /* Total number of seek operations */ + unsigned long long total_truncate_ops; /* Total number of truncate operations */ + double total_read_time; /* Total time spent in read operations */ + double total_write_time; /* Total time spent in write operations */ + double total_seek_time; /* Total time spent in seek operations */ + size_t iosize; /* Size of I/O information buffers */ + FILE *logfp; /* Log file pointer */ + H5FD_log_fapl_t fa; /* Driver-specific file access properties*/ } H5FD_log_t; @@ -126,34 +135,14 @@ typedef struct H5FD_log_t { * some macros here so we don't have to have conditional compilations later * throughout the code. * - * file_offset_t: The datatype for file offsets, the second argument of - * the lseek() or lseek64() call. + * HDoff_t: The datatype for file offsets, the second argument of + * the lseek() or lseek64() call. * - * file_seek: The function which adjusts the current file position, - * either lseek() or lseek64(). */ -/* adding for windows NT file system support. */ - -#ifdef H5_HAVE_LSEEK64 -# define file_offset_t off64_t -# define file_seek lseek64 -#elif defined (_WIN32) -# ifdef __MWERKS__ -# define file_offset_t off_t -# define file_seek lseek -# else /*MSVC*/ -# define file_offset_t __int64 -# define file_seek _lseeki64 -# endif -#else -# define file_offset_t off_t -# define file_seek lseek -#endif - /* * These macros check for overflow of various quantities. These macros - * assume that file_offset_t is signed and haddr_t and size_t are unsigned. + * assume that HDoff_t is signed and haddr_t and size_t are unsigned. * * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' * is too large to be represented by the second argument @@ -166,14 +155,13 @@ typedef struct H5FD_log_t { * which can be addressed entirely by the second * argument of the file seek function. */ -#define MAXADDR (((haddr_t)1<<(8*sizeof(file_offset_t)-1))-1) +#define MAXADDR (((haddr_t)1<<(8*sizeof(HDoff_t)-1))-1) #define ADDR_OVERFLOW(A) (HADDR_UNDEF==(A) || \ ((A) & ~(haddr_t)MAXADDR)) #define SIZE_OVERFLOW(Z) ((Z) & ~(hsize_t)MAXADDR) #define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ - sizeof(file_offset_t)<sizeof(size_t) || \ HADDR_UNDEF==(A)+(Z) || \ - (file_offset_t)((A)+(Z))<(file_offset_t)(A)) + (HDoff_t)((A)+(Z))<(HDoff_t)(A)) /* Prototypes */ static void *H5FD_log_fapl_get(H5FD_t *file); @@ -195,21 +183,6 @@ static herr_t H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, hadd size_t size, const void *buf); static herr_t H5FD_log_truncate(H5FD_t *_file, hid_t dxpl_id, hbool_t closing); -#ifdef OLD_WAY -/* - * The free list map which causes each request type to use no free lists - */ -#define H5FD_FLMAP_NOLIST { \ - H5FD_MEM_NOLIST, /*default*/ \ - H5FD_MEM_NOLIST, /*super*/ \ - H5FD_MEM_NOLIST, /*btree*/ \ - H5FD_MEM_NOLIST, /*draw*/ \ - H5FD_MEM_NOLIST, /*gheap*/ \ - H5FD_MEM_NOLIST, /*lheap*/ \ - H5FD_MEM_NOLIST /*ohdr*/ \ -} -#endif /* OLD_WAY */ - static const H5FD_class_t H5FD_log_g = { "log", /*name */ MAXADDR, /*maxaddr */ @@ -244,6 +217,9 @@ static const H5FD_class_t H5FD_log_g = { H5FD_FLMAP_SINGLE /*fl_map */ }; +/* Declare a free list to manage the H5FD_log_t struct */ +H5FL_DEFINE_STATIC(H5FD_log_t); + /*-------------------------------------------------------------------------- NAME @@ -274,32 +250,29 @@ H5FD_log_init_interface(void) * library. * * Return: Success: The driver ID for the log driver. - * * Failure: Negative. * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ hid_t H5FD_log_init(void) { - hid_t ret_value; /* Return value */ + hid_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5FD_log_init, FAIL) - if (H5I_VFL!=H5Iget_type(H5FD_LOG_g)) - H5FD_LOG_g = H5FD_register(&H5FD_log_g,sizeof(H5FD_class_t),FALSE); + if(H5I_VFL != H5I_get_type(H5FD_LOG_g)) + H5FD_LOG_g = H5FD_register(&H5FD_log_g, sizeof(H5FD_class_t), FALSE); /* Set return value */ - ret_value=H5FD_LOG_g; + ret_value = H5FD_LOG_g; done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_log_init() */ /*--------------------------------------------------------------------------- @@ -312,8 +285,6 @@ done: * Programmer: Quincey Koziol * Friday, Jan 30, 2004 * - * Modification: - * *--------------------------------------------------------------------------- */ void @@ -322,7 +293,7 @@ H5FD_log_term(void) FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_term) /* Reset VFL ID */ - H5FD_LOG_g=0; + H5FD_LOG_g = 0; FUNC_LEAVE_NOAPI_VOID } /* end H5FD_log_term() */ @@ -340,16 +311,10 @@ H5FD_log_term(void) * Programmer: Robb Matzke * Thursday, February 19, 1998 * - * Modifications: - * We copy the LOGFILE value into our own access properties. - * - * Raymond Lu, 2001-10-25 - * Changed the file access list to the new generic property list. - * *------------------------------------------------------------------------- */ herr_t -H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned flags, size_t buf_size) +H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned long long flags, size_t buf_size) { H5FD_log_fapl_t fa; /* File access property list information */ H5P_genplist_t *plist; /* Property list pointer */ @@ -358,7 +323,7 @@ H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned flags, size_t buf_s FUNC_ENTER_API(H5Pset_fapl_log, FAIL) H5TRACE4("e", "i*sIuz", fapl_id, logfile, flags, buf_size); - if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS))) + if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") fa.logfile = (char *)logfile; @@ -380,28 +345,24 @@ done: * * Return: Success: Ptr to new file access property list with all * members copied from the file struct. - * * Failure: NULL * * Programmer: Quincey Koziol * Thursday, April 20, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ static void * H5FD_log_fapl_get(H5FD_t *_file) { - H5FD_log_t *file = (H5FD_log_t*)_file; + H5FD_log_t *file = (H5FD_log_t *)_file; void *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_log_fapl_get, NULL) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_fapl_get) /* Set return value */ - ret_value= H5FD_log_fapl_copy(&(file->fa)); + ret_value = H5FD_log_fapl_copy(&(file->fa)); -done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5FD_log_fapl_get() */ @@ -426,7 +387,7 @@ H5FD_log_fapl_copy(const void *_old_fa) H5FD_log_fapl_t *new_fa = NULL; /* New FAPL info */ void *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_log_fapl_copy, NULL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_fapl_copy) HDassert(old_fa); @@ -502,22 +463,29 @@ H5FD_log_fapl_free(void *_fa) *------------------------------------------------------------------------- */ static H5FD_t * -H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, - haddr_t maxaddr) +H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { - int o_flags; - int fd = (-1); H5FD_log_t *file = NULL; - H5FD_log_fapl_t *fa; /* File access property list information */ + H5P_genplist_t *plist; /* Property list */ + H5FD_log_fapl_t *fa; /* File access property list information */ + int fd = (-1); /* File descriptor */ + int o_flags; /* Flags for open() call */ #ifdef _WIN32 HFILE filehandle; struct _BY_HANDLE_FILE_INFORMATION fileinfo; #endif - h5_stat_t sb; - H5P_genplist_t *plist; /* Property list */ - H5FD_t *ret_value; +#ifdef H5_HAVE_GETTIMEOFDAY + struct timeval timeval_start; + struct timeval open_timeval_diff; + struct timeval stat_timeval_diff; +#endif /* H5_HAVE_GETTIMEOFDAY */ + h5_stat_t sb; + H5FD_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_open) - FUNC_ENTER_NOAPI(H5FD_log_open, NULL) + /* Sanity check on file offsets */ + HDcompile_assert(sizeof(HDoff_t) >= sizeof(size_t)); /* Check arguments */ if(!name || !*name) @@ -536,22 +504,65 @@ H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, if(H5F_ACC_EXCL & flags) o_flags |= O_EXCL; - /* Open the file */ - if((fd = HDopen(name, o_flags, 0666)) < 0) - HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file") - if(HDfstat(fd, &sb) < 0) - HGOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file") - - /* Create the new file struct */ - if(NULL == (file = (H5FD_log_t *)H5MM_calloc(sizeof(H5FD_log_t)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct") - /* Get the driver specific information */ if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a file access property list") fa = (H5FD_log_fapl_t *)H5P_get_driver_info(plist); HDassert(fa); +#ifdef H5_HAVE_GETTIMEOFDAY + if(fa->flags & H5FD_LOG_TIME_OPEN) + HDgettimeofday(&timeval_start, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + /* Open the file */ + if((fd = HDopen(name, o_flags, 0666)) < 0) { + int myerrno = errno; + + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "unable to open file: name = '%s', errno = %d, error message = '%s', flags = %x, o_flags = %x", name, myerrno, HDstrerror(myerrno), flags, (unsigned)o_flags); + } /* end if */ +#ifdef H5_HAVE_GETTIMEOFDAY + if(fa->flags & H5FD_LOG_TIME_OPEN) { + struct timeval timeval_stop; + + HDgettimeofday(&timeval_stop, NULL); + + /* Calculate the elapsed gettimeofday time */ + open_timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + open_timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(open_timeval_diff.tv_usec < 0) { + open_timeval_diff.tv_usec += 1000000; + open_timeval_diff.tv_sec--; + } /* end if */ + } /* end if */ +#endif /* H5_HAVE_GETTIMEOFDAY */ + +#ifdef H5_HAVE_GETTIMEOFDAY + if(fa->flags & H5FD_LOG_TIME_STAT) + HDgettimeofday(&timeval_start, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + /* Get the file stats */ + if(HDfstat(fd, &sb) < 0) + HSYS_GOTO_ERROR(H5E_FILE, H5E_BADFILE, NULL, "unable to fstat file") +#ifdef H5_HAVE_GETTIMEOFDAY + if(fa->flags & H5FD_LOG_TIME_STAT) { + struct timeval timeval_stop; + + HDgettimeofday(&timeval_stop, NULL); + + /* Calculate the elapsed gettimeofday time */ + stat_timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + stat_timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(stat_timeval_diff.tv_usec < 0) { + stat_timeval_diff.tv_usec += 1000000; + stat_timeval_diff.tv_sec--; + } /* end if */ + } /* end if */ +#endif /* H5_HAVE_GETTIMEOFDAY */ + + /* Create the new file struct */ + if(NULL == (file = H5FL_CALLOC(H5FD_log_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "unable to allocate file struct") + file->fd = fd; H5_ASSIGN_OVERFLOW(file->eof, sb.st_size, h5_stat_size_t, haddr_t); file->pos = HADDR_UNDEF; @@ -561,16 +572,28 @@ H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, (void)GetFileInformationByHandle((HANDLE)filehandle, &fileinfo); file->fileindexhi = fileinfo.nFileIndexHigh; file->fileindexlo = fileinfo.nFileIndexLow; -#else +#else /* _WIN32 */ file->device = sb.st_dev; +#ifdef H5_VMS + file->inode[0] = sb.st_ino[0]; + file->inode[1] = sb.st_ino[1]; + file->inode[2] = sb.st_ino[2]; +#else file->inode = sb.st_ino; -#endif +#endif /*H5_VMS*/ + +#endif /* _WIN32 */ + + /* Retain a copy of the name used to open the file, for possible error reporting */ + HDstrncpy(file->filename, name, sizeof(file->filename)); + file->filename[sizeof(file->filename) - 1] = '\0'; /* Get the flags for logging */ file->fa.flags = fa->flags; /* Check if we are doing any logging at all */ if(file->fa.flags != 0) { + /* Allocate buffers for tracking file accesses and data "flavor" */ file->iosize = fa->buf_size; if(file->fa.flags & H5FD_LOG_FILE_READ) { file->nread = (unsigned char *)H5MM_calloc(file->iosize); @@ -584,16 +607,38 @@ H5FD_log_open(const char *name, unsigned flags, hid_t fapl_id, file->flavor = (unsigned char *)H5MM_calloc(file->iosize); HDassert(file->flavor); } /* end if */ + + /* Set the log file pointer */ if(fa->logfile) file->logfp = HDfopen(fa->logfile, "w"); else file->logfp = stderr; + +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_OPEN) + HDfprintf(file->logfp, "Open took: (%f s)\n", (double)open_timeval_diff.tv_sec + ((double)open_timeval_diff.tv_usec / (double)1000000.0)); + if(file->fa.flags & H5FD_LOG_TIME_STAT) + HDfprintf(file->logfp, "Stat took: (%f s)\n", (double)stat_timeval_diff.tv_sec + ((double)stat_timeval_diff.tv_usec / (double)1000000.0)); +#endif /* H5_HAVE_GETTIMEOFDAY */ + } /* end if */ /* Check for SWMR reader access */ if(flags & H5F_ACC_SWMR_READ) file->swmr_read = TRUE; + /* Check for non-default FAPL */ + if(H5P_FILE_ACCESS_DEFAULT != fapl_id) { + /* This step is for h5repart tool only. If user wants to change file driver from + * family to sec2 while using h5repart, this private property should be set so that + * in the later step, the library can ignore the family driver information saved + * in the superblock. + */ + if(H5P_exist_plist(plist, H5F_ACS_FAMILY_TO_SEC2_NAME) > 0) + if(H5P_get(plist, H5F_ACS_FAMILY_TO_SEC2_NAME, &file->fam_to_sec2) < 0) + HGOTO_ERROR(H5E_VFL, H5E_CANTGET, NULL, "can't get property of changing family to sec2") + } /* end if */ + /* Set return value */ ret_value = (H5FD_t*)file; @@ -601,7 +646,8 @@ done: if(NULL == ret_value) { if(fd >= 0) HDclose(fd); - file = (H5FD_log_t *)H5MM_xfree(file); + if(file) + file = H5FL_FREE(H5FD_log_t, file); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) @@ -624,24 +670,27 @@ done: static herr_t H5FD_log_close(H5FD_t *_file) { - H5FD_log_t *file = (H5FD_log_t*)_file; + H5FD_log_t *file = (H5FD_log_t *)_file; #ifdef H5_HAVE_GETTIMEOFDAY - struct timeval timeval_start,timeval_stop; - struct timeval timeval_diff; + struct timeval timeval_start, timeval_stop; #endif /* H5_HAVE_GETTIMEOFDAY */ - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_log_close, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_close) + + /* Sanity check */ + HDassert(file); #ifdef H5_HAVE_GETTIMEOFDAY if(file->fa.flags&H5FD_LOG_TIME_CLOSE) - HDgettimeofday(&timeval_start,NULL); + HDgettimeofday(&timeval_start, NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ + /* Close the underlying file */ if(HDclose(file->fd) < 0) - HGOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file") + HSYS_GOTO_ERROR(H5E_IO, H5E_CANTCLOSEFILE, FAIL, "unable to close file") #ifdef H5_HAVE_GETTIMEOFDAY if(file->fa.flags&H5FD_LOG_TIME_CLOSE) - HDgettimeofday(&timeval_stop,NULL); + HDgettimeofday(&timeval_stop, NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ /* Dump I/O information */ @@ -652,6 +701,8 @@ H5FD_log_close(H5FD_t *_file) #ifdef H5_HAVE_GETTIMEOFDAY if(file->fa.flags & H5FD_LOG_TIME_CLOSE) { + struct timeval timeval_diff; + /* Calculate the elapsed gettimeofday time */ timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; @@ -663,6 +714,24 @@ H5FD_log_close(H5FD_t *_file) } /* end if */ #endif /* H5_HAVE_GETTIMEOFDAY */ + /* Dump the total number of seek/read/write operations */ + if(file->fa.flags & H5FD_LOG_NUM_READ) + HDfprintf(file->logfp, "Total number of read operations: %llu\n", file->total_read_ops); + if(file->fa.flags & H5FD_LOG_NUM_WRITE) + HDfprintf(file->logfp, "Total number of write operations: %llu\n", file->total_write_ops); + if(file->fa.flags & H5FD_LOG_NUM_SEEK) + HDfprintf(file->logfp, "Total number of seek operations: %llu\n", file->total_seek_ops); + if(file->fa.flags & H5FD_LOG_NUM_TRUNCATE) + HDfprintf(file->logfp, "Total number of truncate operations: %llu\n", file->total_truncate_ops); + + /* Dump the total time in seek/read/write */ + if(file->fa.flags & H5FD_LOG_TIME_READ) + HDfprintf(file->logfp, "Total time in read operations: %f s\n", file->total_read_time); + if(file->fa.flags & H5FD_LOG_TIME_WRITE) + HDfprintf(file->logfp, "Total time in write operations: %f s\n", file->total_write_time); + if(file->fa.flags & H5FD_LOG_TIME_SEEK) + HDfprintf(file->logfp, "Total time in seek operations: %f s\n", file->total_seek_time); + /* Dump the write I/O information */ if(file->fa.flags & H5FD_LOG_FILE_WRITE) { HDfprintf(file->logfp, "Dumping write I/O information:\n"); @@ -725,7 +794,8 @@ H5FD_log_close(H5FD_t *_file) fclose(file->logfp); } /* end if */ - H5MM_xfree(file); + /* Release the file info */ + file = H5FL_FREE(H5FD_log_t, file); done: FUNC_LEAVE_NOAPI(ret_value) @@ -739,53 +809,56 @@ done: * arbitrary (but consistent) ordering. * * Return: Success: A value like strcmp() - * * Failure: never fails (arguments were checked by the * caller). * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static int H5FD_log_cmp(const H5FD_t *_f1, const H5FD_t *_f2) { - const H5FD_log_t *f1 = (const H5FD_log_t*)_f1; - const H5FD_log_t *f2 = (const H5FD_log_t*)_f2; - int ret_value=0; + const H5FD_log_t *f1 = (const H5FD_log_t *)_f1; + const H5FD_log_t *f2 = (const H5FD_log_t *)_f2; + int ret_value = 0; - FUNC_ENTER_NOAPI(H5FD_log_cmp, H5FD_VFD_DEFAULT) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_cmp) #ifdef _WIN32 - if (f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1) - if (f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1) + if(f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1) + if(f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1) - if (f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1) - if (f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1) + if(f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1) + if(f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1) #else #ifdef H5_DEV_T_IS_SCALAR - if (f1->device < f2->device) HGOTO_DONE(-1) - if (f1->device > f2->device) HGOTO_DONE(1) + if(f1->device < f2->device) HGOTO_DONE(-1) + if(f1->device > f2->device) HGOTO_DONE(1) #else /* H5_DEV_T_IS_SCALAR */ /* If dev_t isn't a scalar value on this system, just use memcmp to * determine if the values are the same or not. The actual return value * shouldn't really matter... */ - if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t))<0) HGOTO_DONE(-1) - if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t))>0) HGOTO_DONE(1) + if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t)) < 0) HGOTO_DONE(-1) + if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t)) > 0) HGOTO_DONE(1) #endif /* H5_DEV_T_IS_SCALAR */ - if (f1->inode < f2->inode) HGOTO_DONE(-1) - if (f1->inode > f2->inode) HGOTO_DONE(1) +#ifndef H5_VMS + if(f1->inode < f2->inode) HGOTO_DONE(-1) + if(f1->inode > f2->inode) HGOTO_DONE(1) +#else + if(HDmemcmp(&(f1->inode), &(f2->inode), 3 * sizeof(ino_t)) < 0) HGOTO_DONE(-1) + if(HDmemcmp(&(f1->inode), &(f2->inode), 3 * sizeof(ino_t)) > 0) HGOTO_DONE(1) +#endif /*H5_VMS*/ + #endif done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_log_cmp() */ /*------------------------------------------------------------------------- @@ -795,20 +868,18 @@ done: * (listed in H5FDpublic.h) * * Return: Success: non-negative - * * Failure: negative * * Programmer: Quincey Koziol * Friday, August 25, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ -/* ARGSUSED */ static herr_t -H5FD_log_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */) +H5FD_log_query(const H5FD_t *_file, unsigned long *flags /* out */) { + const H5FD_log_t *file = (const H5FD_log_t *)_file; + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_query) /* Set the VFL feature flags that this driver supports */ @@ -819,6 +890,10 @@ H5FD_log_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */) *flags |= H5FD_FEAT_DATA_SIEVE; /* OK to perform data sieving for faster raw data reads & writes */ *flags |= H5FD_FEAT_AGGREGATE_SMALLDATA; /* OK to aggregate "small" raw data allocations */ *flags |= H5FD_FEAT_POSIX_COMPAT_HANDLE; /* VFD handle is POSIX I/O call compatible */ + + /* Check for flags that are set by h5repart */ + if(file->fam_to_sec2) + *flags |= H5FD_FEAT_IGNORE_DRVRINFO; /* Ignore the driver info when file is opened (which eliminates it) */ } /* end if */ FUNC_LEAVE_NOAPI(SUCCEED) @@ -831,56 +906,52 @@ H5FD_log_query(const H5FD_t UNUSED * _f, unsigned long *flags /* out */) * Purpose: Allocate file memory. * * Return: Success: Address of new memory - * * Failure: HADDR_UNDEF * * Programmer: Quincey Koziol * Monday, April 17, 2000 * - * Modifications: - * *------------------------------------------------------------------------- */ /* ARGSUSED */ static haddr_t H5FD_log_alloc(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, hsize_t size) { - H5FD_log_t *file = (H5FD_log_t*)_file; - haddr_t addr; + H5FD_log_t *file = (H5FD_log_t *)_file; + haddr_t addr; haddr_t ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_log_alloc, HADDR_UNDEF) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_alloc) /* Compute the address for the block to allocate */ addr = file->eoa; /* Check if we need to align this block */ - if(size>=file->pub.threshold) { + if(size >= file->pub.threshold) { /* Check for an already aligned block */ - if(addr%file->pub.alignment!=0) - addr=((addr/file->pub.alignment)+1)*file->pub.alignment; + if(addr % file->pub.alignment != 0) + addr = ((addr / file->pub.alignment) + 1) * file->pub.alignment; } /* end if */ - file->eoa = addr+size; + file->eoa = addr + size; /* Retain the (first) flavor of the information written to the file */ - if(file->fa.flags!=0) { - if(file->fa.flags&H5FD_LOG_FLAVOR) { - assert(addr<file->iosize); - H5_CHECK_OVERFLOW(size,hsize_t,size_t); - HDmemset(&file->flavor[addr],(int)type,(size_t)size); + if(file->fa.flags != 0) { + if(file->fa.flags & H5FD_LOG_FLAVOR) { + HDassert(addr < file->iosize); + H5_CHECK_OVERFLOW(size, hsize_t, size_t); + HDmemset(&file->flavor[addr], (int)type, (size_t)size); } /* end if */ - if(file->fa.flags&H5FD_LOG_ALLOC) - HDfprintf(file->logfp,"%10a-%10a (%10Hu bytes) (%s) Allocated\n",addr,addr+size-1,size,flavors[type]); + if(file->fa.flags & H5FD_LOG_ALLOC) + HDfprintf(file->logfp, "%10a-%10a (%10Hu bytes) (%s) Allocated\n", addr, (addr + size) - 1, size, flavors[type]); } /* end if */ /* Set return value */ - ret_value=addr; + ret_value = addr; -done: FUNC_LEAVE_NOAPI(ret_value) -} /* H5FD_log_alloc() */ +} /* end H5FD_log_alloc() */ /*------------------------------------------------------------------------- @@ -891,33 +962,22 @@ done: * format address space. * * Return: Success: The end-of-address marker. - * * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * Monday, August 2, 1999 * - * Modifications: - * Raymond Lu - * 21 Dec. 2006 - * Added the parameter TYPE. It's only used for MULTI driver. - * *------------------------------------------------------------------------- */ static haddr_t H5FD_log_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) { - const H5FD_log_t *file = (const H5FD_log_t*)_file; - haddr_t ret_value; /* Return value */ + const H5FD_log_t *file = (const H5FD_log_t *)_file; - FUNC_ENTER_NOAPI(H5FD_log_get_eoa, HADDR_UNDEF) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_get_eoa) - /* Set return value */ - ret_value=file->eoa; - -done: - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI(file->eoa) +} /* end H5FD_log_get_eoa() */ /*------------------------------------------------------------------------- @@ -928,32 +988,24 @@ done: * to tell the driver where the end of the HDF5 data is located. * * Return: Success: 0 - * * Failure: -1 * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * Raymond Lu - * 21 Dec. 2006 - * Added the parameter TYPE. It's only used for MULTI driver. - * *------------------------------------------------------------------------- */ static herr_t H5FD_log_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr) { - H5FD_log_t *file = (H5FD_log_t*)_file; - herr_t ret_value=SUCCEED; /* Return value */ + H5FD_log_t *file = (H5FD_log_t *)_file; - FUNC_ENTER_NOAPI(H5FD_log_set_eoa, FAIL) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_set_eoa) file->eoa = addr; -done: - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI(SUCCEED) +} /* end H5FD_log_set_eoa() */ /*------------------------------------------------------------------------- @@ -966,30 +1018,22 @@ done: * Return: Success: End of file address, the first address past * the end of the "file", either the Unix file * or the HDF5 file. - * * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static haddr_t H5FD_log_get_eof(const H5FD_t *_file) { - const H5FD_log_t *file = (const H5FD_log_t*)_file; - haddr_t ret_value; /* Return value */ + const H5FD_log_t *file = (const H5FD_log_t *)_file; - FUNC_ENTER_NOAPI(H5FD_log_get_eof, HADDR_UNDEF) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_log_get_eof) - /* Set return value */ - ret_value=MAX(file->eof, file->eoa); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI(MAX(file->eof, file->eoa)) +} /* end H5FD_log_get_eof() */ /*------------------------------------------------------------------------- @@ -1002,18 +1046,16 @@ done: * Programmer: Raymond Lu * Sept. 16, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ /* ARGSUSED */ static herr_t -H5FD_log_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle) +H5FD_log_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void **file_handle) { H5FD_log_t *file = (H5FD_log_t *)_file; herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5FD_log_get_handle, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_get_handle) if(!file_handle) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid") @@ -1022,7 +1064,7 @@ H5FD_log_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void** file_handle) done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_log_get_handle() */ /*------------------------------------------------------------------------- @@ -1034,14 +1076,11 @@ done: * * Return: Success: Zero. Result is stored in caller-supplied * buffer BUF. - * * Failure: -1, Contents of buffer BUF are undefined. * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ /* ARGSUSED */ @@ -1049,20 +1088,25 @@ static herr_t H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t addr, size_t size, void *buf/*out*/) { - H5FD_log_t *file = (H5FD_log_t*)_file; + H5FD_log_t *file = (H5FD_log_t *)_file; ssize_t nbytes; - herr_t ret_value=SUCCEED; /* Return value */ + size_t orig_size = size; /* Save the original size for later */ + haddr_t orig_addr = addr; +#ifdef H5_HAVE_GETTIMEOFDAY + struct timeval timeval_start, timeval_stop; +#endif /* H5_HAVE_GETTIMEOFDAY */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_log_read, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_read) - assert(file && file->pub.cls); - assert(buf); + HDassert(file && file->pub.cls); + HDassert(buf); /* Check for overflow conditions */ - if (HADDR_UNDEF==addr) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined") - if (REGION_OVERFLOW(addr, size)) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + if(!H5F_addr_defined(addr)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %llu", (unsigned long long)addr) + if(REGION_OVERFLOW(addr, size)) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr) /* If the file is open for SWMR read access, allow access to data past * the end of the allocated space (the 'eoa'). This is done because the * eoa stored in the file's superblock might be out of sync with the @@ -1070,76 +1114,151 @@ H5FD_log_read(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t addr * SWMR write operations. */ if(!file->swmr_read && (addr + size) > file->eoa) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr) /* Log the I/O information about the read */ - if(file->fa.flags!=0) { - size_t tmp_size=size; - haddr_t tmp_addr=addr; + if(file->fa.flags != 0) { + size_t tmp_size = size; + haddr_t tmp_addr = addr; /* Log information about the number of times these locations are read */ - if(file->fa.flags&H5FD_LOG_FILE_READ) { - assert((addr+size)<file->iosize); - while(tmp_size-->0) + if(file->fa.flags & H5FD_LOG_FILE_READ) { + HDassert((addr + size) < file->iosize); + while(tmp_size-- > 0) file->nread[tmp_addr++]++; } /* end if */ + } /* end if */ - /* Log information about the seek, if it's going to occur */ - if(file->fa.flags&H5FD_LOG_LOC_SEEK) { - if(addr!=file->pos || OP_READ!=file->op) - HDfprintf(file->logfp,"Seek: From %10a To %10a\n",file->pos,addr); - } /* end if */ + /* Seek to the correct location */ + if(addr != file->pos || OP_READ != file->op) { +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_SEEK) + HDgettimeofday(&timeval_start, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + if(HDlseek(file->fd, (HDoff_t)addr, SEEK_SET) < 0) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_SEEK) + HDgettimeofday(&timeval_stop, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + + /* Log information about the seek */ + if(file->fa.flags & H5FD_LOG_NUM_SEEK) + file->total_seek_ops++; + if(file->fa.flags & H5FD_LOG_LOC_SEEK) { + HDfprintf(file->logfp, "Seek: From %10a To %10a", file->pos, addr); +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_SEEK) { + struct timeval timeval_diff; + double time_diff; + + /* Calculate the elapsed gettimeofday time */ + timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(timeval_diff.tv_usec < 0) { + timeval_diff.tv_usec += 1000000; + timeval_diff.tv_sec--; + } /* end if */ + time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0); + HDfprintf(file->logfp, " (%f s)\n", time_diff); - /* Log information about the read */ - if(file->fa.flags&H5FD_LOG_LOC_READ) { - HDfprintf(file->logfp,"%10a-%10a (%10Zu bytes) (%s) Read\n",addr,addr+size-1,size,flavors[type]); -/* XXX: Verify the flavor information, if we have it? */ + /* Add to total seek time */ + file->total_seek_time += time_diff; + } /* end if */ + else + HDfprintf(file->logfp, "\n"); +#else /* H5_HAVE_GETTIMEOFDAY */ + HDfprintf(file->logfp, "\n"); +#endif /* H5_HAVE_GETTIMEOFDAY */ } /* end if */ } /* end if */ - /* Seek to the correct location */ - if ((addr!=file->pos || OP_READ!=file->op) && - file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0) { - file->pos = HADDR_UNDEF; - file->op = OP_UNKNOWN; - HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") - } - /* * Read data, being careful of interrupted system calls, partial results, * and the end of the file. */ - while (size>0) { +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_READ) + HDgettimeofday(&timeval_start, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + while(size > 0) { do { nbytes = HDread(file->fd, buf, size); - } while (-1==nbytes && EINTR==errno); - if (-1==nbytes) { - /* error */ - file->pos = HADDR_UNDEF; - file->op = OP_UNKNOWN; - HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed") - } - if (0==nbytes) { + } while(-1 == nbytes && EINTR == errno); + if(-1 == nbytes) { /* error */ + int myerrno = errno; + time_t mytime = HDtime(NULL); + HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR); + + if(file->fa.flags & H5FD_LOG_LOC_READ) + HDfprintf(file->logfp, "Error! Reading: %10a-%10a (%10Zu bytes)\n", orig_addr, (orig_addr + orig_size) - 1, orig_size); + + HGOTO_ERROR(H5E_IO, H5E_READERROR, FAIL, "file read failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, size = %lu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long)size, (unsigned long long)myoffset); + } /* end if */ + if(0 == nbytes) { /* end of file but not end of format address space */ HDmemset(buf, 0, size); - size = 0; - } - assert(nbytes>=0); - assert((size_t)nbytes<=size); - H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t); + break; + } /* end if */ + HDassert(nbytes >= 0); + HDassert((size_t)nbytes <= size); + H5_CHECK_OVERFLOW(nbytes, ssize_t, size_t); size -= (size_t)nbytes; - H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t); + H5_CHECK_OVERFLOW(nbytes, ssize_t, haddr_t); addr += (haddr_t)nbytes; - buf = (char*)buf + nbytes; - } + buf = (char *)buf + nbytes; + } /* end while */ +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_READ) + HDgettimeofday(&timeval_stop, NULL); +#endif /* H5_HAVE_GETTIMEOFDAY */ + + /* Log information about the read */ + if(file->fa.flags & H5FD_LOG_NUM_READ) + file->total_read_ops++; + if(file->fa.flags & H5FD_LOG_LOC_READ) { + HDfprintf(file->logfp, "%10a-%10a (%10Zu bytes) (%s) Read", orig_addr, (orig_addr + orig_size) - 1, orig_size, flavors[type]); + + /* XXX: Verify the flavor information, if we have it? */ + +#ifdef H5_HAVE_GETTIMEOFDAY + if(file->fa.flags & H5FD_LOG_TIME_READ) { + struct timeval timeval_diff; + double time_diff; + + /* Calculate the elapsed gettimeofday time */ + timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(timeval_diff.tv_usec < 0) { + timeval_diff.tv_usec += 1000000; + timeval_diff.tv_sec--; + } /* end if */ + time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0); + HDfprintf(file->logfp, " (%f s)\n", time_diff); + + /* Add to total read time */ + file->total_read_time += time_diff; + } /* end if */ + else + HDfprintf(file->logfp, "\n"); +#else /* H5_HAVE_GETTIMEOFDAY */ + HDfprintf(file->logfp, "\n"); +#endif /* H5_HAVE_GETTIMEOFDAY */ + } /* end if */ /* Update current position */ file->pos = addr; file->op = OP_READ; done: + if(ret_value < 0) { + /* Reset last file I/O information */ + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_log_read() */ /*------------------------------------------------------------------------- @@ -1150,14 +1269,11 @@ done: * DXPL_ID. * * Return: Success: Zero - * * Failure: -1 * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ /* ARGSUSED */ @@ -1165,80 +1281,86 @@ static herr_t H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t addr, size_t size, const void *buf) { - H5FD_log_t *file = (H5FD_log_t*)_file; + H5FD_log_t *file = (H5FD_log_t *)_file; ssize_t nbytes; - size_t orig_size=size; /* Save the original size for later */ - haddr_t orig_addr=addr; + size_t orig_size = size; /* Save the original size for later */ + haddr_t orig_addr = addr; #ifdef H5_HAVE_GETTIMEOFDAY - struct timeval timeval_start,timeval_stop; - struct timeval timeval_diff; + struct timeval timeval_start, timeval_stop; #endif /* H5_HAVE_GETTIMEOFDAY */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_log_write, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_write) - assert(file && file->pub.cls); - assert(size>0); - assert(buf); + HDassert(file && file->pub.cls); + HDassert(size > 0); + HDassert(buf); /* Verify that we are writing out the type of data we allocated in this location */ if(file->flavor) { - assert(type==H5FD_MEM_DEFAULT || type==(H5FD_mem_t)file->flavor[addr] || (H5FD_mem_t)file->flavor[addr]==H5FD_MEM_DEFAULT); - assert(type==H5FD_MEM_DEFAULT || type==(H5FD_mem_t)file->flavor[(addr+size)-1] || (H5FD_mem_t)file->flavor[(addr+size)-1]==H5FD_MEM_DEFAULT); + HDassert(type == H5FD_MEM_DEFAULT || type == (H5FD_mem_t)file->flavor[addr] || (H5FD_mem_t)file->flavor[addr] == H5FD_MEM_DEFAULT); + HDassert(type == H5FD_MEM_DEFAULT || type == (H5FD_mem_t)file->flavor[(addr + size) - 1] || (H5FD_mem_t)file->flavor[(addr + size) - 1] == H5FD_MEM_DEFAULT); } /* end if */ /* Check for overflow conditions */ - if (HADDR_UNDEF==addr) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined") - if (REGION_OVERFLOW(addr, size)) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") - if (addr+size>file->eoa) - HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow") + if(!H5F_addr_defined(addr)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "addr undefined, addr = %llu", (unsigned long long)addr) + if(REGION_OVERFLOW(addr, size)) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu, size = %llu", (unsigned long long)addr, (unsigned long long)size) + if((addr + size) > file->eoa) + HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu, size = %llu, eoa = %llu", (unsigned long long)addr, (unsigned long long)size, (unsigned long long)file->eoa) /* Log the I/O information about the write */ - if(file->fa.flags&H5FD_LOG_FILE_WRITE) { - size_t tmp_size=size; - haddr_t tmp_addr=addr; + if(file->fa.flags & H5FD_LOG_FILE_WRITE) { + size_t tmp_size = size; + haddr_t tmp_addr = addr; - assert((addr+size)<file->iosize); - while(tmp_size-->0) + /* Log information about the number of times these locations are read */ + HDassert((addr + size) < file->iosize); + while(tmp_size-- > 0) file->nwrite[tmp_addr++]++; } /* end if */ /* Seek to the correct location */ - if (addr!=file->pos || OP_WRITE!=file->op) { + if(addr != file->pos || OP_WRITE != file->op) { #ifdef H5_HAVE_GETTIMEOFDAY - if(file->fa.flags&H5FD_LOG_TIME_SEEK) - HDgettimeofday(&timeval_start,NULL); + if(file->fa.flags & H5FD_LOG_TIME_SEEK) + HDgettimeofday(&timeval_start, NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ - if(file_seek(file->fd, (file_offset_t)addr, SEEK_SET)<0) { - file->pos = HADDR_UNDEF; - file->op = OP_UNKNOWN; - HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") - } /* end if */ + if(HDlseek(file->fd, (HDoff_t)addr, SEEK_SET) < 0) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") #ifdef H5_HAVE_GETTIMEOFDAY - if(file->fa.flags&H5FD_LOG_TIME_SEEK) - HDgettimeofday(&timeval_stop,NULL); + if(file->fa.flags & H5FD_LOG_TIME_SEEK) + HDgettimeofday(&timeval_stop, NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ /* Log information about the seek */ - if(file->fa.flags&H5FD_LOG_LOC_SEEK) { + if(file->fa.flags & H5FD_LOG_NUM_SEEK) + file->total_seek_ops++; + if(file->fa.flags & H5FD_LOG_LOC_SEEK) { + HDfprintf(file->logfp, "Seek: From %10a To %10a", file->pos, addr); #ifdef H5_HAVE_GETTIMEOFDAY - HDfprintf(file->logfp,"Seek: From %10a To %10a",file->pos,addr); - if(file->fa.flags&H5FD_LOG_TIME_SEEK) { - /* Calculate the elapsed gettimeofday time */ - timeval_diff.tv_usec=timeval_stop.tv_usec-timeval_start.tv_usec; - timeval_diff.tv_sec=timeval_stop.tv_sec-timeval_start.tv_sec; - if(timeval_diff.tv_usec<0) { - timeval_diff.tv_usec+=1000000; - timeval_diff.tv_sec--; - } /* end if */ - HDfprintf(file->logfp," (%f s)\n",(double)timeval_diff.tv_sec+((double)timeval_diff.tv_usec/(double)1000000.0)); + if(file->fa.flags & H5FD_LOG_TIME_SEEK) { + struct timeval timeval_diff; + double time_diff; + + /* Calculate the elapsed gettimeofday time */ + timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(timeval_diff.tv_usec < 0) { + timeval_diff.tv_usec += 1000000; + timeval_diff.tv_sec--; + } /* end if */ + time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0); + HDfprintf(file->logfp, " (%f s)\n", time_diff); + + /* Add to total seek time */ + file->total_seek_time += time_diff; } /* end if */ else - HDfprintf(file->logfp,"\n"); + HDfprintf(file->logfp, "\n"); #else /* H5_HAVE_GETTIMEOFDAY */ - HDfprintf(file->logfp,"Seek: From %10a To %10a\n",file->pos,addr); + HDfprintf(file->logfp, "\n"); #endif /* H5_HAVE_GETTIMEOFDAY */ } /* end if */ } /* end if */ @@ -1249,70 +1371,87 @@ H5FD_log_write(H5FD_t *_file, H5FD_mem_t type, hid_t UNUSED dxpl_id, haddr_t add */ #ifdef H5_HAVE_GETTIMEOFDAY if(file->fa.flags&H5FD_LOG_TIME_WRITE) - HDgettimeofday(&timeval_start,NULL); + HDgettimeofday(&timeval_start, NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ - while (size>0) { + while(size > 0) { do { nbytes = HDwrite(file->fd, buf, size); - } while (-1==nbytes && EINTR==errno); - if (-1==nbytes) { - /* error */ - file->pos = HADDR_UNDEF; - file->op = OP_UNKNOWN; - if(file->fa.flags&H5FD_LOG_LOC_WRITE) - HDfprintf(file->logfp,"Error! Writing: %10a-%10a (%10Zu bytes)\n",orig_addr,orig_addr+orig_size-1,orig_size); - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") - } - assert(nbytes>0); - assert((size_t)nbytes<=size); - H5_CHECK_OVERFLOW(nbytes,ssize_t,size_t); + } while(-1 == nbytes && EINTR == errno); + if(-1 == nbytes) { /* error */ + int myerrno = errno; + time_t mytime = HDtime(NULL); + HDoff_t myoffset = HDlseek(file->fd, (HDoff_t)0, SEEK_CUR); + + if(file->fa.flags & H5FD_LOG_LOC_WRITE) + HDfprintf(file->logfp, "Error! Writing: %10a-%10a (%10Zu bytes)\n", orig_addr, (orig_addr + orig_size) - 1, orig_size); + + HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed: time = %s, filename = '%s', file descriptor = %d, errno = %d, error message = '%s', buf = %p, size = %lu, offset = %llu", HDctime(&mytime), file->filename, file->fd, myerrno, HDstrerror(myerrno), buf, (unsigned long)size, (unsigned long long)myoffset); + } /* end if */ + HDassert(nbytes > 0); + HDassert((size_t)nbytes <= size); + H5_CHECK_OVERFLOW(nbytes, ssize_t, size_t); size -= (size_t)nbytes; - H5_CHECK_OVERFLOW(nbytes,ssize_t,haddr_t); + H5_CHECK_OVERFLOW(nbytes, ssize_t, haddr_t); addr += (haddr_t)nbytes; - buf = (const char*)buf + nbytes; - } + buf = (const char *)buf + nbytes; + } /* end while */ #ifdef H5_HAVE_GETTIMEOFDAY - if(file->fa.flags&H5FD_LOG_TIME_WRITE) - HDgettimeofday(&timeval_stop,NULL); + if(file->fa.flags & H5FD_LOG_TIME_WRITE) + HDgettimeofday(&timeval_stop, NULL); #endif /* H5_HAVE_GETTIMEOFDAY */ /* Log information about the write */ - if(file->fa.flags&H5FD_LOG_LOC_WRITE) { - HDfprintf(file->logfp,"%10a-%10a (%10Zu bytes) (%s) Written",orig_addr,orig_addr+orig_size-1,orig_size,flavors[type]); + if(file->fa.flags & H5FD_LOG_NUM_WRITE) + file->total_write_ops++; + if(file->fa.flags & H5FD_LOG_LOC_WRITE) { + HDfprintf(file->logfp, "%10a-%10a (%10Zu bytes) (%s) Written", orig_addr, (orig_addr + orig_size) - 1, orig_size, flavors[type]); /* Check if this is the first write into a "default" section, grabbed by the metadata agregation algorithm */ - if(file->fa.flags&H5FD_LOG_FLAVOR) { - if((H5FD_mem_t)file->flavor[orig_addr]==H5FD_MEM_DEFAULT) - HDmemset(&file->flavor[orig_addr],(int)type,orig_size); + if(file->fa.flags & H5FD_LOG_FLAVOR) { + if((H5FD_mem_t)file->flavor[orig_addr] == H5FD_MEM_DEFAULT) + HDmemset(&file->flavor[orig_addr], (int)type, orig_size); } /* end if */ #ifdef H5_HAVE_GETTIMEOFDAY - if(file->fa.flags&H5FD_LOG_TIME_WRITE) { - /* Calculate the elapsed gettimeofday time */ - timeval_diff.tv_usec=timeval_stop.tv_usec-timeval_start.tv_usec; - timeval_diff.tv_sec=timeval_stop.tv_sec-timeval_start.tv_sec; - if(timeval_diff.tv_usec<0) { - timeval_diff.tv_usec+=1000000; - timeval_diff.tv_sec--; - } /* end if */ - HDfprintf(file->logfp," (%f s)\n",(double)timeval_diff.tv_sec+((double)timeval_diff.tv_usec/(double)1000000.0)); + if(file->fa.flags & H5FD_LOG_TIME_WRITE) { + struct timeval timeval_diff; + double time_diff; + + /* Calculate the elapsed gettimeofday time */ + timeval_diff.tv_usec = timeval_stop.tv_usec - timeval_start.tv_usec; + timeval_diff.tv_sec = timeval_stop.tv_sec - timeval_start.tv_sec; + if(timeval_diff.tv_usec < 0) { + timeval_diff.tv_usec += 1000000; + timeval_diff.tv_sec--; + } /* end if */ + time_diff = (double)timeval_diff.tv_sec + ((double)timeval_diff.tv_usec / (double)1000000.0); + HDfprintf(file->logfp, " (%f s)\n", time_diff); + + /* Add to total write time */ + file->total_write_time += time_diff; } /* end if */ else - HDfprintf(file->logfp,"\n"); + HDfprintf(file->logfp, "\n"); #else /* H5_HAVE_GETTIMEOFDAY */ - HDfprintf(file->logfp,"\n"); + HDfprintf(file->logfp, "\n"); #endif /* H5_HAVE_GETTIMEOFDAY */ } /* end if */ /* Update current position and eof */ file->pos = addr; file->op = OP_WRITE; - if (file->pos>file->eof) + if(file->pos > file->eof) file->eof = file->pos; done: + if(ret_value < 0) { + /* Reset last file I/O information */ + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + } /* end if */ + FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_log_write() */ /*------------------------------------------------------------------------- @@ -1331,22 +1470,53 @@ done: */ /* ARGSUSED */ static herr_t -H5FD_log_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, unsigned UNUSED closing) +H5FD_log_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing) { - H5FD_log_t *file = (H5FD_log_t*)_file; - herr_t ret_value=SUCCEED; /* Return value */ + H5FD_log_t *file = (H5FD_log_t *)_file; + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5FD_log_truncate) + + HDassert(file); + + /* Extend the file to make sure it's large enough */ + if(!H5F_addr_eq(file->eoa, file->eof)) { +#ifdef _WIN32 + HFILE filehandle; /* Windows file handle */ + LARGE_INTEGER li; /* 64-bit integer for SetFilePointer() call */ + + /* Map the posix file handle to a Windows file handle */ + filehandle = _get_osfhandle(file->fd); + + /* Translate 64-bit integers into form Windows wants */ + /* [This algorithm is from the Windows documentation for SetFilePointer()] */ + li.QuadPart = (LONGLONG)file->eoa; + (void)SetFilePointer((HANDLE)filehandle, li.LowPart, &li.HighPart, FILE_BEGIN); + if(SetEndOfFile((HANDLE)filehandle) == 0) + HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly") +#else /* _WIN32 */ +#ifdef H5_VMS + /* Reset seek offset to the beginning of the file, so that the file isn't + * re-extended later. This may happen on Open VMS. */ + if(-1 == HDlseek(file->fd, (HDoff_t)0, SEEK_SET)) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") +#endif - FUNC_ENTER_NOAPI(H5FD_log_truncate, FAIL) + if(-1 == HDftruncate(file->fd, (HDoff_t)file->eoa)) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to extend file properly") +#endif /* _WIN32 */ - if(file->eoa>file->eof) { - if(-1 == file_seek(file->fd, (file_offset_t)(file->eoa - 1), SEEK_SET)) - HGOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") - if(HDwrite(file->fd, "", (size_t)1) != 1) - HGOTO_ERROR(H5E_IO, H5E_WRITEERROR, FAIL, "file write failed") + /* Log information about the truncate */ + if(file->fa.flags & H5FD_LOG_NUM_TRUNCATE) + file->total_truncate_ops++; + + /* Update the eof value */ file->eof = file->eoa; - file->pos = file->eoa; - file->op = OP_WRITE; - } + + /* Reset last file I/O information */ + file->pos = HADDR_UNDEF; + file->op = OP_UNKNOWN; + } /* end if */ done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5FDlog.h b/src/H5FDlog.h index e829016..ffc4df1 100644 --- a/src/H5FDlog.h +++ b/src/H5FDlog.h @@ -28,30 +28,32 @@ /* Flags for H5Pset_fapl_log() */ /* Flags for tracking where reads/writes/seeks occur */ -#define H5FD_LOG_LOC_READ 0x0001 -#define H5FD_LOG_LOC_WRITE 0x0002 -#define H5FD_LOG_LOC_SEEK 0x0004 +#define H5FD_LOG_LOC_READ 0x00000001 +#define H5FD_LOG_LOC_WRITE 0x00000002 +#define H5FD_LOG_LOC_SEEK 0x00000004 #define H5FD_LOG_LOC_IO (H5FD_LOG_LOC_READ|H5FD_LOG_LOC_WRITE|H5FD_LOG_LOC_SEEK) /* Flags for tracking number of times each byte is read/written */ -#define H5FD_LOG_FILE_READ 0x0008 -#define H5FD_LOG_FILE_WRITE 0x0010 +#define H5FD_LOG_FILE_READ 0x00000008 +#define H5FD_LOG_FILE_WRITE 0x00000010 #define H5FD_LOG_FILE_IO (H5FD_LOG_FILE_READ|H5FD_LOG_FILE_WRITE) /* Flag for tracking "flavor" (type) of information stored at each byte */ -#define H5FD_LOG_FLAVOR 0x0020 -/* Flags for tracking total number of reads/writes/seeks */ -#define H5FD_LOG_NUM_READ 0x0040 -#define H5FD_LOG_NUM_WRITE 0x0080 -#define H5FD_LOG_NUM_SEEK 0x0100 -#define H5FD_LOG_NUM_IO (H5FD_LOG_NUM_READ|H5FD_LOG_NUM_WRITE|H5FD_LOG_NUM_SEEK) -/* Flags for tracking time spent in open/read/write/seek/close */ -#define H5FD_LOG_TIME_OPEN 0x0200 /* Not implemented yet */ -#define H5FD_LOG_TIME_READ 0x0400 /* Not implemented yet */ -#define H5FD_LOG_TIME_WRITE 0x0800 /* Partially implemented (need to track total time) */ -#define H5FD_LOG_TIME_SEEK 0x1000 /* Partially implemented (need to track total time & track time for seeks during reading) */ -#define H5FD_LOG_TIME_CLOSE 0x2000 /* Fully implemented */ -#define H5FD_LOG_TIME_IO (H5FD_LOG_TIME_OPEN|H5FD_LOG_TIME_READ|H5FD_LOG_TIME_WRITE|H5FD_LOG_TIME_SEEK|H5FD_LOG_TIME_CLOSE) +#define H5FD_LOG_FLAVOR 0x00000020 +/* Flags for tracking total number of reads/writes/seeks/truncates */ +#define H5FD_LOG_NUM_READ 0x00000040 +#define H5FD_LOG_NUM_WRITE 0x00000080 +#define H5FD_LOG_NUM_SEEK 0x00000100 +#define H5FD_LOG_NUM_TRUNCATE 0x00000200 +#define H5FD_LOG_NUM_IO (H5FD_LOG_NUM_READ|H5FD_LOG_NUM_WRITE|H5FD_LOG_NUM_SEEK|H5FD_LOG_NUM_TRUNCATE) +/* Flags for tracking time spent in open/stat/read/write/seek/close */ +#define H5FD_LOG_TIME_OPEN 0x00000400 +#define H5FD_LOG_TIME_STAT 0x00000800 +#define H5FD_LOG_TIME_READ 0x00001000 +#define H5FD_LOG_TIME_WRITE 0x00002000 +#define H5FD_LOG_TIME_SEEK 0x00004000 +#define H5FD_LOG_TIME_CLOSE 0x00008000 +#define H5FD_LOG_TIME_IO (H5FD_LOG_TIME_OPEN|H5FD_LOG_TIME_STAT|H5FD_LOG_TIME_READ|H5FD_LOG_TIME_WRITE|H5FD_LOG_TIME_SEEK|H5FD_LOG_TIME_CLOSE) /* Flag for tracking allocation of space in file */ -#define H5FD_LOG_ALLOC 0x4000 +#define H5FD_LOG_ALLOC 0x00010000 #define H5FD_LOG_ALL (H5FD_LOG_ALLOC|H5FD_LOG_TIME_IO|H5FD_LOG_NUM_IO|H5FD_LOG_FLAVOR|H5FD_LOG_FILE_IO|H5FD_LOG_LOC_IO) #ifdef __cplusplus @@ -60,10 +62,11 @@ extern "C" { H5_DLL hid_t H5FD_log_init(void); H5_DLL void H5FD_log_term(void); -H5_DLL herr_t H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned flags, size_t buf_size); +H5_DLL herr_t H5Pset_fapl_log(hid_t fapl_id, const char *logfile, unsigned long long flags, size_t buf_size); #ifdef __cplusplus } #endif #endif + diff --git a/src/H5FDmpiposix.c b/src/H5FDmpiposix.c index 86f4d95..2a61c89 100644 --- a/src/H5FDmpiposix.c +++ b/src/H5FDmpiposix.c @@ -141,7 +141,7 @@ typedef struct H5FD_mpiposix_t { # define file_offset_t off64_t # define file_seek lseek64 # define file_truncate ftruncate64 -#elif defined (_WIN32) && !defined(__MWERKS__) +#elif defined (_WIN32) # /*MSVC*/ # define file_offset_t __int64 # define file_seek _lseeki64 diff --git a/src/H5FDprivate.h b/src/H5FDprivate.h index cb40e5c..fe770d2 100644 --- a/src/H5FDprivate.h +++ b/src/H5FDprivate.h @@ -31,13 +31,40 @@ */ #include "H5FDmpi.h" /* MPI-based file drivers */ -/* Macros */ + +/**************************/ +/* Library Private Macros */ +/**************************/ + +/* Length of filename buffer */ +#define H5FD_MAX_FILENAME_LEN 1024 + + +/****************************/ +/* Library Private Typedefs */ +/****************************/ + +/* File operations */ +typedef enum { + OP_UNKNOWN = 0, /* Unknown last file operation */ + OP_READ = 1, /* Last file I/O operation was a read */ + OP_WRITE = 2 /* Last file I/O operation was a write */ +} H5FD_file_op_t; + + +/*****************************/ +/* Library Private Variables */ +/*****************************/ + + +/******************************/ +/* Library Private Prototypes */ +/******************************/ /* Forward declarations for prototype arguments */ struct H5P_genplist_t; struct H5F_t; -/* Prototypes */ H5_DLL int H5FD_term_interface(void); H5_DLL H5FD_class_t *H5FD_get_class(hid_t id); H5_DLL hsize_t H5FD_sb_size(H5FD_t *file); diff --git a/src/H5FDsec2.c b/src/H5FDsec2.c index 5322737..94f1fc3 100644 --- a/src/H5FDsec2.c +++ b/src/H5FDsec2.c @@ -42,15 +42,6 @@ /* The driver identification number, initialized at runtime */ static hid_t H5FD_SEC2_g = 0; -/* File operations */ -typedef enum { - OP_UNKNOWN = 0, /* Unknown last file operation */ - OP_READ = 1, /* Last file I/O operation was a read */ - OP_WRITE = 2 /* Last file I/O operation was a write */ -} H5FD_sec2_file_op_t; - -#define H5FD_SEC2_MAX_FILENAME_LEN 1024 - /* * The description of a file belonging to this driver. The `eoa' and `eof' * determine the amount of hdf5 address space in use and the high-water mark @@ -69,8 +60,8 @@ typedef struct H5FD_sec2_t { haddr_t eoa; /*end of allocated region */ haddr_t eof; /*end of file; current file size*/ haddr_t pos; /*current file I/O position */ - H5FD_sec2_file_op_t op; /*last operation */ - char filename[H5FD_SEC2_MAX_FILENAME_LEN]; /* Copy of file name from open operation */ + H5FD_file_op_t op; /*last operation */ + char filename[H5FD_MAX_FILENAME_LEN]; /* Copy of file name from open operation */ #ifndef _WIN32 /* * On most systems the combination of device and i-node number uniquely @@ -168,10 +159,10 @@ static const H5FD_class_t H5FD_sec2_g = { 0, /*dxpl_size */ NULL, /*dxpl_copy */ NULL, /*dxpl_free */ - H5FD_sec2_open, /*open */ - H5FD_sec2_close, /*close */ - H5FD_sec2_cmp, /*cmp */ - H5FD_sec2_query, /*query */ + H5FD_sec2_open, /*open */ + H5FD_sec2_close, /*close */ + H5FD_sec2_cmp, /*cmp */ + H5FD_sec2_query, /*query */ NULL, /*get_type_map */ NULL, /*alloc */ NULL, /*free */ @@ -231,7 +222,7 @@ H5FD_sec2_init_interface(void) hid_t H5FD_sec2_init(void) { - hid_t ret_value; /* Return value */ + hid_t ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5FD_sec2_init, FAIL) @@ -293,14 +284,14 @@ H5Pset_fapl_sec2(hid_t fapl_id) FUNC_ENTER_API(H5Pset_fapl_sec2, FAIL) H5TRACE1("e", "i", fapl_id); - if(NULL == (plist = H5P_object_verify(fapl_id,H5P_FILE_ACCESS))) + if(NULL == (plist = H5P_object_verify(fapl_id, H5P_FILE_ACCESS))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a file access property list") - ret_value= H5P_set_driver(plist, H5FD_SEC2, NULL); + ret_value = H5P_set_driver(plist, H5FD_SEC2, NULL); done: FUNC_LEAVE_API(ret_value) -} +} /* end H5Pset_fapl_sec2() */ /*------------------------------------------------------------------------- @@ -311,22 +302,19 @@ done: * Return: Success: A pointer to a new file data structure. The * public fields will be initialized by the * caller, which is always H5FD_open(). - * * Failure: NULL * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static H5FD_t * H5FD_sec2_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) { H5FD_sec2_t *file = NULL; /* sec2 VFD info */ - int fd = (-1); /* File descriptor */ - int o_flags; /* Flags for open() call */ + int fd = (-1); /* File descriptor */ + int o_flags; /* Flags for open() call */ #ifdef _WIN32 HFILE filehandle; struct _BY_HANDLE_FILE_INFORMATION fileinfo; @@ -334,10 +322,10 @@ H5FD_sec2_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr) h5_stat_t sb; H5FD_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_sec2_open, NULL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_open) /* Sanity check on file offsets */ - HDassert(sizeof(HDoff_t) >= sizeof(size_t)); + HDcompile_assert(sizeof(HDoff_t) >= sizeof(size_t)); /* Check arguments */ if(!name || !*name) @@ -437,7 +425,6 @@ done: * Purpose: Closes a Unix file. * * Return: Success: 0 - * * Failure: -1, file not closed. * * Programmer: Robb Matzke @@ -448,10 +435,10 @@ done: static herr_t H5FD_sec2_close(H5FD_t *_file) { - H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_sec2_close, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_close) /* Sanity check */ HDassert(file); @@ -475,59 +462,56 @@ done: * arbitrary (but consistent) ordering. * * Return: Success: A value like strcmp() - * * Failure: never fails (arguments were checked by the * caller). * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static int H5FD_sec2_cmp(const H5FD_t *_f1, const H5FD_t *_f2) { - const H5FD_sec2_t *f1 = (const H5FD_sec2_t*)_f1; - const H5FD_sec2_t *f2 = (const H5FD_sec2_t*)_f2; - int ret_value=0; + const H5FD_sec2_t *f1 = (const H5FD_sec2_t *)_f1; + const H5FD_sec2_t *f2 = (const H5FD_sec2_t *)_f2; + int ret_value = 0; - FUNC_ENTER_NOAPI(H5FD_sec2_cmp, H5FD_VFD_DEFAULT) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_cmp) #ifdef _WIN32 - if (f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1) - if (f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1) + if(f1->fileindexhi < f2->fileindexhi) HGOTO_DONE(-1) + if(f1->fileindexhi > f2->fileindexhi) HGOTO_DONE(1) - if (f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1) - if (f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1) + if(f1->fileindexlo < f2->fileindexlo) HGOTO_DONE(-1) + if(f1->fileindexlo > f2->fileindexlo) HGOTO_DONE(1) #else #ifdef H5_DEV_T_IS_SCALAR - if (f1->device < f2->device) HGOTO_DONE(-1) - if (f1->device > f2->device) HGOTO_DONE(1) + if(f1->device < f2->device) HGOTO_DONE(-1) + if(f1->device > f2->device) HGOTO_DONE(1) #else /* H5_DEV_T_IS_SCALAR */ /* If dev_t isn't a scalar value on this system, just use memcmp to * determine if the values are the same or not. The actual return value * shouldn't really matter... */ - if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t))<0) HGOTO_DONE(-1) - if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t))>0) HGOTO_DONE(1) + if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t)) < 0) HGOTO_DONE(-1) + if(HDmemcmp(&(f1->device),&(f2->device),sizeof(dev_t)) > 0) HGOTO_DONE(1) #endif /* H5_DEV_T_IS_SCALAR */ #ifndef H5_VMS - if (f1->inode < f2->inode) HGOTO_DONE(-1) - if (f1->inode > f2->inode) HGOTO_DONE(1) + if(f1->inode < f2->inode) HGOTO_DONE(-1) + if(f1->inode > f2->inode) HGOTO_DONE(1) #else - if(HDmemcmp(&(f1->inode),&(f2->inode),3*sizeof(ino_t))<0) HGOTO_DONE(-1) - if(HDmemcmp(&(f1->inode),&(f2->inode),3*sizeof(ino_t))>0) HGOTO_DONE(1) + if(HDmemcmp(&(f1->inode), &(f2->inode), 3 * sizeof(ino_t)) < 0) HGOTO_DONE(-1) + if(HDmemcmp(&(f1->inode), &(f2->inode), 3 * sizeof(ino_t)) > 0) HGOTO_DONE(1) #endif /*H5_VMS*/ #endif done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5FD_sec2_cmp() */ /*------------------------------------------------------------------------- @@ -547,7 +531,7 @@ done: static herr_t H5FD_sec2_query(const H5FD_t *_file, unsigned long *flags /* out */) { - const H5FD_sec2_t *file = (const H5FD_sec2_t*)_file; /* sec2 VFD info */ + const H5FD_sec2_t *file = (const H5FD_sec2_t *)_file; /* sec2 VFD info */ FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_query) @@ -577,32 +561,21 @@ H5FD_sec2_query(const H5FD_t *_file, unsigned long *flags /* out */) * format address space. * * Return: Success: The end-of-address marker. - * * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * Monday, August 2, 1999 * - * Modifications: - * Raymond Lu - * 21 Dec. 2006 - * Added the parameter TYPE. It's only used for MULTI driver. - * *------------------------------------------------------------------------- */ static haddr_t H5FD_sec2_get_eoa(const H5FD_t *_file, H5FD_mem_t UNUSED type) { - const H5FD_sec2_t *file = (const H5FD_sec2_t*)_file; - haddr_t ret_value; /* Return value */ - - FUNC_ENTER_NOAPI(H5FD_sec2_get_eoa, HADDR_UNDEF) + const H5FD_sec2_t *file = (const H5FD_sec2_t *)_file; - /* Set return value */ - ret_value = file->eoa; + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_get_eoa) -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(file->eoa) } /* end H5FD_sec2_get_eoa() */ @@ -614,31 +587,23 @@ done: * to tell the driver where the end of the HDF5 data is located. * * Return: Success: 0 - * * Failure: -1 * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * Raymond Lu - * 21 Dec. 2006 - * Added the parameter TYPE. It's only used for MULTI driver. - * *------------------------------------------------------------------------- */ static herr_t H5FD_sec2_set_eoa(H5FD_t *_file, H5FD_mem_t UNUSED type, haddr_t addr) { - H5FD_sec2_t *file = (H5FD_sec2_t*)_file; - herr_t ret_value=SUCCEED; /* Return value */ + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; - FUNC_ENTER_NOAPI(H5FD_sec2_set_eoa, FAIL) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_set_eoa) file->eoa = addr; -done: - FUNC_LEAVE_NOAPI(ret_value) + FUNC_LEAVE_NOAPI(SUCCEED) } /* end H5FD_sec2_set_eoa() */ @@ -652,30 +617,22 @@ done: * Return: Success: End of file address, the first address past * the end of the "file", either the Unix file * or the HDF5 file. - * * Failure: HADDR_UNDEF * * Programmer: Robb Matzke * Thursday, July 29, 1999 * - * Modifications: - * *------------------------------------------------------------------------- */ static haddr_t H5FD_sec2_get_eof(const H5FD_t *_file) { - const H5FD_sec2_t *file = (const H5FD_sec2_t*)_file; - haddr_t ret_value; /* Return value */ + const H5FD_sec2_t *file = (const H5FD_sec2_t *)_file; - FUNC_ENTER_NOAPI(H5FD_sec2_get_eof, HADDR_UNDEF) + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5FD_sec2_get_eof) - /* Set return value */ - ret_value=MAX(file->eof, file->eoa); - -done: - FUNC_LEAVE_NOAPI(ret_value) -} + FUNC_LEAVE_NOAPI(MAX(file->eof, file->eoa)) +} /* end H5FD_sec2_get_eof() */ /*------------------------------------------------------------------------- @@ -697,10 +654,11 @@ H5FD_sec2_get_handle(H5FD_t *_file, hid_t UNUSED fapl, void **file_handle) H5FD_sec2_t *file = (H5FD_sec2_t *)_file; herr_t ret_value = SUCCEED; - FUNC_ENTER_NOAPI(H5FD_sec2_get_handle, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_get_handle) if(!file_handle) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "file handle not valid") + *file_handle = &(file->fd); done: @@ -729,11 +687,11 @@ static herr_t H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, size_t size, void *buf/*out*/) { - H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; ssize_t nbytes; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_sec2_read, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_read) HDassert(file && file->pub.cls); HDassert(buf); @@ -753,9 +711,10 @@ H5FD_sec2_read(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu", (unsigned long long)addr) /* Seek to the correct location */ - if((addr != file->pos || OP_READ != file->op) && - HDlseek(file->fd, (HDoff_t)addr, SEEK_SET) < 0) - HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") + if(addr != file->pos || OP_READ != file->op) { + if(HDlseek(file->fd, (HDoff_t)addr, SEEK_SET) < 0) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") + } /* end if */ /* * Read data, being careful of interrupted system calls, partial results, @@ -821,11 +780,11 @@ static herr_t H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, haddr_t addr, size_t size, const void *buf) { - H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; ssize_t nbytes; - herr_t ret_value = SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_sec2_write, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_write) HDassert(file && file->pub.cls); HDassert(buf); @@ -839,9 +798,10 @@ H5FD_sec2_write(H5FD_t *_file, H5FD_mem_t UNUSED type, hid_t UNUSED dxpl_id, had HGOTO_ERROR(H5E_ARGS, H5E_OVERFLOW, FAIL, "addr overflow, addr = %llu, size = %llu, eoa = %llu", (unsigned long long)addr, (unsigned long long)size, (unsigned long long)file->eoa) /* Seek to the correct location */ - if((addr != file->pos || OP_WRITE != file->op) && - HDlseek(file->fd, (HDoff_t)addr, SEEK_SET) < 0) - HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") + if(addr != file->pos || OP_WRITE != file->op) { + if(HDlseek(file->fd, (HDoff_t)addr, SEEK_SET) < 0) + HSYS_GOTO_ERROR(H5E_IO, H5E_SEEKERROR, FAIL, "unable to seek to proper position") + } /* end if */ /* * Write the data, being careful of interrupted system calls and partial @@ -891,7 +851,6 @@ done: * than the end-of-address. * * Return: Success: Non-negative - * * Failure: Negative * * Programmer: Robb Matzke @@ -903,10 +862,10 @@ done: static herr_t H5FD_sec2_truncate(H5FD_t *_file, hid_t UNUSED dxpl_id, hbool_t UNUSED closing) { - H5FD_sec2_t *file = (H5FD_sec2_t*)_file; + H5FD_sec2_t *file = (H5FD_sec2_t *)_file; herr_t ret_value = SUCCEED; /* Return value */ - FUNC_ENTER_NOAPI(H5FD_sec2_truncate, FAIL) + FUNC_ENTER_NOAPI_NOINIT(H5FD_sec2_truncate) HDassert(file); diff --git a/src/H5FDstdio.c b/src/H5FDstdio.c index 3cba6a1..4eab71f 100644 --- a/src/H5FDstdio.c +++ b/src/H5FDstdio.c @@ -133,14 +133,8 @@ typedef struct H5FD_stdio_t { /* Use file_xxx to indicate these are local macros, avoiding confusing * with the global HD_xxx macros. - * Need fseeko, off_t, ftell and ftruncate are all of the same 32 or 64 - * versions. * Assume fseeko, which is POSIX standard, is always supported; * but prefer to use fseeko64 if supported. - * [Note: the ifndef H5_HAVE_FSEEKO condition to determine BIG FILE not - * supported was old code. This condition is not supposed to be true in Unix - * like systems but may happen in non-Unix systems like Windows. They are left - * in for now and will be cleaned later. -AKC-] */ #ifndef file_fseek #ifdef H5_HAVE_FSEEKO64 @@ -178,11 +172,6 @@ typedef struct H5FD_stdio_t { #define REGION_OVERFLOW(A,Z) (ADDR_OVERFLOW(A) || SIZE_OVERFLOW(Z) || \ HADDR_UNDEF==(A)+(Z) || (file_offset_t)((A)+(Z))<(file_offset_t)(A)) -#ifndef H5_HAVE_FSEEKO -/* Define big file as 2GB */ -#define BIG_FILE 0x80000000UL -#endif - /* Prototypes */ static H5FD_t *H5FD_stdio_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); @@ -595,9 +584,6 @@ H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxp { H5FD_stdio_t *file = (H5FD_stdio_t*)_file; haddr_t addr; -#ifndef H5_HAVE_FSEEKO - static const char *func = "H5FD_stdio_alloc"; /* Function Name for error reporting */ -#endif haddr_t ret_value; /* Return value */ /* Shut compiler up */ @@ -617,12 +603,6 @@ H5FD_stdio_alloc(H5FD_t *_file, H5FD_mem_t /*UNUSED*/ type, hid_t /*UNUSED*/ dxp addr = ((addr / file->pub.alignment) + 1) * file->pub.alignment; } /* end if */ -#ifndef H5_HAVE_FSEEKO - /* If fseeko isn't available, big files (>2GB) won't be supported. */ - if((addr + size) > BIG_FILE) - H5Epush_ret(func, H5E_ERR_CLS, H5E_IO, H5E_SEEKERROR, "can't write file bigger than 2GB because fseeko isn't available", HADDR_UNDEF) -#endif - file->eoa = addr + size; /* Set return value */ diff --git a/src/H5FScache.c b/src/H5FScache.c index 17f8f6a..d1c8a2a 100644 --- a/src/H5FScache.c +++ b/src/H5FScache.c @@ -555,7 +555,7 @@ H5FS_cache_hdr_size(const H5F_t UNUSED *f, const H5FS_t *fspace, size_t *size_pt *------------------------------------------------------------------------- */ static H5FS_sinfo_t * -H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t addr, void *_udata) +H5FS_cache_sinfo_load(H5F_t *f, hid_t dxpl_id, haddr_t UNUSED addr, void *_udata) { H5FS_sinfo_t *sinfo = NULL; /* Free space section info */ H5FS_sinfo_cache_ud_t *udata = (H5FS_sinfo_cache_ud_t *)_udata; /* user data for callback */ diff --git a/src/H5Fefc.c b/src/H5Fefc.c new file mode 100644 index 0000000..eebf143 --- /dev/null +++ b/src/H5Fefc.c @@ -0,0 +1,951 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Copyright by The HDF Group. * + * Copyright by the Board of Trustees of the University of Illinois. * + * All rights reserved. * + * * + * This file is part of HDF5. The full HDF5 copyright notice, including * + * terms governing use, modification, and redistribution, is contained in * + * the files COPYING and Copyright.html. COPYING can be found at the root * + * of the source code distribution tree; Copyright.html can be found at the * + * root level of an installed copy of the electronic HDF5 document set and * + * is linked from the top-level documents page. It can also be found at * + * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have * + * access to either file, you may request a copy from help@hdfgroup.org. * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/*------------------------------------------------------------------------- + * + * Created: H5Defc.c + * December 13, 2010 + * Neil Fortner <nfortne2@hdfgroup.org> + * + * Purpose: External file caching routines - implements a + * cache of external files to minimize the number of + * file opens and closes. + * + *------------------------------------------------------------------------- + */ + +#define H5F_PACKAGE /*suppress error about including H5Fpkg */ + + +/* Packages needed by this file... */ +#include "H5private.h" /* Generic Functions */ +#include "H5Eprivate.h" /* Error handling */ +#include "H5Fpkg.h" /* File access */ +#include "H5MMprivate.h" /* Memory management */ +#include "H5Pprivate.h" /* Property lists */ + + +/* Special values for the "tag" field below */ +#define H5F_EFC_TAG_DEFAULT -1 +#define H5F_EFC_TAG_LOCK -2 +#define H5F_EFC_TAG_CLOSE -3 +#define H5F_EFC_TAG_DONTCLOSE -4 + +/* Structure for each entry in a file's external file cache */ +typedef struct H5F_efc_ent_t { + char *name; /* Name of the file */ + H5F_t *file; /* File object */ + struct H5F_efc_ent_t *LRU_next; /* Next item in LRU list */ + struct H5F_efc_ent_t *LRU_prev; /* Previous item in LRU list */ + unsigned nopen; /* Number of times this file is currently opened by an EFC client */ +} H5F_efc_ent_t; + +/* Structure for a shared file struct's external file cache */ +struct H5F_efc_t { + H5SL_t *slist; /* Skip list of cached external files */ + H5F_efc_ent_t *LRU_head; /* Head of LRU list. This is the least recently used file */ + H5F_efc_ent_t *LRU_tail; /* Tail of LRU list. This is the most recently used file */ + unsigned nfiles; /* Size of the external file cache */ + unsigned max_nfiles; /* Maximum size of the external file cache */ + unsigned nrefs; /* Number of times this file appears in another file's EFC */ + int tag; /* Temporary variable used by H5F_efc_try_close() */ + H5F_file_t *tmp_next; /* Next file in temporary list used by H5F_efc_try_close() */ +}; + +/* Private prototypes */ +static herr_t H5F_efc_remove_ent(H5F_efc_t *efc, H5F_efc_ent_t *ent); +static void H5F_efc_try_close_tag1(H5F_file_t *sf, H5F_file_t **tail); +static void H5F_efc_try_close_tag2(H5F_file_t *sf, H5F_file_t **tail); + +/* Free lists */ +H5FL_DEFINE_STATIC(H5F_efc_ent_t); +H5FL_DEFINE_STATIC(H5F_efc_t); + + +/*------------------------------------------------------------------------- + * Function: H5F_efc_create + * + * Purpose: Allocate and initialize a new external file cache object, + * which can the be used to cache open external files. + * the object must be freed with H5F_efc_destroy. + * + * Return: Pointer to new external file cache object on success + * NULL on failure + * + * Programmer: Neil Fortner + * Tuesday, December 14, 2010 + * + *------------------------------------------------------------------------- + */ +H5F_efc_t * +H5F_efc_create(unsigned max_nfiles) +{ + H5F_efc_t *efc = NULL; /* EFC object */ + H5F_efc_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI(H5F_efc_create, NULL) + + /* Sanity checks */ + HDassert(max_nfiles > 0); + + /* Allocate EFC struct */ + if(NULL == (efc = H5FL_CALLOC(H5F_efc_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + /* Initialize maximum number of files */ + efc->max_nfiles = max_nfiles; + + /* Initialize temporary ref count */ + efc->tag = H5F_EFC_TAG_DEFAULT; + + /* Set the return value */ + ret_value = efc; + +done: + if(ret_value == NULL && efc) + efc = H5FL_FREE(H5F_efc_t, efc); + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_efc_create() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_efc_open + * + * Purpose: Opens a file using the external file cache. The target + * file is added to the external file cache of the parent + * if it is not already present. If the target file is in + * the parent's EFC, simply returns the target file. When + * the file object is no longer in use, it should be closed + * with H5F_efc_close (will not actually close the file + * until it is evicted from the EFC). + * + * Return: Pointer to open file on success + * NULL on failure + * + * Programmer: Neil Fortner + * Tuesday, December 14, 2010 + * + *------------------------------------------------------------------------- + */ +H5F_t * +H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, hid_t fcpl_id, + hid_t fapl_id, hid_t dxpl_id) +{ + H5F_efc_t *efc = NULL; /* External file cache for parent file */ + H5F_efc_ent_t *ent = NULL; /* Entry for target file in efc */ + hbool_t open_file = FALSE; /* Whether ent->file needs to be closed in case of error */ + H5F_t *ret_value; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_efc_open) + + /* Sanity checks */ + HDassert(parent); + HDassert(parent->shared); + HDassert(name); + + /* Get external file cache */ + efc = parent->shared->efc; + + /* Check if the EFC exists. If it does not, just call H5F_open(). We + * support this so clients do not have to make 2 different calls depending + * on the state of the efc. */ + if(!efc) { + if(NULL == (ret_value = H5F_open(name, flags, fcpl_id, fapl_id, + dxpl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open file") + + /* Increment the number of open objects to prevent the file from being + * closed out from under us - "simulate" having an open file id. Note + * that this behaviour replaces the calls to H5F_incr_nopen_objs() and + * H5F_decr_nopen_objs() in H5L_extern_traverse(). */ + ret_value->nopen_objs++; + + HGOTO_DONE(ret_value) + } /* end if */ + + /* Search the skip list for name if the skip list exists, create the skip + * list otherwise */ + if(efc->slist) { + if(efc->nfiles > 0) + ent = (H5F_efc_ent_t *)H5SL_search(efc->slist, name); + } /* end if */ + else { + HDassert(efc->nfiles == 0); + if(NULL == (efc->slist = H5SL_create(H5SL_TYPE_STR))) + HGOTO_ERROR(H5E_FILE, H5E_CANTCREATE, NULL, "can't create skip list") + } /* end else */ + + /* If we found the file update the LRU list and return the cached file, + * otherwise open the file and cache it */ + if(ent) { + HDassert(efc->LRU_head); + HDassert(efc->LRU_tail); + + /* Move ent to the head of the LRU list, if it is not already there */ + if(ent->LRU_prev) { + HDassert(efc->LRU_head != ent); + + /* Remove from current position. Note that once we touch the LRU + * list we cannot revert to the previous state. Make sure there can + * be no errors between when we first touch the LRU list and when + * the cache is in a consistent state! */ + if(ent->LRU_next) + ent->LRU_next->LRU_prev = ent->LRU_prev; + else { + HDassert(efc->LRU_tail == ent); + efc->LRU_tail = ent->LRU_prev; + } /* end else */ + ent->LRU_prev->LRU_next = ent->LRU_next; + + /* Add to head of LRU list */ + ent->LRU_next = efc->LRU_head; + ent->LRU_next->LRU_prev = ent; + ent->LRU_prev = NULL; + efc->LRU_head = ent; + } /* end if */ + + /* Mark the file as open */ + ent->nopen++; + } /* end if */ + else { + /* Check if we need to evict something */ + if(efc->nfiles == efc->max_nfiles) { + /* Search for an unopened file from the tail */ + for(ent = efc->LRU_tail; ent && ent->nopen; ent = ent->LRU_prev); + + /* Evict the file if found, otherwise just open the target file and + * do not add it to cache */ + if(ent) { + if(H5F_efc_remove_ent(efc, ent) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTREMOVE, NULL, "can't remove entry from external file cache") + + /* Do not free ent, we will recycle it below */ + } /* end if */ + else { + /* Cannot cache file, just open file and return */ + if(NULL == (ret_value = H5F_open(name, flags, fcpl_id, fapl_id, + dxpl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open file") + + /* Increment the number of open objects to prevent the file from + * being closed out from under us - "simulate" having an open + * file id */ + ret_value->nopen_objs++; + + HGOTO_DONE(ret_value) + } /* end else */ + } /* end if */ + else + /* Allocate new entry */ + if(NULL == (ent = H5FL_MALLOC(H5F_efc_ent_t))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + /* Build new entry */ + if(NULL == (ent->name = H5MM_strdup(name))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, NULL, "memory allocation failed") + + /* Open the file */ + if(NULL == (ent->file = H5F_open(name, flags, fcpl_id, fapl_id, + dxpl_id))) + HGOTO_ERROR(H5E_FILE, H5E_CANTOPENFILE, NULL, "can't open file") + open_file = TRUE; + + /* Increment the number of open objects to prevent the file from being + * closed out from under us - "simulate" having an open file id */ + ent->file->nopen_objs++; + + /* Add the file to the cache */ + /* Skip list */ + if(H5SL_insert(efc->slist, ent, ent->name) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTINSERT, NULL, "can't insert entry into skip list") + + /* Add to head of LRU list and update tail if necessary */ + ent->LRU_next = efc->LRU_head; + if(ent->LRU_next) + ent->LRU_next->LRU_prev = ent; + ent->LRU_prev = NULL; + efc->LRU_head = ent; + if(!efc->LRU_tail) { + HDassert(!ent->LRU_next); + efc->LRU_tail = ent; + } /* end if */ + + /* Mark the file as open */ + ent->nopen = 1; + + /* Update nfiles and nrefs */ + efc->nfiles++; + if(ent->file->shared->efc) + ent->file->shared->efc->nrefs++; + } /* end else */ + + HDassert(ent); + HDassert(ent->file); + HDassert(ent->name); + HDassert(ent->nopen); + + /* Set the return value */ + ret_value = ent->file; + +done: + if(!ret_value) + if(ent) { + if(open_file) { + ent->file->nopen_objs--; + if(H5F_try_close(ent->file) < 0) + HDONE_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, NULL, "can't close external file") + } /* end if */ + ent->name = (char *)H5MM_xfree(ent->name); + ent = H5FL_FREE(H5F_efc_ent_t, ent); + } /* end if */ + + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_efc_open() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_efc_close + * + * Purpose: Closes (unlocks) a file opened using the external file + * cache. The target file is not immediately closed unless + * there is no external file cache for the parent file. + * + * Return: Non-negative on success + * Negative on failure + * + * Programmer: Neil Fortner + * Wednesday, December 15, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_efc_close(H5F_t *parent, H5F_t *file) +{ + H5F_efc_t *efc = NULL; /* External file cache for parent file */ + H5F_efc_ent_t *ent = NULL; /* Entry for target file in efc */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_efc_close) + + /* Sanity checks */ + HDassert(parent); + HDassert(parent->shared); + HDassert(file); + HDassert(file->shared); + + /* Get external file cache */ + efc = parent->shared->efc; + + /* Check if the EFC exists. If it does not, just call H5F_try_close(). We + * support this so clients do not have to make 2 different calls depending + * on the state of the efc. */ + if(!efc) { + file->nopen_objs--; + if(H5F_try_close(file) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close external file") + + HGOTO_DONE(SUCCEED) + } /* end if */ + + /* Scan the parent's LRU list from the head to file file. We do this + * instead of a skip list lookup because the file will almost always be at + * the head. In the unlikely case that the file is not found, just call + * H5F_try_close(). This could happen if the EFC was full of open files + * when the file was opened. */ + for(ent = efc->LRU_head; ent && ent->file != file; ent = ent->LRU_next); + if(!ent) { + file->nopen_objs--; + if(H5F_try_close(file) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close external file") + } /* end if */ + else + /* Reduce the open count on this entry */ + ent->nopen--; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_efc_close() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_efc_max_nfiles + * + * Purpose: Returns the maximum number of files in the provided + * external file cache. + * + * Return: Maximum number of files (never fails) + * + * Programmer: Neil Fortner + * Wednesday, December 15, 2010 + * + *------------------------------------------------------------------------- + */ +unsigned +H5F_efc_max_nfiles(H5F_efc_t *efc) +{ + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_efc_max_nfiles) + + HDassert(efc); + HDassert(efc->max_nfiles > 0); + + FUNC_LEAVE_NOAPI(efc->max_nfiles) +} /* end H5F_efc_max_nfiles */ + + +/*------------------------------------------------------------------------- + * Function: H5F_efc_release + * + * Purpose: Releases the external file cache, potentially closing any + * cached files unless they are held open from somewhere + * else (or are currently opened by a client). + * + * Return: Non-negative on success + * Negative on failure + * + * Programmer: Neil Fortner + * Wednesday, December 15, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_efc_release(H5F_efc_t *efc) +{ + H5F_efc_ent_t *ent = NULL; /* EFC entry */ + H5F_efc_ent_t *prev_ent = NULL; /* Previous EFC entry */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_efc_release) + + /* Sanity checks */ + HDassert(efc); + + /* Lock the EFC to prevent manipulation of the EFC wile we are releasing it. + * The EFC should never be locked when we enter this function because that + * would require a cycle, a cycle would necessarily invoke + * H5F_efc_try_close(), and that function checks the status of the lock + * before calling this one. */ + HDassert((efc->tag == H5F_EFC_TAG_DEFAULT) + || (efc->tag == H5F_EFC_TAG_CLOSE)); + efc->tag = H5F_EFC_TAG_LOCK; + + /* Walk down the LRU list, releasing any files that are not opened by an EFC + * client */ + ent = efc->LRU_head; + while(ent) + if(!ent->nopen) { + if(H5F_efc_remove_ent(efc, ent) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTREMOVE, FAIL, "can't remove entry from external file cache") + + /* Free the entry and move to next entry in LRU list */ + prev_ent = ent; + ent = ent->LRU_next; + prev_ent = H5FL_FREE(H5F_efc_ent_t, prev_ent); + } /* end if */ + else + /* Can't release file because it's open; just advance the pointer */ + ent = ent->LRU_next; + + /* Reset tag. No need to reset to CLOSE if that was the original tag, as in + * that case the file must be getting closed anyways. */ + efc->tag = H5F_EFC_TAG_DEFAULT; + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5F_efc_release() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_efc_destroy + * + * Purpose: Frees an external file cache object, releasing it first + * if necessary. If it cannot be fully released, for example + * if there are open files, returns an error. + * + * Return: Non-negative on success + * Negative on failure + * + * Programmer: Neil Fortner + * Wednesday, December 15, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_efc_destroy(H5F_efc_t *efc) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_efc_destroy) + + /* Sanity checks */ + HDassert(efc); + + if(efc->nfiles > 0) { + /* Release (clear) the efc */ + if(H5F_efc_release(efc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") + + /* If there are still cached files, return an error */ + if(efc->nfiles > 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't destroy EFC after incomplete release") + } /* end if */ + + HDassert(efc->nfiles == 0); + HDassert(efc->LRU_head == NULL); + HDassert(efc->LRU_tail == NULL); + + /* Close skip list */ + if(efc->slist) + if(H5SL_close(efc->slist) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTFREE, FAIL, "can't close skip list") + + /* Free EFC object */ + (void)H5FL_FREE(H5F_efc_t, efc); + +done: + FUNC_LEAVE_NOAPI(ret_value); +} /* end H5F_efc_destroy() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_efc_remove_ent + * + * Purpose: Removes the specified entry from the specified EFC, + * closing the file if requested. Does not free the entry. + * + * Return: Non-negative on success + * Negative on failure + * + * Programmer: Neil Fortner + * Wednesday, December 15, 2010 + * + *------------------------------------------------------------------------- + */ +static herr_t +H5F_efc_remove_ent(H5F_efc_t *efc, H5F_efc_ent_t *ent) +{ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_efc_remove_ent) + + /* Sanity checks */ + HDassert(efc); + HDassert(efc->slist); + HDassert(ent); + + /* Remove from skip list */ + if(ent != H5SL_remove(efc->slist, ent->name)) + HGOTO_ERROR(H5E_FILE, H5E_CANTDELETE, FAIL, "can't delete entry from skip list") + + /* Remove from LRU list */ + if(ent->LRU_next) + ent->LRU_next->LRU_prev = ent->LRU_prev; + else { + HDassert(efc->LRU_tail == ent); + efc->LRU_tail = ent->LRU_prev; + } /* end else */ + if(ent->LRU_prev) + ent->LRU_prev->LRU_next = ent->LRU_next; + else { + HDassert(efc->LRU_head == ent); + efc->LRU_head = ent->LRU_next; + } /* end else */ + + /* Update nfiles and nrefs */ + efc->nfiles--; + if(ent->file->shared->efc) + ent->file->shared->efc->nrefs--; + + /* Free the name */ + ent->name = (char *)H5MM_xfree(ent->name); + + /* Close the file. Note that since H5F_t structs returned from H5F_open() + * are *always* unique, there is no need to reference count this struct. + * However we must still manipulate the nopen_objs field to prevent the file + * from being closed out from under us. */ + ent->file->nopen_objs--; + if(H5F_try_close(ent->file) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTCLOSEFILE, FAIL, "can't close external file") + ent->file = NULL; + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_efc_remove_ent() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_efc_try_close_tag1 + * + * Purpose: Recursively traverse the EFC tree, keeping a temporary + * reference count on each file that assumes all reachable + * files will eventually be closed. + * + * Return: void (never fails) + * + * Programmer: Neil Fortner + * Monday, January 10, 2011 + * + *------------------------------------------------------------------------- + */ +static void +H5F_efc_try_close_tag1(H5F_file_t *sf, H5F_file_t **tail) +{ + H5F_efc_ent_t *ent = NULL; /* EFC entry */ + H5F_file_t *esf; /* Convenience pointer to ent->file->shared */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_efc_try_close_tag1) + + /* Sanity checks */ + HDassert(sf); + HDassert(sf->efc); + HDassert((sf->efc->tag > 0) || (sf->nrefs == sf->efc->nrefs)); + HDassert(sf->efc->tag != H5F_EFC_TAG_LOCK); + HDassert(tail); + HDassert(*tail); + + /* Recurse into this file's cached files */ + for(ent = sf->efc->LRU_head; ent; ent = ent->LRU_next) { + esf = ent->file->shared; + + if(esf->efc) { + /* If tag were 0, that would mean there are more actual references + * than are counted by nrefs */ + HDassert(esf->efc->tag != 0); + + /* If tag has been set, we have already visited this file so just + * decrement tag and continue */ + if(esf->efc->tag > 0) + esf->efc->tag--; + /* If there are references that are not from an EFC, it will never + * be possible to close the file. Just continue. Also continue if + * the EFC is locked or the file is open (through the EFC). Note + * that the reference counts will never match for the root file, but + * that's ok because the root file will always have a tag and enter + * the branch above. */ + else if((esf->nrefs == esf->efc->nrefs) + && (esf->efc->tag != H5F_EFC_TAG_LOCK) && !(ent->nopen)) { + /* If we get here, this file's "tmp_next" pointer must be NULL + */ + HDassert(esf->efc->tmp_next == NULL); + + /* If nrefs > 1, Add this file to the list of files with nrefs > + * 1 and initialize tag to the number of references (except this + * one) */ + if(esf->nrefs > 1) { + (*tail)->efc->tmp_next = esf; + *tail = esf; + esf->efc->tag = (int)esf->nrefs - 1; + } /* end if */ + + /* Recurse into the entry */ + H5F_efc_try_close_tag1(ent->file->shared, tail); + } /* end if */ + } /* end if */ + } /* end for */ + + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_efc_try_close_tag1() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_efc_try_close_tag2 + * + * Purpose: Recuresively mark all files reachable through this one as + * uncloseable, and add newly uncloseable files to the tail + * of the provided linked list. + * + * Return: void (never fails) + * + * Programmer: Neil Fortner + * Monday, January 10, 2011 + * + *------------------------------------------------------------------------- + */ +static void +H5F_efc_try_close_tag2(H5F_file_t *sf, H5F_file_t **tail) +{ + H5F_efc_ent_t *ent = NULL; /* EFC entry */ + H5F_file_t *esf; /* Convenience pointer to ent->file->shared */ + + FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5F_efc_try_close_tag2) + + /* Sanity checks */ + HDassert(sf); + HDassert(sf->efc); + + /* Recurse into this file's cached files */ + for(ent = sf->efc->LRU_head; ent; ent = ent->LRU_next) { + esf = ent->file->shared; + + /* Only recurse if the file is tagged CLOSE or DEFAULT. If it is tagged + * DONTCLOSE, we have already visited this file *or* it will be the + * start point of another iteration. No files should be tagged with a + * nonegative value at this point. If it is tagged as DEFAULT, we must + * apply the same conditions as in cb1 above for recursion in order to + * make sure we do not go off into somewhere cb1 didn't touch. The + * root file should never be tagged DEFAULT here, so the reference check + * is still appropriate. */ + if((esf->efc) && ((esf->efc->tag == H5F_EFC_TAG_CLOSE) + || ((esf->efc->tag == H5F_EFC_TAG_DEFAULT) + && (esf->nrefs == esf->efc->nrefs) && !(ent->nopen)))) { + /* tag should always be CLOSE is nrefs > 1 or DEFAULT if nrefs == 1 + * here */ + HDassert(((esf->nrefs > 1) + && ((esf->efc->tag == H5F_EFC_TAG_CLOSE))) + || ((esf->nrefs == 1) + && (esf->efc->tag == H5F_EFC_TAG_DEFAULT))); + + /* If tag is set to DONTCLOSE, we have already visited this file + * *or* it will be the start point of another iteration so just + * continue */ + if(esf->efc->tag != H5F_EFC_TAG_DONTCLOSE) { + /* If tag is CLOSE, set to DONTCLOSE and add to the list of + * uncloseable files. */ + if(esf->efc->tag == H5F_EFC_TAG_CLOSE) { + esf->efc->tag = H5F_EFC_TAG_DONTCLOSE; + esf->efc->tmp_next = NULL; + (*tail)->efc->tmp_next = esf; + *tail = esf; + } /* end if */ + + /* Recurse into the entry */ + H5F_efc_try_close_tag2(esf, tail); + } /* end if */ + } /* end if */ + } /* end for */ + + FUNC_LEAVE_NOAPI_VOID +} /* end H5F_efc_try_close_tag2() */ + + +/*------------------------------------------------------------------------- + * Function: H5F_efc_try_close + * + * Purpose: Attempts to close the provided (shared) file by checking + * to see if the releasing the EFC would cause its reference + * count to drop to 0. Necessary to handle the case where + * chained EFCs form a cycle. Note that this function does + * not actually close the file (though it closes all children + * as appropriate), as that is left up to the calling + * function H5F_try_close(). + * + * Because H5F_try_close() has no way of telling if it is + * called recursively from within this function, this + * function serves as both the root of iteration and the + * "callback" for the final pass (the one where the files are + * actually closed). The code for the callback case is at + * the top of this function; luckily it only consists of a + * (possible) call to H5F_efc_release(). + * + * The algorithm basically consists of 3 passes over the EFC + * tree. The first pass assumes that every reachable file is + * closed, and keeps track of what the final reference count + * would be for every reachable file. The files are then + * tagged as either closeable or uncloseable based on whether + * this reference count drops to 0. + * + * The second pass initiates a traversal from each file + * marked as uncloseable in the first pass, and marks every + * file reachable from the initial uncloseable file as + * uncloseable. This eliminates files that were marked as + * closeable only because the first pass assumed that an + * uncloseable file would be closed. + * + * The final pass exploits the H5F_efc_release()-> + * H5F_efc_remove_ent()->H5F_try_close()->H5F_efc_try_close() + * calling chain to recursively close the tree, but only the + * files that are still marked as closeable. All files + * marked as closeable have their EFCs released, and will + * eventually be closed when their last parent EFC is + * released (the last part is guaranteed to be true by the + * first 2 passes). + * + * Return: Non-negative on success + * Negative on failure + * + * Programmer: Neil Fortner + * Thursday, January 6, 2011 + * + *------------------------------------------------------------------------- + */ +herr_t +H5F_efc_try_close(H5F_t *f) +{ + H5F_file_t *tail; /* Tail of linked list of found files. Head will be f->shared. */ + H5F_file_t *uncloseable_head = NULL; /* Head of linked list of files found to be uncloseable by the first pass */ + H5F_file_t *uncloseable_tail = NULL; /* Tail of linked list of files found to be uncloseable by the first pass */ + H5F_file_t *sf; /* Temporary file pointer */ + H5F_file_t *next; /* Temporary file pointer */ + herr_t ret_value = SUCCEED; /* Return value */ + + FUNC_ENTER_NOAPI_NOINIT(H5F_efc_try_close) + + /* Sanity checks */ + HDassert(f); + HDassert(f->shared); + HDassert(f->shared->efc); + HDassert(f->shared->nrefs > f->shared->efc->nrefs); + HDassert(f->shared->nrefs > 1); + HDassert(f->shared->efc->tag < 0); + + if(f->shared->efc->tag == H5F_EFC_TAG_CLOSE) { + /* We must have reentered this function, and we should close this file. + * In actuality, we just release the EFC, the recursion should + * eventually reduce this file's reference count to 1 (though possibly + * not from this call to H5F_efc_release()). */ + if(H5F_efc_release(f->shared->efc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") + + /* If we marked the file as closeable, there must be no open files in + * its EFC. This is because, in order to close an open child file, the + * client must keep a copy of the parent file open. The algorithm + * detect that the parent file is open (directly or through an EFC) and + * refuse to close it. Verify that all files were released from this + * EFC (i.e. none were open). */ + HDassert(f->shared->efc->nfiles == 0); + + HGOTO_DONE(SUCCEED) + } /* end if */ + + /* Conditions where we should not do anything and just return immediately */ + /* If there are references that are not from an EFC or f, it will never + * be possible to close the file. Just return. Note that this holds true + * for the case that this file is being closed through H5F_efc_release() + * because that function (through H5F_efc_remove_ent()) decrements the EFC + * reference count before it calls H5F_try_close(). This may occur if this + * function is reentered. */ + /* If the tag is H5F_EFC_TAG_DONTCLOSE, then we have definitely reentered + * this function, and this file has been marked as uncloseable, so we should + * not close/release it */ + /* If nfiles is 0, then there is nothing to do. Just return. This may also + * occur on reentry (for example if this file was previously released). */ + if((f->shared->nrefs != f->shared->efc->nrefs + 1) + || (f->shared->efc->tag == H5F_EFC_TAG_DONTCLOSE) + || (f->shared->efc->nfiles == 0)) + /* We must have reentered this function, and we should not close this + * file. Just return. */ + HGOTO_DONE(SUCCEED) + + /* If the file EFC were locked, that should always mean that there exists + * a reference to this file that is not in an EFC (it may have just been + * removed from an EFC), and should have been caught by the above check */ + /* If we get here then we must be beginning a new run. Make sure that the + * temporary variables in f->shared->efc are at the default value */ + HDassert(f->shared->efc->tag == H5F_EFC_TAG_DEFAULT); + HDassert(f->shared->efc->tmp_next == NULL); + + /* Set up linked list for traversal into EFC tree. f->shared is guaranteed + * to always be at the head. */ + tail = f->shared; + + /* Set up temporary reference count on root file */ + f->shared->efc->tag = (int)f->shared->efc->nrefs; + + /* First Pass: simulate closing all files reachable from this one, use "tag" + * field to keep track of final reference count for each file (including + * this one). Keep list of files with starting reference count > 1 (head is + * f->shared). */ + H5F_efc_try_close_tag1(f->shared, &tail); + + /* Check if f->shared->efc->tag dropped to 0. If it did not, + * we cannot close anything. Just reset temporary values and return. */ + if(f->shared->efc->tag > 0) { + sf = f->shared; + while(sf) { + next = sf->efc->tmp_next; + sf->efc->tag = H5F_EFC_TAG_DEFAULT; + sf->efc->tmp_next = NULL; + sf = next; + } /* end while */ + HGOTO_DONE(SUCCEED) + } /* end if */ + + /* Run through the linked list , separating into two lists, one with tag == + * 0 and one with tag > 0. Mark them as either H5F_EFC_TAG_CLOSE or + * H5F_EFC_TAG_DONTCLOSE as appropriate. */ + sf = f->shared; + tail = NULL; + while(sf) { + HDassert(sf->efc->tag >= 0); + next = sf->efc->tmp_next; + if(sf->efc->tag > 0) { + /* Remove from main list */ + HDassert(tail); + tail->efc->tmp_next = sf->efc->tmp_next; + sf->efc->tmp_next = NULL; + + /* Add to uncloseable list */ + if(!uncloseable_head) + uncloseable_head = sf; + else + uncloseable_tail->efc->tmp_next = sf; + uncloseable_tail = sf; + + /* Mark as uncloseable */ + sf->efc->tag = H5F_EFC_TAG_DONTCLOSE; + } /* end if */ + else { + sf->efc->tag = H5F_EFC_TAG_CLOSE; + tail = sf; + } /* end else */ + sf = next; + } /* end while */ + + /* Second pass: Determine which of the reachable files found in pass 1 + * cannot be closed by releasing the root file's EFC. Run through the + * uncloseable list, for each item traverse the files reachable through the + * EFC, mark the file as uncloseable, and add it to the list of uncloseable + * files (for cleanup). Use "tail" to store the original uncloseable tail + * so we know when to stop. We do not need to keep track of the closeable + * list any more. */ + sf = uncloseable_head; + if(sf) { + tail = uncloseable_tail; + HDassert(tail); + while(sf != tail->efc->tmp_next) { + H5F_efc_try_close_tag2(sf, &uncloseable_tail); + sf = sf->efc->tmp_next; + } /* end while */ + } /* end if */ + + /* If the root file's tag is still H5F_EFC_TAG_CLOSE, release its EFC. This + * should start the recursive release that should close all closeable files. + * Also, see the top of this function. */ + if(f->shared->efc->tag == H5F_EFC_TAG_CLOSE) { + if(H5F_efc_release(f->shared->efc) < 0) + HGOTO_ERROR(H5E_FILE, H5E_CANTRELEASE, FAIL, "can't release external file cache") + + /* Make sure the file's reference count is now 1 and will be closed by + * H5F_dest(). */ + HDassert(f->shared->nrefs == 1); + } /* end if */ + + /* Clean up uncloseable files (reset tag and tmp_next). All closeable files + * should have been closed, and therefore do not need to be cleaned up. */ + if(uncloseable_head) { + sf = uncloseable_head; + while(sf) { + next = sf->efc->tmp_next; + HDassert(sf->efc->tag == H5F_EFC_TAG_DONTCLOSE); + sf->efc->tag = H5F_EFC_TAG_DEFAULT; + sf->efc->tmp_next = NULL; + sf = next; + } /* end while */ + } /* end if */ + +done: + FUNC_LEAVE_NOAPI(ret_value) +} /* end H5F_efc_try_close() */ + diff --git a/src/H5Fio.c b/src/H5Fio.c index 2a456f1..a10fafc 100644 --- a/src/H5Fio.c +++ b/src/H5Fio.c @@ -102,6 +102,7 @@ H5F_block_read(const H5F_t *f, H5FD_mem_t type, haddr_t addr, size_t size, HDassert(f); HDassert(f->shared); HDassert(buf); + HDassert(H5F_addr_defined(addr)); /* Check for attempting I/O on 'temporary' file address */ if(H5F_addr_le(f->shared->tmp_addr, (addr + size))) @@ -146,6 +147,7 @@ HDfprintf(stderr, "%s: write to addr = %a, size = %Zu\n", FUNC, addr, size); HDassert(f->shared); HDassert(f->intent & H5F_ACC_RDWR); HDassert(buf); + HDassert(H5F_addr_defined(addr)); /* Check for attempting I/O on 'temporary' file address */ if(H5F_addr_le(f->shared->tmp_addr, (addr + size))) diff --git a/src/H5Fpkg.h b/src/H5Fpkg.h index 5bff8c6..74c9aa5 100644 --- a/src/H5Fpkg.h +++ b/src/H5Fpkg.h @@ -127,6 +127,10 @@ + H5F_SUPERBLOCK_VARLEN_SIZE(v, f)) +/* Forward declaration external file cache struct used below (defined in + * H5Fefc.c) */ +typedef struct H5F_efc_t H5F_efc_t; + /* Structure for metadata & "small [raw] data" block aggregation fields */ struct H5F_blk_aggr_t { unsigned long feature_flag; /* Feature flag type */ @@ -200,6 +204,7 @@ typedef struct H5F_file_t { unsigned nrefs; /* Ref count for times file is opened */ unsigned flags; /* Access Permissions for file */ H5F_mtab_t mtab; /* File mount table */ + H5F_efc_t *efc; /* External file cache */ /* Cached values from FCPL/superblock */ uint8_t sizeof_addr; /* Size of addresses in file */ @@ -328,6 +333,13 @@ H5_DLL herr_t H5F_sfile_add(H5F_file_t *shared); H5_DLL H5F_file_t * H5F_sfile_search(H5FD_t *lf); H5_DLL herr_t H5F_sfile_remove(H5F_file_t *shared); +/* External file cache routines */ +H5_DLL H5F_efc_t *H5F_efc_create(unsigned max_nfiles); +H5_DLL unsigned H5F_efc_max_nfiles(H5F_efc_t *efc); +H5_DLL herr_t H5F_efc_release(H5F_efc_t *efc); +H5_DLL herr_t H5F_efc_destroy(H5F_efc_t *efc); +H5_DLL herr_t H5F_efc_try_close(H5F_t *f); + /* Testing functions */ #ifdef H5F_TESTING H5_DLL herr_t H5F_get_sohm_mesg_count_test(hid_t fid, unsigned type_id, diff --git a/src/H5Fprivate.h b/src/H5Fprivate.h index a07e7ce..8ce9833 100644 --- a/src/H5Fprivate.h +++ b/src/H5Fprivate.h @@ -381,6 +381,7 @@ typedef struct H5F_blk_aggr_t H5F_blk_aggr_t; #define H5F_ACS_MULTI_TYPE_NAME "multi_type" /* Data type in multi file driver */ #define H5F_ACS_LATEST_FORMAT_NAME "latest_format" /* 'Use latest format version' flag */ #define H5F_ACS_WANT_POSIX_FD_NAME "want_posix_fd" /* Internal: query the file descriptor from the core VFD, instead of the memory address */ +#define H5F_ACS_EFC_SIZE_NAME "efc_size" /* Size of external file cache */ /* ======================== File Mount properties ====================*/ #define H5F_MNT_SYM_LOCAL_NAME "local" /* Whether absolute symlinks local to file. */ @@ -555,6 +556,11 @@ H5_DLL MPI_Comm H5F_mpi_get_comm(const H5F_t *f); H5_DLL int H5F_mpi_get_size(const H5F_t *f); #endif /* H5_HAVE_PARALLEL */ +/* External file cache routines */ +H5_DLL H5F_t *H5F_efc_open(H5F_t *parent, const char *name, unsigned flags, + hid_t fcpl_id, hid_t fapl_id, hid_t dxpl_id); +H5_DLL herr_t H5F_efc_close(H5F_t *parent, H5F_t *file); + /* Debugging functions */ H5_DLL herr_t H5F_debug(H5F_t *f, FILE * stream, int indent, int fwidth); diff --git a/src/H5Fpublic.h b/src/H5Fpublic.h index c9e83cc..6aca9e8 100644 --- a/src/H5Fpublic.h +++ b/src/H5Fpublic.h @@ -215,6 +215,7 @@ H5_DLL ssize_t H5Fget_name(hid_t obj_id, char *name, size_t size); H5_DLL herr_t H5Fget_info2(hid_t obj_id, H5F_info2_t *finfo); H5_DLL ssize_t H5Fget_free_sections(hid_t file_id, H5F_mem_t type, size_t nsects, H5F_sect_info_t *sect_info/*out*/); +H5_DLL herr_t H5Frelease_file_cache(hid_t file_id); /* Symbols defined for compatibility with previous versions of the HDF5 API. * diff --git a/src/H5Groot.c b/src/H5Groot.c index b8ba0fd..ff4a8c4 100644 --- a/src/H5Groot.c +++ b/src/H5Groot.c @@ -15,7 +15,7 @@ /*------------------------------------------------------------------------- * - * Created: H5Gobj.c + * Created: H5Groot.c * Apr 8 2009 * Neil Fortner <nfortne2@hdfgroup.org> * diff --git a/src/H5HGdbg.c b/src/H5HGdbg.c index 38b7047..f301701 100644 --- a/src/H5HGdbg.c +++ b/src/H5HGdbg.c @@ -106,6 +106,9 @@ H5HG_debug(H5F_t *f, hid_t dxpl_id, haddr_t addr, FILE *stream, int indent, if (h->obj[u].begin) { sprintf (buf, "Object %u", u); fprintf (stream, "%*s%s\n", indent, "", buf); + fprintf (stream, "%*s%-*s %lu\n", indent+3, "", MIN(fwidth-3, 0), + "Obffset in block:", + (unsigned long)(h->obj[u].begin - h->chunk)); fprintf (stream, "%*s%-*s %d\n", indent+3, "", MIN(fwidth-3, 0), "Reference count:", h->obj[u].nrefs); @@ -2414,8 +2414,8 @@ H5L_move_dest_cb(H5G_loc_t *grp_loc/*in*/, const char *name, H5G_own_loc_t *own_loc/*out*/) { H5L_trav_mv2_t *udata = (H5L_trav_mv2_t *)_udata; /* User data passed in */ - H5G_t *grp=NULL; /* H5G_t for this group, opened to pass to user callback */ - hid_t grp_id = FAIL; /* Id for this group (passed to user callback */ + H5G_t *grp = NULL; /* H5G_t for this group, opened to pass to user callback */ + hid_t grp_id = FAIL; /* ID for this group (passed to user callback */ H5G_loc_t temp_loc; /* For UD callback */ hbool_t temp_loc_init = FALSE; herr_t ret_value = SUCCEED; /* Return value */ @@ -2500,6 +2500,10 @@ done: * location for the object */ *own_loc = H5G_OWN_NONE; + /* Reset the "name" field in udata->lnk because it is owned by traverse() + * and must not be manipulated after traverse closes */ + udata->lnk->name = NULL; + FUNC_LEAVE_NOAPI(ret_value) } /* end H5L_move_dest_cb() */ @@ -2539,7 +2543,7 @@ H5L_move_cb(H5G_loc_t *grp_loc/*in*/, const char *name, const H5O_link_t *lnk, HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "the name of a link must be supplied to move or copy") /* Set up user data for move_dest_cb */ - if((udata_out.lnk = (H5O_link_t *)H5O_msg_copy(H5O_LINK_ID, lnk, NULL)) == NULL) + if(NULL == (udata_out.lnk = (H5O_link_t *)H5O_msg_copy(H5O_LINK_ID, lnk, NULL))) HGOTO_ERROR(H5E_LINK, H5E_CANTCOPY, FAIL, "unable to copy link to be moved") /* In this special case, the link's name is going to be replaced at its @@ -2600,16 +2604,11 @@ done: H5MM_xfree(orig_name); /* If udata_out.lnk was copied, free any memory allocated - * In this special case, the H5L_move_dest_cb callback frees the name - * if it succeeds + * In this special case, the H5L_move_dest_cb callback resets the name + * so H5O_msg_free shouldn't try to free it */ - if(link_copied) { - if(udata_out.lnk->type == H5L_TYPE_SOFT) - udata_out.lnk->u.soft.name = (char *)H5MM_xfree(udata_out.lnk->u.soft.name); - else if(udata_out.lnk->type >= H5L_TYPE_UD_MIN && udata_out.lnk->u.ud.size > 0) - udata_out.lnk->u.ud.udata = H5MM_xfree(udata_out.lnk->u.ud.udata); - H5MM_xfree(udata_out.lnk); - } /* end if */ + if(link_copied) + H5O_msg_free(H5O_LINK_ID, udata_out.lnk); /* Indicate that this callback didn't take ownership of the group * * location for the object */ diff --git a/src/H5Lexternal.c b/src/H5Lexternal.c index 9880897..9be21dd 100644 --- a/src/H5Lexternal.c +++ b/src/H5Lexternal.c @@ -188,6 +188,9 @@ done: * Otherwise, the file access property retrieved from H5Pget_elink_fapl() * is used to H5F_open() the target file. * + * Vailin Choi; Nov 2010 + * Free memory pointed to by tmp_env_prefix for HDF5_EXT_PREFIX case. + * *------------------------------------------------------------------------- */ static hid_t @@ -319,7 +322,7 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, /* target file_name is an absolute pathname: see RM for detailed description */ if(CHECK_ABSOLUTE(file_name) || CHECK_ABS_PATH(file_name)) { /* Try opening file */ - if(NULL == (ext_file = H5F_open(file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) { + if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) { char *ptr = NULL; H5E_clear_stack(NULL); @@ -331,7 +334,7 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, } /* end if */ } /* end if */ else if(CHECK_ABS_DRIVE(file_name)) { - if(NULL == (ext_file = H5F_open(file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) { + if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) { H5E_clear_stack(NULL); /* strip "<drive-letter>:" */ HDstrcpy(temp_file_name, &file_name[2]); @@ -343,9 +346,9 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, char *env_prefix; if(NULL != (env_prefix = HDgetenv("HDF5_EXT_PREFIX"))) { - char *tmp_env_prefix; + char *tmp_env_prefix, *saved_env; - if(NULL == (tmp_env_prefix = H5MM_strdup(env_prefix))) + if(NULL == (saved_env = tmp_env_prefix = H5MM_strdup(env_prefix))) HGOTO_ERROR(H5E_LINK, H5E_NOSPACE, FAIL, "memory allocation failed") while((tmp_env_prefix) && (*tmp_env_prefix)) { @@ -353,16 +356,19 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, out_prefix_name = H5L_getenv_prefix_name(&tmp_env_prefix/*in,out*/); if(out_prefix_name && (*out_prefix_name)) { - if(H5L_build_name(out_prefix_name, temp_file_name, &full_name/*out*/) < 0) + if(H5L_build_name(out_prefix_name, temp_file_name, &full_name/*out*/) < 0) { + saved_env = (char *)H5MM_xfree(saved_env); HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename") + } /* end if */ - ext_file = H5F_open(full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id); + ext_file = H5F_efc_open(loc.oloc->file, full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id); full_name = (char *)H5MM_xfree(full_name); if(ext_file != NULL) break; H5E_clear_stack(NULL); } /* end if */ } /* end while */ + saved_env = (char *)H5MM_xfree(saved_env); } /* end if */ } /* end if */ @@ -373,7 +379,7 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, if(my_prefix) { if(H5L_build_name(my_prefix, temp_file_name, &full_name/*out*/) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename") - if(NULL == (ext_file = H5F_open(full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) + if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) H5E_clear_stack(NULL); full_name = (char *)H5MM_xfree(full_name); } /* end if */ @@ -386,7 +392,7 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, if(NULL != (extpath = H5F_EXTPATH(loc.oloc->file))) { if(H5L_build_name(extpath, temp_file_name, &full_name/*out*/) < 0) HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename") - if(NULL == (ext_file = H5F_open(full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) + if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) H5E_clear_stack(NULL); full_name = (char *)H5MM_xfree(full_name); } /* end if */ @@ -394,7 +400,7 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, /* try the relative file_name stored in temp_file_name */ if(ext_file == NULL) { - if(NULL == (ext_file = H5F_open(temp_file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) + if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, temp_file_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) H5E_clear_stack(NULL); } /* end if */ @@ -421,32 +427,19 @@ H5L_extern_traverse(const char UNUSED *link_name, hid_t cur_group, HGOTO_ERROR(H5E_LINK, H5E_CANTGET, FAIL, "can't prepend prefix to filename") /* Try opening with the resolved name */ - if(NULL == (ext_file = H5F_open(full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) + if(NULL == (ext_file = H5F_efc_open(loc.oloc->file, full_name, intent, H5P_FILE_CREATE_DEFAULT, fapl_id, H5AC_dxpl_id))) HGOTO_ERROR(H5E_LINK, H5E_CANTOPENFILE, FAIL, "unable to open external file, external link file name = '%s', temp_file_name = '%s'", file_name, temp_file_name) full_name = (char *)H5MM_xfree(full_name); } /* end if */ - /* Increment the number of open objects, to hold the file open */ - H5F_incr_nopen_objs(ext_file); - /* Retrieve the "group location" for the file's root group */ if(H5G_loc_root(ext_file, &root_loc) < 0) HGOTO_ERROR(H5E_SYM, H5E_BADVALUE, FAIL, "unable to create location for file") /* Open the object referenced in the external file */ - if((ext_obj = H5O_open_name(&root_loc, obj_name, lapl_id, FALSE)) < 0) { - H5F_decr_nopen_objs(ext_file); + if((ext_obj = H5O_open_name(&root_loc, obj_name, lapl_id, FALSE)) < 0) HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open object") - } /* end if */ - - /* Decrement the number of open objects, to let the file close */ - H5F_decr_nopen_objs(ext_file); - - /* Close the external file */ - if(H5F_try_close(ext_file) < 0) - HGOTO_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, FAIL, "problem closing external file") - ext_file = NULL; /* Set return value */ ret_value = ext_obj; @@ -455,7 +448,7 @@ done: /* Release resources */ if(fapl_id > 0 && H5I_dec_ref(fapl_id) < 0) HDONE_ERROR(H5E_ATOM, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list") - if(ext_file && H5F_try_close(ext_file) < 0) + if(ext_file && H5F_efc_close(loc.oloc->file, ext_file) < 0) HDONE_ERROR(H5E_LINK, H5E_CANTCLOSEFILE, FAIL, "problem closing external file") if(parent_group_name && parent_group_name != local_group_name) parent_group_name = (char *)H5MM_xfree(parent_group_name); @@ -1663,7 +1663,10 @@ H5O_protect(const H5O_loc_t *loc, hid_t dxpl_id, H5AC_protect_t prot) /* check args */ HDassert(loc); HDassert(loc->file); - HDassert(H5F_addr_defined(loc->addr)); + + /* Check for valid address */ + if(!H5F_addr_defined(loc->addr)) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, NULL, "address undefined") /* Check for write access on the file */ file_intent = H5F_INTENT(loc->file); diff --git a/src/H5Oattribute.c b/src/H5Oattribute.c index f155c94..4a19ed4 100644 --- a/src/H5Oattribute.c +++ b/src/H5Oattribute.c @@ -472,9 +472,10 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) { H5O_t *oh = NULL; /* Pointer to actual object header */ H5O_ainfo_t ainfo; /* Attribute information for object */ - H5A_t *ret_value; /* Return value */ - H5A_t *exist_attr = NULL; /* Opened attribute object */ + H5A_t *exist_attr = NULL; /* Existing opened attribute object */ + H5A_t *opened_attr = NULL; /* Newly opened attribute object */ htri_t found_open_attr = FALSE; /* Whether opened object is found */ + H5A_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT_TAG(H5O_attr_open_by_name, dxpl_id, loc->addr, NULL) @@ -500,14 +501,14 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, name)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "failed in finding opened attribute") else if(found_open_attr == TRUE) { - if(NULL == (ret_value = H5A_copy(NULL, exist_attr))) + if(NULL == (opened_attr = H5A_copy(NULL, exist_attr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy existing attribute") } /* end else if */ else { /* Check for attributes in dense storage */ if(H5F_addr_defined(ainfo.fheap_addr)) { /* Open attribute with dense storage */ - if(NULL == (ret_value = H5A_dense_open(loc->file, dxpl_id, &ainfo, name))) + if(NULL == (opened_attr = H5A_dense_open(loc->file, dxpl_id, &ainfo, name))) HGOTO_ERROR(H5E_ATTR, H5E_CANTOPENOBJ, NULL, "can't open attribute") } /* end if */ else { @@ -530,19 +531,26 @@ H5O_attr_open_by_name(const H5O_loc_t *loc, const char *name, hid_t dxpl_id) /* Get attribute opened from object header */ HDassert(udata.attr); - ret_value = udata.attr; + opened_attr = udata.attr; } /* end else */ /* Mark datatype as being on disk now */ - if(H5T_set_loc(ret_value->shared->dt, loc->file, H5T_LOC_DISK) < 0) + if(H5T_set_loc(opened_attr->shared->dt, loc->file, H5T_LOC_DISK) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "invalid datatype location") - } /* end else */ + /* Set return value */ + ret_value = opened_attr; + done: if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, NULL, "unable to release object header") + /* Release any resources, on error */ + if(NULL == ret_value && opened_attr) + if(H5A_close(opened_attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, NULL, "can't close attribute") + FUNC_LEAVE_NOAPI_TAG(ret_value, NULL) } /* end H5O_attr_open_by_name() */ @@ -606,9 +614,10 @@ H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, { H5O_t *oh = NULL; /* Object header */ H5A_attr_iter_op_t attr_op; /* Attribute operator */ - H5A_t *exist_attr = NULL; /* Opened attribute object */ + H5A_t *exist_attr = NULL; /* Existing opened attribute object */ + H5A_t *opened_attr = NULL; /* Newly opened attribute object */ htri_t found_open_attr = FALSE; /* Whether opened object is found */ - H5A_t *ret_value = NULL; /* Return value */ + H5A_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5O_attr_open_by_idx) @@ -620,7 +629,7 @@ H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, attr_op.u.lib_op = H5O_attr_open_by_idx_cb; /* Iterate over attributes to locate correct one */ - if(H5O_attr_iterate_real((hid_t)-1, loc, dxpl_id, idx_type, order, n, NULL, &attr_op, &ret_value) < 0) + if(H5O_attr_iterate_real((hid_t)-1, loc, dxpl_id, idx_type, order, n, NULL, &attr_op, &opened_attr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_BADITER, NULL, "can't locate attribute") /* Protect the object header to iterate over */ @@ -630,29 +639,37 @@ H5O_attr_open_by_idx(const H5O_loc_t *loc, H5_index_t idx_type, /* Find out whether it has already been opened. If it has, close the object * and make a copy of the already opened object to share the object info. */ - if(ret_value) { - if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, ret_value->shared->name)) < 0) + if(opened_attr) { + if((found_open_attr = H5O_attr_find_opened_attr(loc, &exist_attr, opened_attr->shared->name)) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTGET, NULL, "failed in finding opened attribute") /* If found that the attribute is already opened, make a copy of it * and close the object just opened. */ if(found_open_attr && exist_attr) { - if(H5A_close(ret_value) < 0) + if(H5A_close(opened_attr) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, NULL, "can't close attribute") - if(NULL == (ret_value = H5A_copy(NULL, exist_attr))) + if(NULL == (opened_attr = H5A_copy(NULL, exist_attr))) HGOTO_ERROR(H5E_ATTR, H5E_CANTCOPY, NULL, "can't copy existing attribute") } else { /* Mark datatype as being on disk now */ - if(H5T_set_loc(ret_value->shared->dt, loc->file, H5T_LOC_DISK) < 0) + if(H5T_set_loc(opened_attr->shared->dt, loc->file, H5T_LOC_DISK) < 0) HGOTO_ERROR(H5E_ATTR, H5E_CANTINIT, NULL, "invalid datatype location") } /* end if */ } /* end if */ + /* Set return value */ + ret_value = opened_attr; + done: if(oh && H5O_unprotect(loc, dxpl_id, oh, H5AC__NO_FLAGS_SET) < 0) HDONE_ERROR(H5E_ATTR, H5E_CANTUNPROTECT, NULL, "unable to release object header") + /* Release any resources, on error */ + if(NULL == ret_value && opened_attr) + if(H5A_close(opened_attr) < 0) + HDONE_ERROR(H5E_ATTR, H5E_CANTCLOSEOBJ, NULL, "can't close attribute") + FUNC_LEAVE_NOAPI(ret_value) } /* end H5O_attr_open_by_idx() */ diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 10922da..7dea0b2 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -119,6 +119,9 @@ */ #define H5F_ACS_WANT_POSIX_FD_SIZE sizeof(hbool_t) #define H5F_ACS_WANT_POSIX_FD_DEF FALSE +/* Definition for external file cache size */ +#define H5F_ACS_EFC_SIZE_SIZE sizeof(unsigned) +#define H5F_ACS_EFC_SIZE_DEF 0 /******************/ @@ -211,6 +214,7 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass) H5FD_mem_t mem_type = H5F_ACS_MULTI_TYPE_DEF; /* Default file space type for multi VFD */ hbool_t latest_format = H5F_ACS_LATEST_FORMAT_DEF; /* Default setting for "use the latest version of the format" flag */ hbool_t want_posix_fd = H5F_ACS_WANT_POSIX_FD_DEF; /* Default setting for retrieving 'handle' from core VFD */ + unsigned efc_size = H5F_ACS_EFC_SIZE_DEF; /* Default external file cache size */ herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5P_facc_reg_prop) @@ -292,6 +296,10 @@ H5P_facc_reg_prop(H5P_genclass_t *pclass) if(H5P_register_real(pclass, H5F_ACS_WANT_POSIX_FD_NAME, H5F_ACS_WANT_POSIX_FD_SIZE, &want_posix_fd, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + /* Register the external file cache size */ + if(H5P_register_real(pclass, H5F_ACS_EFC_SIZE_NAME, H5F_ACS_EFC_SIZE_SIZE, &efc_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class") + done: FUNC_LEAVE_NOAPI(ret_value) } /* end H5P_facc_reg_prop() */ @@ -2016,3 +2024,80 @@ done: FUNC_LEAVE_API(ret_value) } /* end H5Pget_libver_bounds() */ + +/*------------------------------------------------------------------------- + * Function: H5Pset_elink_file_cache_size + * + * Purpose: Sets the number of files opened through external links + * from the file associated with this fapl to be held open + * in that file's external file cache. When the maximum + * number of files is reached, the least recently used file + * is closed (unless it is opened from somewhere else). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Friday, December 17, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pset_elink_file_cache_size(hid_t plist_id, unsigned efc_size) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pset_elink_file_cache_size, FAIL) + H5TRACE2("e", "iIu", plist_id, efc_size); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Set value */ + if(H5P_set(plist, H5F_ACS_EFC_SIZE_NAME, &efc_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set elink file cache size") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pset_elink_file_cache_size() */ + + +/*------------------------------------------------------------------------- + * Function: H5Pget_elink_file_cache_size + * + * Purpose: Gets the number of files opened through external links + * from the file associated with this fapl to be held open + * in that file's external file cache. When the maximum + * number of files is reached, the least recently used file + * is closed (unless it is opened from somewhere else). + * + * Return: Non-negative on success/Negative on failure + * + * Programmer: Neil Fortner + * Friday, December 17, 2010 + * + *------------------------------------------------------------------------- + */ +herr_t +H5Pget_elink_file_cache_size(hid_t plist_id, unsigned *efc_size) +{ + H5P_genplist_t *plist; /* Property list pointer */ + herr_t ret_value = SUCCEED; /* return value */ + + FUNC_ENTER_API(H5Pget_elink_file_cache_size, FAIL) + H5TRACE2("e", "i*Iu", plist_id, efc_size); + + /* Get the plist structure */ + if(NULL == (plist = H5P_object_verify(plist_id, H5P_FILE_ACCESS))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID") + + /* Get value */ + if(efc_size) + if(H5P_get(plist, H5F_ACS_EFC_SIZE_NAME, efc_size) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get elink file cache size") + +done: + FUNC_LEAVE_API(ret_value) +} /* end H5Pget_elink_file_cache_size() */ + diff --git a/src/H5Ppublic.h b/src/H5Ppublic.h index acdac96..ba6106e 100644 --- a/src/H5Ppublic.h +++ b/src/H5Ppublic.h @@ -287,6 +287,8 @@ H5_DLL herr_t H5Pset_libver_bounds(hid_t plist_id, H5F_libver_t low, H5F_libver_t high); H5_DLL herr_t H5Pget_libver_bounds(hid_t plist_id, H5F_libver_t *low, H5F_libver_t *high); +H5_DLL herr_t H5Pset_elink_file_cache_size(hid_t plist_id, unsigned efc_size); +H5_DLL herr_t H5Pget_elink_file_cache_size(hid_t plist_id, unsigned *efc_size); /* Dataset creation property list (DCPL) routines */ H5_DLL herr_t H5Pset_layout(hid_t plist_id, H5D_layout_t layout); diff --git a/src/H5Smpio.c b/src/H5Smpio.c index e9d0541..d6131b9 100644 --- a/src/H5Smpio.c +++ b/src/H5Smpio.c @@ -35,6 +35,7 @@ #include "H5Oprivate.h" /* Object headers */ #include "H5Pprivate.h" /* Property lists */ #include "H5Spkg.h" /* Dataspaces */ +#include "H5Vprivate.h" /* Vector and array functions */ #ifdef H5_HAVE_PARALLEL @@ -83,7 +84,7 @@ H5S_mpio_all_type(const H5S_t *space, size_t elmt_size, HDassert(space); /* Just treat the entire extent as a block of bytes */ - if((snelmts = H5S_GET_EXTENT_NPOINTS(space)) < 0) + if((snelmts = (hssize_t)H5S_GET_EXTENT_NPOINTS(space)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "src dataspace has invalid selection") H5_ASSIGN_OVERFLOW(nelmts, snelmts, hssize_t, hsize_t); @@ -160,14 +161,15 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, hsize_t count; } d[H5S_MAX_RANK]; - int i; - int offset[H5S_MAX_RANK]; - int max_xtent[H5S_MAX_RANK]; + hsize_t offset[H5S_MAX_RANK]; + hsize_t max_xtent[H5S_MAX_RANK]; H5S_hyper_dim_t *diminfo; /* [rank] */ - int rank; + unsigned rank; int block_length[3]; MPI_Datatype inner_type, outer_type, old_types[3]; MPI_Aint extent_len, displacement[3]; + unsigned u; /* Local index variable */ + int i; /* Local index variable */ int mpi_code; /* MPI return code */ herr_t ret_value = SUCCEED; @@ -192,66 +194,68 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, if(sel_iter.u.hyp.iter_rank != 0 && sel_iter.u.hyp.iter_rank < space->extent.rank) { /* Flattened selection */ rank = sel_iter.u.hyp.iter_rank; - HDassert(rank >= 0 && rank <= H5S_MAX_RANK); /* within array bounds */ + HDassert(rank <= H5S_MAX_RANK); /* within array bounds */ #ifdef H5S_DEBUG if(H5DEBUG(S)) HDfprintf(H5DEBUG(S), "%s: Flattened selection\n",FUNC); #endif - for(i = 0; i < rank; ++i) { - d[i].start = diminfo[i].start + sel_iter.u.hyp.sel_off[i]; - d[i].strid = diminfo[i].stride; - d[i].block = diminfo[i].block; - d[i].count = diminfo[i].count; - d[i].xtent = sel_iter.u.hyp.size[i]; + for(u = 0; u < rank; ++u) { + H5_CHECK_OVERFLOW(diminfo[u].start, hsize_t, hssize_t) + d[u].start = (hssize_t)diminfo[u].start + sel_iter.u.hyp.sel_off[u]; + d[u].strid = diminfo[u].stride; + d[u].block = diminfo[u].block; + d[u].count = diminfo[u].count; + d[u].xtent = sel_iter.u.hyp.size[u]; #ifdef H5S_DEBUG if(H5DEBUG(S)){ HDfprintf(H5DEBUG(S), "%s: start=%Hd stride=%Hu count=%Hu block=%Hu xtent=%Hu", - FUNC, d[i].start, d[i].strid, d[i].count, d[i].block, d[i].xtent ); - if (i==0) - HDfprintf(H5DEBUG(S), " rank=%d\n", rank ); + FUNC, d[u].start, d[u].strid, d[u].count, d[u].block, d[u].xtent ); + if (u==0) + HDfprintf(H5DEBUG(S), " rank=%u\n", rank ); else HDfprintf(H5DEBUG(S), "\n" ); } #endif - if(0 == d[i].block) + if(0 == d[u].block) goto empty; - if(0 == d[i].count) + if(0 == d[u].count) goto empty; - if(0 == d[i].xtent) + if(0 == d[u].xtent) goto empty; } /* end for */ } /* end if */ else { /* Non-flattened selection */ rank = space->extent.rank; - HDassert(rank >= 0 && rank <= H5S_MAX_RANK); /* within array bounds */ + HDassert(rank <= H5S_MAX_RANK); /* within array bounds */ if(0 == rank) goto empty; #ifdef H5S_DEBUG if(H5DEBUG(S)) HDfprintf(H5DEBUG(S),"%s: Non-flattened selection\n",FUNC); #endif - for(i = 0; i < rank; ++i) { - d[i].start = diminfo[i].start + space->select.offset[i]; - d[i].strid = diminfo[i].stride; - d[i].block = diminfo[i].block; - d[i].count = diminfo[i].count; - d[i].xtent = space->extent.size[i]; + for(u = 0; u < rank; ++u) { + H5_CHECK_OVERFLOW(diminfo[u].start, hsize_t, hssize_t) + d[u].start = (hssize_t)diminfo[u].start + space->select.offset[u]; + d[u].strid = diminfo[u].stride; + d[u].block = diminfo[u].block; + d[u].count = diminfo[u].count; + d[u].xtent = space->extent.size[u]; #ifdef H5S_DEBUG if(H5DEBUG(S)){ HDfprintf(H5DEBUG(S), "%s: start=%Hd stride=%Hu count=%Hu block=%Hu xtent=%Hu", - FUNC, d[i].start, d[i].strid, d[i].count, d[i].block, d[i].xtent ); - if (i==0) - HDfprintf(H5DEBUG(S), " rank=%d\n", rank ); + FUNC, d[u].start, d[u].strid, d[u].count, d[u].block, d[u].xtent ); + if (u==0) + HDfprintf(H5DEBUG(S), " rank=%u\n", rank ); else HDfprintf(H5DEBUG(S), "\n" ); } #endif - if(0 == d[i].block) + if(0 == d[u].block) goto empty; - if(0 == d[i].count) + if(0 == d[u].count) goto empty; - if(0 == d[i].xtent) + if(0 == d[u].xtent) goto empty; } /* end for */ } /* end else */ @@ -264,17 +268,17 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, max_xtent[rank - 1] = d[rank - 1].xtent; #ifdef H5S_DEBUG if(H5DEBUG(S)) { - i=rank-1; - HDfprintf(H5DEBUG(S), " offset[%2d]=%d; max_xtent[%2d]=%d\n", + i = ((int)rank) - 1; + HDfprintf(H5DEBUG(S), " offset[%2d]=%Hu; max_xtent[%2d]=%Hu\n", i, offset[i], i, max_xtent[i]); } #endif - for(i = rank - 2; i >= 0; --i) { + for(i = ((int)rank) - 2; i >= 0; --i) { offset[i] = offset[i + 1] * d[i + 1].xtent; max_xtent[i] = max_xtent[i + 1] * d[i].xtent; #ifdef H5S_DEBUG if(H5DEBUG(S)) - HDfprintf(H5DEBUG(S), " offset[%2d]=%d; max_xtent[%2d]=%d\n", + HDfprintf(H5DEBUG(S), " offset[%2d]=%Hu; max_xtent[%2d]=%Hu\n", i, offset[i], i, max_xtent[i]); #endif } /* end for */ @@ -290,7 +294,7 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, #ifdef H5S_DEBUG if(H5DEBUG(S)) { HDfprintf(H5DEBUG(S), "%s: Making contig type %Zu MPI_BYTEs\n", FUNC, elmt_size); - for (i=rank-1; i>=0; --i) + for(i = ((int)rank) - 1; i >= 0; --i) HDfprintf(H5DEBUG(S), "d[%d].xtent=%Hu \n", i, d[i].xtent); } #endif @@ -301,7 +305,7 @@ H5S_mpio_hyper_type(const H5S_t *space, size_t elmt_size, * Construct the type by walking the hyperslab dims * from the inside out: *******************************************************/ - for(i = rank - 1; i >= 0; --i) { + for(i = ((int)rank) - 1; i >= 0; --i) { #ifdef H5S_DEBUG if(H5DEBUG(S)) HDfprintf(H5DEBUG(S), "%s: Dimension i=%d \n" @@ -538,7 +542,8 @@ H5S_obtain_datatype(const hsize_t *down, H5S_hyper_span_t *span, /* Store displacement & block length */ disp[outercount] = (MPI_Aint)elmt_size * tspan->low; - blocklen[outercount] = tspan->nelem; + H5_CHECK_OVERFLOW(tspan->nelem, hsize_t, int) + blocklen[outercount] = (int)tspan->nelem; tspan = tspan->next; outercount++; @@ -710,12 +715,15 @@ H5S_mpio_space_type(const H5S_t *space, size_t elmt_size, } /* end else */ break; + case H5S_SEL_ERROR: + case H5S_SEL_N: default: HDassert("unknown selection type" && 0); break; } /* end switch */ break; + case H5S_NO_CLASS: default: HDassert("unknown data space type" && 0); break; @@ -2807,6 +2807,11 @@ done: * slu@ncsa.uiuc.edu * July 14, 2004 * + * Modification:Raymond Lu + * songyulu@hdfgroup.org + * 17 February 2011 + * I changed the value for the APP_REF parameter of H5I_register + * from FALSE to TRUE. *------------------------------------------------------------------------- */ hid_t @@ -2827,7 +2832,7 @@ H5Tdecode(const void *buf) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTDECODE, FAIL, "can't decode object") /* Register the type and return the ID */ - if((ret_value = H5I_register(H5I_DATATYPE, dt, FALSE)) < 0) + if((ret_value = H5I_register(H5I_DATATYPE, dt, TRUE)) < 0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL, "unable to register data type") done: diff --git a/src/H5Tconv.c b/src/H5Tconv.c index 9d98e50..927a9dc 100644 --- a/src/H5Tconv.c +++ b/src/H5Tconv.c @@ -662,17 +662,16 @@ CI_INC_DST(d_mv) \ \ /* Get the plist structure */ \ - if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) \ - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); \ + if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) \ + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID") \ \ /* Get conversion exception callback property */ \ - if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0) \ - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); \ + if(H5P_get(plist, H5D_XFER_CONV_CB_NAME, &cb_struct) < 0) \ + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") \ \ /* Get source and destination datatypes */ \ - if (NULL==(st=(H5T_t*)H5I_object(src_id)) || NULL==(dt=(H5T_t*)H5I_object(dst_id))) \ - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, \ - "unable to dereference datatype object ID") \ + if(NULL == (st = (H5T_t *)H5I_object(src_id)) || NULL == (dt = (H5T_t *)H5I_object(dst_id))) \ + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to dereference datatype object ID") \ \ /* Get source & destination precisions into a variable */ \ tclass = st->shared->type; \ @@ -1041,9 +1040,8 @@ H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, switch(cdata->command) { case H5T_CONV_INIT: /* Capability query */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset) @@ -1055,7 +1053,7 @@ H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, !((H5T_ORDER_BE == src->shared->u.atomic.order && H5T_ORDER_LE == dst->shared->u.atomic.order) || (H5T_ORDER_LE == src->shared->u.atomic.order && H5T_ORDER_BE == dst->shared->u.atomic.order))) HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported") - if (src->shared->size != 1 && src->shared->size != 2 && src->shared->size != 4 && + if(src->shared->size != 1 && src->shared->size != 2 && src->shared->size != 4 && src->shared->size != 8 && src->shared->size != 16) HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "conversion not supported") switch(src->shared->type) { @@ -1085,14 +1083,14 @@ H5T_conv_order_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, case H5T_CONV_CONV: /* The conversion */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* Check for "no op" reference conversion */ if(src->shared->type == H5T_REFERENCE) { /* Sanity check */ - HDassert(dst->shared->type == H5T_REFERENCE); + if(dst->shared->type != H5T_REFERENCE) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_REFERENCE datatype") /* Check if we are on a little-endian machine (the order that * the addresses in the file must be) and just get out now, there @@ -1452,7 +1450,7 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* Capability query */ if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(src->shared->size != dst->shared->size || 0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset || !((H5T_ORDER_BE == src->shared->u.atomic.order && @@ -1487,9 +1485,8 @@ H5T_conv_order(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* The conversion */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") + if(NULL == (src = (H5T_t *)H5I_object(src_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") buf_stride = buf_stride ? buf_stride : src->shared->size; md = src->shared->size / 2; @@ -1535,7 +1532,7 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void UNUSED *background, hid_t dxpl_id) { uint8_t *buf = (uint8_t*)_buf; - H5T_t *src = NULL, *dst = NULL; /*source and dest data types */ + H5T_t *src = NULL, *dst = NULL; /*source and dest datatypes */ int direction; /*direction of traversal */ size_t elmtno; /*element number */ size_t olap; /*num overlapping elements */ @@ -1558,7 +1555,7 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* Capability query */ if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") if(H5T_ORDER_LE != src->shared->u.atomic.order && H5T_ORDER_BE != src->shared->u.atomic.order) HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") @@ -1572,10 +1569,9 @@ H5T_conv_b_b(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; case H5T_CONV_CONV: - /* Get the data types */ - if(NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type") + /* Get the datatypes */ + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* * Do we process the values from beginning to end or vice versa? Also, @@ -1777,24 +1773,26 @@ H5T_conv_struct_free(H5T_conv_struct_t *priv) hid_t *src_memb_id = priv->src_memb_id, *dst_memb_id = priv->dst_memb_id; unsigned i; - int status; FUNC_ENTER_NOAPI_NOINIT_NOFUNC(H5T_conv_struct_free) - for (i=0; i<priv->src_nmembs; i++) - if (src2dst[i] >= 0) { + for(i = 0; i < priv->src_nmembs; i++) + if(src2dst[i] >= 0) { + int status; + status = H5I_dec_ref(src_memb_id[i]); HDassert(status >= 0); status = H5I_dec_ref(dst_memb_id[src2dst[i]]); HDassert(status >= 0); - } + } /* end if */ H5MM_xfree(src2dst); H5MM_xfree(src_memb_id); H5MM_xfree(dst_memb_id); H5MM_xfree(priv->memb_path); - FUNC_LEAVE_NOAPI((H5T_conv_struct_t *)H5MM_xfree(priv)); -} + + FUNC_LEAVE_NOAPI((H5T_conv_struct_t *)H5MM_xfree(priv)) +} /* end H5T_conv_struct_free() */ /*------------------------------------------------------------------------- @@ -1852,9 +1850,7 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) int *src2dst = NULL; unsigned src_nmembs, dst_nmembs; unsigned i, j; - H5T_t *type = NULL; - hid_t tid; - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5T_conv_struct_init) @@ -1900,9 +1896,12 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) } /* end if */ } /* end for */ if(src2dst[i] >= 0) { + hid_t tid; + H5T_t *type; + type = H5T_copy(src->shared->u.compnd.memb[i].type, H5T_COPY_ALL); tid = H5I_register(H5I_DATATYPE, type, FALSE); - HDassert(tid>=0); + HDassert(tid >= 0); priv->src_memb_id[i] = tid; type = H5T_copy(dst->shared->u.compnd.memb[src2dst[i]].type, H5T_COPY_ALL); @@ -1933,7 +1932,7 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) H5T_path_t *tpath = H5T_path_find(src->shared->u.compnd.memb[i].type, dst->shared->u.compnd.memb[src2dst[i]].type, NULL, NULL, dxpl_id, FALSE); if(NULL == (priv->memb_path[i] = tpath)) { - cdata->priv = priv = H5T_conv_struct_free(priv); + cdata->priv = H5T_conv_struct_free(priv); HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unable to convert member datatype") } /* end if */ } /* end if */ @@ -1959,8 +1958,8 @@ H5T_conv_struct_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata, hid_t dxpl_id) * the end of src. */ if(priv->subset_info.subset == H5T_SUBSET_SRC) - priv->subset_info.copy_size = src->shared->u.compnd.memb[src_nmembs-1].offset - + src->shared->u.compnd.memb[src_nmembs-1].size; + priv->subset_info.copy_size = src->shared->u.compnd.memb[src_nmembs - 1].offset + + src->shared->u.compnd.memb[src_nmembs - 1].size; } else if(dst_nmembs < src_nmembs) { priv->subset_info.subset = H5T_SUBSET_DST; for(i = 0; i < dst_nmembs; i++) { @@ -2075,23 +2074,23 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, { uint8_t *buf = (uint8_t *)_buf; /*cast for pointer arithmetic */ uint8_t *bkg = (uint8_t *)_bkg; /*background pointer arithmetic */ - uint8_t *xbuf=buf, *xbkg=bkg; /*temp pointers into buf and bkg*/ + uint8_t *xbuf = buf, *xbkg = bkg; /*temp pointers into buf and bkg*/ H5T_t *src = NULL; /*source datatype */ H5T_t *dst = NULL; /*destination datatype */ int *src2dst = NULL; /*maps src member to dst member */ H5T_cmemb_t *src_memb = NULL; /*source struct member descript.*/ H5T_cmemb_t *dst_memb = NULL; /*destination struct memb desc. */ size_t offset; /*byte offset wrt struct */ - size_t src_delta; /*source stride */ + size_t src_delta; /*source stride */ size_t elmtno; - unsigned u; /*counters */ - int i; /*counters */ + unsigned u; /*counters */ + int i; /*counters */ H5T_conv_struct_t *priv = (H5T_conv_struct_t *)(cdata->priv); - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5T_conv_struct, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: /* * First, determine if this conversion function applies to the @@ -2099,35 +2098,35 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * otherwise initialize the `priv' field of `cdata' with information * that remains (almost) constant for this conversion path. */ - if (NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - assert (H5T_COMPOUND==src->shared->type); - assert (H5T_COMPOUND==dst->shared->type); + if (NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") + if(H5T_COMPOUND != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype") + if(H5T_COMPOUND != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype") - if (H5T_conv_struct_init (src, dst, cdata, dxpl_id)<0) - HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); + if(H5T_conv_struct_init(src, dst, cdata, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data") break; case H5T_CONV_FREE: /* * Free the private conversion data. */ - cdata->priv = priv = H5T_conv_struct_free(priv); + cdata->priv = H5T_conv_struct_free(priv); break; case H5T_CONV_CONV: /* * Conversion. */ - if (NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - assert (priv); - assert (bkg && cdata->need_bkg); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") + HDassert(priv); + HDassert(bkg && cdata->need_bkg); - if (cdata->recalc && H5T_conv_struct_init (src, dst, cdata, dxpl_id)<0) - HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data"); + if(cdata->recalc && H5T_conv_struct_init(src, dst, cdata, dxpl_id) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data") /* * Insure that members are sorted. @@ -2139,7 +2138,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* * Direction of conversion and striding through background. */ - if (buf_stride) { + if(buf_stride) { src_delta = buf_stride; if(!bkg_stride) bkg_stride = dst->shared->size; @@ -2156,7 +2155,7 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /* end else */ /* Conversion loop... */ - for (elmtno=0; elmtno<nelmts; elmtno++) { + for(elmtno = 0; elmtno < nelmts; elmtno++) { /* * For each source member which will be present in the * destination, convert the member to the destination type unless @@ -2165,8 +2164,9 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * data point as small as possible with all the free space on the * right side. */ - for (u=0, offset=0; u<src->shared->u.compnd.nmembs; u++) { - if (src2dst[u]<0) continue; /*subsetting*/ + for(u = 0, offset = 0; u < src->shared->u.compnd.nmembs; u++) { + if(src2dst[u] < 0) + continue; /*subsetting*/ src_memb = src->shared->u.compnd.memb + u; dst_memb = dst->shared->u.compnd.memb + src2dst[u]; @@ -2176,15 +2176,16 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, (size_t)1, (size_t)0, (size_t)0, /*no striding (packed array)*/ xbuf + src_memb->offset, xbkg + dst_memb->offset, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound datatype member"); + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound datatype member") HDmemmove(xbuf + offset, xbuf + src_memb->offset, dst_memb->size); offset += dst_memb->size; - } else { + } /* end if */ + else { HDmemmove (xbuf+offset, xbuf+src_memb->offset, src_memb->size); offset += src_memb->size; - } - } + } /* end else */ + } /* end for */ /* * For each source member which will be present in the @@ -2193,8 +2194,9 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * yet). Then copy the member to the destination offset in the * background buffer. */ - for (i=src->shared->u.compnd.nmembs-1; i>=0; --i) { - if (src2dst[i]<0) continue; /*subsetting*/ + for(i = src->shared->u.compnd.nmembs - 1; i >= 0; --i) { + if(src2dst[i] < 0) + continue; /*subsetting*/ src_memb = src->shared->u.compnd.memb + i; dst_memb = dst->shared->u.compnd.memb + src2dst[i]; @@ -2205,43 +2207,44 @@ H5T_conv_struct(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, (size_t)1, (size_t)0, (size_t)0, /*no striding (packed array)*/ xbuf + offset, xbkg + dst_memb->offset, dxpl_id) < 0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound datatype member"); - } else + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to convert compound datatype member") + } /* end if */ + else offset -= dst_memb->size; HDmemmove(xbkg + dst_memb->offset, xbuf + offset, dst_memb->size); - } - assert (0==offset); + } /* end for */ + HDassert(0 == offset); /* * Update pointers */ xbuf += src_delta; xbkg += bkg_stride; - } + } /* end for */ /* If the bkg_stride was set to -(dst->shared->size), make it positive now */ - if(buf_stride==0 && dst->shared->size>src->shared->size) - bkg_stride=dst->shared->size; + if(buf_stride == 0 && dst->shared->size > src->shared->size) + bkg_stride = dst->shared->size; /* * Copy the background buffer back into the in-place conversion * buffer. */ - for (xbuf=buf, xbkg=bkg, elmtno=0; elmtno<nelmts; elmtno++) { + for(xbuf = buf, xbkg = bkg, elmtno = 0; elmtno < nelmts; elmtno++) { HDmemmove(xbuf, xbkg, dst->shared->size); xbuf += buf_stride ? buf_stride : dst->shared->size; xbkg += bkg_stride; - } + } /* end for */ break; default: /* Some other command we don't know about yet.*/ - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_struct() */ /*------------------------------------------------------------------------- @@ -2337,7 +2340,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, FUNC_ENTER_NOAPI(H5T_conv_struct_opt, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: /* * First, determine if this conversion function applies to the @@ -2347,8 +2350,10 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, */ if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") - HDassert(H5T_COMPOUND == src->shared->type); - HDassert(H5T_COMPOUND == dst->shared->type); + if(H5T_COMPOUND != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype") + if(H5T_COMPOUND != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_COMPOUND datatype") /* Initialize data which is relatively constant */ if(H5T_conv_struct_init(src, dst, cdata, dxpl_id) < 0) @@ -2383,7 +2388,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, if(dst_memb->size > src_memb->size) { offset -= src_memb->size; if(dst_memb->size > src->shared->size-offset) { - cdata->priv = priv = H5T_conv_struct_free(priv); + cdata->priv = H5T_conv_struct_free(priv); HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "convertion is unsupported by this function") } /* end if */ } /* end if */ @@ -2395,8 +2400,7 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, /* * Free the private conversion data. */ - priv = (H5T_conv_struct_t *)(cdata->priv); - cdata->priv = priv = H5T_conv_struct_free(priv); + cdata->priv = H5T_conv_struct_free((H5T_conv_struct_t *)(cdata->priv)); break; case H5T_CONV_CONV: @@ -2410,8 +2414,8 @@ H5T_conv_struct_opt(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, if(cdata->recalc && H5T_conv_struct_init(src, dst, cdata, dxpl_id)<0) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize conversion data") priv = (H5T_conv_struct_t *)(cdata->priv); - src2dst = priv->src2dst; HDassert(priv); + src2dst = priv->src2dst; HDassert(bkg && cdata->need_bkg); /* @@ -2558,20 +2562,20 @@ done: static herr_t H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) { - H5T_enum_struct_t *priv=NULL; /*private conversion data */ + H5T_enum_struct_t *priv = NULL; /*private conversion data */ int n; /*src value cast as native int */ int domain[2] = {0, 0}; /*min and max source values */ - int *map=NULL; /*map from src value to dst idx */ + int *map = NULL; /*map from src value to dst idx */ unsigned length; /*nelmts in map array */ unsigned i, j; /*counters */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI_NOINIT(H5T_conv_enum_init) cdata->need_bkg = H5T_BKG_NO; - if (NULL==(priv=(H5T_enum_struct_t *)(cdata->priv=H5MM_calloc(sizeof(*priv))))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); - if (0==src->shared->u.enumer.nmembs) + if(NULL == (priv = (H5T_enum_struct_t *)(cdata->priv = H5MM_calloc(sizeof(*priv))))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + if(0 == src->shared->u.enumer.nmembs) HGOTO_DONE(SUCCEED); /* @@ -2581,18 +2585,18 @@ H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) */ H5T_sort_name(src, NULL); H5T_sort_name(dst, NULL); - if (NULL==(priv->src2dst=(int *)H5MM_malloc(src->shared->u.enumer.nmembs*sizeof(int)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed");; - for (i=0, j=0; - i<src->shared->u.enumer.nmembs && j<dst->shared->u.enumer.nmembs; + if(NULL == (priv->src2dst = (int *)H5MM_malloc(src->shared->u.enumer.nmembs * sizeof(int)))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") + for(i = 0, j = 0; + i < src->shared->u.enumer.nmembs && j < dst->shared->u.enumer.nmembs; i++, j++) { - while (j<dst->shared->u.enumer.nmembs && + while(j < dst->shared->u.enumer.nmembs && HDstrcmp(src->shared->u.enumer.name[i], dst->shared->u.enumer.name[j])) j++; - if (j>=dst->shared->u.enumer.nmembs) - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "source type is not a subset of destination type"); + if(j >= dst->shared->u.enumer.nmembs) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "source type is not a subset of destination type") priv->src2dst[i] = j; - } + } /* end for */ /* * The conversion function will use an O(log N) lookup method for each @@ -2634,7 +2638,7 @@ H5T_conv_enum_init(H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata) priv->base = domain[0]; priv->length = length; if (NULL==(map=(int *)H5MM_malloc(length*sizeof(int)))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed"); + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed") for (i=0; i<length; i++) map[i] = -1; /*entry unused*/ for (i=0; i<src->shared->u.enumer.nmembs; i++) { @@ -2701,20 +2705,20 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, void UNUSED *bkg, hid_t UNUSED dxpl_id) { uint8_t *buf = (uint8_t*)_buf; /*cast for pointer arithmetic */ - H5T_t *src=NULL, *dst=NULL; /*src and dst datatypes */ - uint8_t *s=NULL, *d=NULL; /*src and dst BUF pointers */ + H5T_t *src = NULL, *dst = NULL; /*src and dst datatypes */ + uint8_t *s = NULL, *d = NULL; /*src and dst BUF pointers */ int src_delta, dst_delta; /*conversion strides */ int n; /*src value cast as native int */ - size_t i; /*counters */ H5T_enum_struct_t *priv = (H5T_enum_struct_t*)(cdata->priv); H5P_genplist_t *plist; /*property list pointer */ H5T_conv_cb_t cb_struct; /*conversion callback structure */ H5T_conv_ret_t except_ret; /*return of callback function */ - herr_t ret_value=SUCCEED; /* Return value */ + size_t i; /*counters */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5T_conv_enum, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: /* * Determine if this conversion function applies to the conversion @@ -2722,13 +2726,15 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * the `priv' field of `cdata' with information about the underlying * integer conversion. */ - if (NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - assert (H5T_ENUM==src->shared->type); - assert (H5T_ENUM==dst->shared->type); - if (H5T_conv_enum_init(src, dst, cdata)<0) - HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize private data"); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") + if(H5T_ENUM != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype") + if(H5T_ENUM != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype") + + if(H5T_conv_enum_init(src, dst, cdata) < 0) + HGOTO_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "unable to initialize private data") break; case H5T_CONV_FREE: @@ -2747,26 +2753,28 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; case H5T_CONV_CONV: - if (NULL == (src = (H5T_t *)H5I_object(src_id)) || - NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - assert (H5T_ENUM==src->shared->type); - assert (H5T_ENUM==dst->shared->type); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + if(H5T_ENUM != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype") + if(H5T_ENUM != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_ENUM datatype") /* priv->src2dst map was computed for certain sort keys. Make sure those same * sort keys are used here during conversion. See H5T_conv_enum_init(). But * we actually don't care about the source type's order when doing the O(1) * conversion algorithm, which is turned on by non-zero priv->length */ H5T_sort_name(dst, NULL); - if (!priv->length) H5T_sort_value(src, NULL); + if(!priv->length) + H5T_sort_value(src, NULL); /* * Direction of conversion. */ - if (buf_stride) { + if(buf_stride) { src_delta = dst_delta = (int)buf_stride; s = d = buf; - } else if (dst->shared->size <= src->shared->size) { + } else if(dst->shared->size <= src->shared->size) { src_delta = (int)src->shared->size; /*overflow shouldn't be possible*/ dst_delta = (int)dst->shared->size; /*overflow shouldn't be possible*/ s = d = buf; @@ -2778,25 +2786,24 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); + if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID") /* Get conversion exception callback property */ - if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); + if(H5P_get(plist, H5D_XFER_CONV_CB_NAME, &cb_struct) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") - for (i=0; i<nelmts; i++, s+=src_delta, d+=dst_delta) { - if (priv->length) { + for(i = 0; i < nelmts; i++, s += src_delta, d += dst_delta) { + if(priv->length) { /* Use O(1) lookup */ - if (1==src->shared->size) { + if(1 == src->shared->size) n = *((signed char*)s); - } else if (sizeof(short)==src->shared->size) { + else if(sizeof(short) == src->shared->size) n = *((short*)s); - } else { + else n = *((int*)s); - } n -= priv->base; - if (n<0 || n>=priv->length || priv->src2dst[n]<0) { + if(n < 0 || n >= priv->length || priv->src2dst[n] < 0) { /*overflow*/ except_ret = H5T_CONV_UNHANDLED; if(cb_struct.func) { /*If user's exception handler is present, use it*/ @@ -2818,19 +2825,19 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, int lt = 0; int rt = src->shared->u.enumer.nmembs; int md, cmp; - while (lt<rt) { - md = (lt+rt)/2; - cmp = HDmemcmp(s, src->shared->u.enumer.value+md*src->shared->size, + + while(lt < rt) { + md = (lt + rt) / 2; + cmp = HDmemcmp(s, src->shared->u.enumer.value + md * src->shared->size, src->shared->size); - if (cmp<0) { + if(cmp < 0) rt = md; - } else if (cmp>0) { - lt = md+1; - } else { + else if(cmp > 0) + lt = md + 1; + else break; - } - } - if (lt>=rt) { + } /* end while */ + if(lt >= rt) { except_ret = H5T_CONV_UNHANDLED; if(cb_struct.func) { /*If user's exception handler is present, use it*/ except_ret = (cb_struct.func)(H5T_CONV_EXCEPT_RANGE_HI, src_id, dst_id, @@ -2841,23 +2848,24 @@ H5T_conv_enum(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, HDmemset(d, 0xff, dst->shared->size); } else if(except_ret == H5T_CONV_ABORT) HGOTO_ERROR(H5E_DATATYPE, H5E_CANTCONVERT, FAIL, "can't handle conversion exception") - } else { + } /* end if */ + else { HDmemcpy(d, dst->shared->u.enumer.value+priv->src2dst[md]*dst->shared->size, dst->shared->size); - } + } /* end else */ } } break; default: /* Some other command we don't know about yet.*/ - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_enum() */ /*------------------------------------------------------------------------- @@ -2930,7 +2938,7 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, FUNC_ENTER_NOAPI(H5T_conv_vlen, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: /* * First, determine if this conversion function applies to the @@ -2940,9 +2948,11 @@ H5T_conv_vlen(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * conversion path. */ if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") - HDassert(H5T_VLEN == src->shared->type); - HDassert(H5T_VLEN == dst->shared->type); + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a datatype") + if(H5T_VLEN != src->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype") + if(H5T_VLEN != dst->shared->type) + HGOTO_ERROR(H5E_DATATYPE, H5E_BADTYPE, FAIL, "not a H5T_VLEN datatype") /* Variable-length types don't need a background buffer */ cdata->need_bkg = H5T_BKG_NO; @@ -3331,8 +3341,8 @@ H5T_conv_array(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; default: /* Some other command we don't know about yet.*/ - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } /* end switch */ + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: /* Release the background buffer, if we have one */ @@ -3340,7 +3350,7 @@ done: bkg_buf = H5FL_BLK_FREE(array_seq, bkg_buf); FUNC_LEAVE_NOAPI(ret_value) -} /* end H5T_conv_array() */ +} /* end H5T_conv_array() */ /*------------------------------------------------------------------------- @@ -3396,19 +3406,16 @@ H5T_conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, FUNC_ENTER_NOAPI(H5T_conv_i_i, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: - if (NULL==(src=(H5T_t *)H5I_object(src_id)) || - NULL==(dst=(H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (H5T_ORDER_LE!=src->shared->u.atomic.order && - H5T_ORDER_BE!=src->shared->u.atomic.order) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (H5T_ORDER_LE!=dst->shared->u.atomic.order && - H5T_ORDER_BE!=dst->shared->u.atomic.order) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (dst->shared->size>sizeof dbuf) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + if(H5T_ORDER_LE != src->shared->u.atomic.order && H5T_ORDER_BE != src->shared->u.atomic.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") + if(H5T_ORDER_LE != dst->shared->u.atomic.order && H5T_ORDER_BE != dst->shared->u.atomic.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") + if(dst->shared->size > sizeof dbuf) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large") cdata->need_bkg = H5T_BKG_NO; break; @@ -3417,9 +3424,8 @@ H5T_conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if (NULL==(src=(H5T_t *)H5I_object(src_id)) || - NULL==(dst=(H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* * Do we process the values from beginning to end or vice versa? Also, @@ -3441,18 +3447,18 @@ H5T_conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, double olap_d = HDceil((double)(src->shared->size)/ (double)(dst->shared->size-src->shared->size)); olap = (size_t)olap_d; - sp = (uint8_t*)buf + (nelmts-1) * src->shared->size; - dp = (uint8_t*)buf + (nelmts-1) * dst->shared->size; + sp = (uint8_t*)buf + (nelmts - 1) * src->shared->size; + dp = (uint8_t*)buf + (nelmts - 1) * dst->shared->size; direction = -1; } /* Get the plist structure */ - if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); + if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID") /* Get conversion exception callback property */ - if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); + if(H5P_get(plist,H5D_XFER_CONV_CB_NAME, &cb_struct) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") /* Allocate space for order-reversed source buffer */ src_rev = (uint8_t*)H5MM_calloc(src->shared->size); @@ -3741,14 +3747,14 @@ H5T_conv_i_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; default: - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: if(src_rev) H5MM_free(src_rev); FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_i_i() */ /*------------------------------------------------------------------------- @@ -3783,7 +3789,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, +H5T_conv_f_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg, hid_t dxpl_id) { @@ -3799,44 +3805,43 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t olap; /*num overlapping elements */ ssize_t bitno = 0; /*bit number */ uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t *src_rev=NULL; /*order-reversed source buffer */ + uint8_t *src_rev = NULL; /*order-reversed source buffer */ uint8_t dbuf[64]; /*temp destination buffer */ uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ /* Conversion-related variables */ hssize_t expo; /*exponent */ hssize_t expo_max; /*maximum possible dst exponent */ - size_t msize=0; /*useful size of mantissa in src*/ + size_t msize = 0; /*useful size of mantissa in src*/ size_t mpos; /*offset to useful mant is src */ hssize_t sign; /*source sign bit value */ size_t mrsh; /*amount to right shift mantissa*/ - hbool_t carry=0; /*carry after rounding mantissa */ + hbool_t carry = 0; /*carry after rounding mantissa */ size_t i; /*miscellaneous counters */ size_t implied; /*destination implied bits */ - hbool_t denormalized=FALSE; /*is either source or destination denormalized?*/ + hbool_t denormalized = FALSE; /*is either source or destination denormalized?*/ H5P_genplist_t *plist; /*property list pointer */ - H5T_conv_cb_t cb_struct={NULL, NULL}; /*conversion callback structure */ + H5T_conv_cb_t cb_struct = {NULL, NULL}; /*conversion callback structure */ H5T_conv_ret_t except_ret; /*return of callback function */ hbool_t reverse; /*if reverse the order of destination */ - herr_t ret_value=SUCCEED; /*return value */ + herr_t ret_value = SUCCEED; /*return value */ FUNC_ENTER_NOAPI(H5T_conv_f_f, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: - if (NULL==(src_p=(H5T_t *)H5I_object(src_id)) || - NULL==(dst_p=(H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src_p = (H5T_t *)H5I_object(src_id)) || NULL == (dst_p = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; - if (H5T_ORDER_LE!=src.order && H5T_ORDER_BE!=src.order && H5T_ORDER_VAX!=src.order) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (H5T_ORDER_LE!=dst.order && H5T_ORDER_BE!=dst.order && H5T_ORDER_VAX!=dst.order) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (dst_p->shared->size>sizeof(dbuf)) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); - if (8*sizeof(expo)-1<src.u.f.esize || 8*sizeof(expo)-1<dst.u.f.esize) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large"); + if(H5T_ORDER_LE != src.order && H5T_ORDER_BE != src.order && H5T_ORDER_VAX != src.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") + if(H5T_ORDER_LE != dst.order && H5T_ORDER_BE != dst.order && H5T_ORDER_VAX != dst.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") + if(dst_p->shared->size > sizeof(dbuf)) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large") + if(8 * sizeof(expo) - 1 < src.u.f.esize || 8 * sizeof(expo) - 1 < dst.u.f.esize) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large") cdata->need_bkg = H5T_BKG_NO; break; @@ -3845,9 +3850,8 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if (NULL==(src_p=(H5T_t *)H5I_object(src_id)) || - NULL==(dst_p=(H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src_p = (H5T_t *)H5I_object(src_id)) || NULL == (dst_p = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; expo_max = ((hssize_t)1 << dst.u.f.esize) - 1; @@ -3878,11 +3882,11 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* Get the plist structure */ if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID") /* Get conversion exception callback property */ - if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); + if(H5P_get(plist,H5D_XFER_CONV_CB_NAME, &cb_struct) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") /* Allocate space for order-reversed source buffer */ src_rev = (uint8_t*)H5MM_calloc(src_p->shared->size); @@ -4319,15 +4323,15 @@ H5T_conv_f_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; default: - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: if(src_rev) H5MM_free(src_rev); FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_f_f() */ /*------------------------------------------------------------------------- @@ -4365,22 +4369,21 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, FUNC_ENTER_NOAPI(H5T_conv_s_s, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: - if (NULL==(src=(H5T_t *)H5I_object(src_id)) || - NULL==(dst=(H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); - if (8*src->shared->size != src->shared->u.atomic.prec || 8*dst->shared->size != dst->shared->u.atomic.prec) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad precision"); - if (0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad offset"); - if (H5T_CSET_ASCII != src->shared->u.atomic.u.s.cset && H5T_CSET_UTF8 != src->shared->u.atomic.u.s.cset) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad source character set"); - if (H5T_CSET_ASCII != dst->shared->u.atomic.u.s.cset && H5T_CSET_UTF8 != dst->shared->u.atomic.u.s.cset) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad destination character set"); - if (src->shared->u.atomic.u.s.pad<0 || src->shared->u.atomic.u.s.pad>=H5T_NPAD || - dst->shared->u.atomic.u.s.pad<0 || dst->shared->u.atomic.u.s.pad>=H5T_NPAD) - HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad character padding"); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") + if(8 * src->shared->size != src->shared->u.atomic.prec || 8 * dst->shared->size != dst->shared->u.atomic.prec) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad precision") + if(0 != src->shared->u.atomic.offset || 0 != dst->shared->u.atomic.offset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad offset") + if(H5T_CSET_ASCII != src->shared->u.atomic.u.s.cset && H5T_CSET_UTF8 != src->shared->u.atomic.u.s.cset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad source character set") + if(H5T_CSET_ASCII != dst->shared->u.atomic.u.s.cset && H5T_CSET_UTF8 != dst->shared->u.atomic.u.s.cset) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad destination character set") + if(src->shared->u.atomic.u.s.pad < 0 || src->shared->u.atomic.u.s.pad >= H5T_NPAD || + dst->shared->u.atomic.u.s.pad < 0 || dst->shared->u.atomic.u.s.pad >= H5T_NPAD) + HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "bad character padding") cdata->need_bkg = H5T_BKG_NO; break; @@ -4389,9 +4392,8 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if (NULL==(src=(H5T_t *)H5I_object(src_id)) || - NULL==(dst=(H5T_t *)H5I_object(dst_id))) - HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src = (H5T_t *)H5I_object(src_id)) || NULL == (dst = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") /* * Do we process the values from beginning to end or vice versa? Also, @@ -4422,22 +4424,22 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, } /* Allocate the overlap buffer */ - if (NULL==(dbuf=(uint8_t *)H5MM_malloc(dst->shared->size))) - HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for string conversion"); + if(NULL == (dbuf = (uint8_t *)H5MM_malloc(dst->shared->size))) + HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "memory allocation failed for string conversion") /* The conversion loop. */ - for (elmtno=0; elmtno<nelmts; elmtno++) { + for(elmtno = 0; elmtno < nelmts; elmtno++) { /* * If the source and destination buffers overlap then use a * temporary buffer for the destination. */ - if (direction>0) { + if(direction > 0) { s = sp; - d = elmtno<olap ? dbuf : dp; + d = elmtno < olap ? dbuf : dp; } else { s = sp; - d = elmtno+olap >= nelmts ? dbuf : dp; + d = elmtno + olap >= nelmts ? dbuf : dp; } #ifndef NDEBUG /* I don't quite trust the overlap calculations yet --rpm */ @@ -4453,7 +4455,7 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, #endif /* Copy characters from source to destination */ - switch (src->shared->u.atomic.u.s.pad) { + switch(src->shared->u.atomic.u.s.pad) { case H5T_STR_NULLTERM: for (nchars=0; nchars<dst->shared->size && nchars<src->shared->size && s[nchars]; @@ -4493,24 +4495,24 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_STR_RESERVED_14: case H5T_STR_RESERVED_15: case H5T_STR_ERROR: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "source string padding method not supported"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "source string padding method not supported") + } /* end switch */ /* Terminate or pad the destination */ - switch (dst->shared->u.atomic.u.s.pad) { + switch(dst->shared->u.atomic.u.s.pad) { case H5T_STR_NULLTERM: - while (nchars<dst->shared->size) + while(nchars < dst->shared->size) d[nchars++] = '\0'; - d[dst->shared->size-1] = '\0'; + d[dst->shared->size - 1] = '\0'; break; case H5T_STR_NULLPAD: - while (nchars<dst->shared->size) + while(nchars < dst->shared->size) d[nchars++] = '\0'; break; case H5T_STR_SPACEPAD: - while (nchars<dst->shared->size) + while(nchars < dst->shared->size) d[nchars++] = ' '; break; @@ -4528,8 +4530,8 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_STR_RESERVED_14: case H5T_STR_RESERVED_15: case H5T_STR_ERROR: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination string padding method not supported"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination string padding method not supported") + } /* end switch */ /* * If we used a temporary buffer for the destination then we @@ -4544,17 +4546,18 @@ H5T_conv_s_s(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, sp += direction * src->shared->size; dp += direction * dst->shared->size; } - } + } /* end for */ break; default: - HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown converson command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown converson command") + } /* end switch */ done: H5MM_xfree(dbuf); + FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_s_s() */ /*------------------------------------------------------------------------- @@ -9714,7 +9717,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, +H5T_conv_f_i(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg, hid_t dxpl_id) { @@ -9750,19 +9753,18 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, FUNC_ENTER_NOAPI(H5T_conv_f_i, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: - if (NULL==(src_p=(H5T_t*)H5I_object(src_id)) || - NULL==(dst_p=(H5T_t*)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src_p = (H5T_t*)H5I_object(src_id)) || NULL == (dst_p = (H5T_t*)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; - if (H5T_ORDER_LE!=src.order && H5T_ORDER_BE!=src.order && H5T_ORDER_VAX!=src.order) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (dst_p->shared->size>sizeof(dbuf)) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); - if (8*sizeof(expo)-1<src.u.f.esize) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large"); + if(H5T_ORDER_LE != src.order && H5T_ORDER_BE != src.order && H5T_ORDER_VAX != src.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") + if(dst_p->shared->size > sizeof(dbuf)) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large") + if(8 * sizeof(expo) - 1 < src.u.f.esize) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large") cdata->need_bkg = H5T_BKG_NO; break; @@ -9771,9 +9773,8 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if (NULL==(src_p=(H5T_t*)H5I_object(src_id)) || - NULL==(dst_p=(H5T_t*)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src_p = (H5T_t*)H5I_object(src_id)) || NULL == (dst_p = (H5T_t*)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; @@ -9782,7 +9783,7 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, * how many of the elements have the source and destination areas * overlapping? */ - if (src_p->shared->size==dst_p->shared->size || buf_stride) { + if(src_p->shared->size==dst_p->shared->size || buf_stride) { sp = dp = (uint8_t*)buf; direction = 1; olap = nelmts; @@ -9809,11 +9810,11 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* Get the plist structure. Do I need to close it? */ if(NULL == (plist = H5P_object_verify(dxpl_id, H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID") /* Get conversion exception callback property */ if(H5P_get(plist, H5D_XFER_CONV_CB_NAME, &cb_struct) < 0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") /* Allocate space for order-reversed source buffer */ src_rev = (uint8_t*)H5MM_calloc(src_p->shared->size); @@ -10265,16 +10266,17 @@ H5T_conv_f_i (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; default: - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: if(int_buf) H5MM_xfree(int_buf); if(src_rev) H5MM_free(src_rev); + FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_f_i() */ /*------------------------------------------------------------------------- @@ -10302,7 +10304,7 @@ done: *------------------------------------------------------------------------- */ herr_t -H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, +H5T_conv_i_f(hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t buf_stride, size_t UNUSED bkg_stride, void *buf, void UNUSED *bkg, hid_t dxpl_id) { @@ -10317,7 +10319,7 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t tsize; /*type size for swapping bytes */ size_t olap; /*num overlapping elements */ uint8_t *s, *sp, *d, *dp; /*source and dest traversal ptrs*/ - uint8_t *src_rev=NULL; /*order-reversed source buffer */ + uint8_t *src_rev = NULL; /*order-reversed source buffer */ uint8_t dbuf[64]; /*temp destination buffer */ uint8_t tmp1, tmp2; /*temp variables for swapping bytes*/ @@ -10327,32 +10329,31 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, size_t sign; /*source sign bit value */ hbool_t is_max_neg; /*source is maximal negative value*/ hbool_t do_round; /*whether there is roundup */ - uint8_t *int_buf=NULL; /*buffer for temporary value */ + uint8_t *int_buf = NULL; /*buffer for temporary value */ size_t buf_size; /*buffer size for temporary value */ size_t i; /*miscellaneous counters */ size_t first; /*first bit(MSB) in an integer */ ssize_t sfirst; /*a signed version of `first' */ H5P_genplist_t *plist; /*Property list pointer */ - H5T_conv_cb_t cb_struct={NULL, NULL}; /*conversion callback structure */ + H5T_conv_cb_t cb_struct = {NULL, NULL}; /*conversion callback structure */ H5T_conv_ret_t except_ret; /*return of callback function */ hbool_t reverse; /*if reverse the order of destination */ - herr_t ret_value=SUCCEED; /* Return value */ + herr_t ret_value = SUCCEED; /* Return value */ FUNC_ENTER_NOAPI(H5T_conv_i_f, FAIL) - switch (cdata->command) { + switch(cdata->command) { case H5T_CONV_INIT: - if (NULL==(src_p=(H5T_t*)H5I_object(src_id)) || - NULL==(dst_p=(H5T_t*)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src_p = (H5T_t *)H5I_object(src_id)) || NULL == (dst_p = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; - if (H5T_ORDER_LE!=dst.order && H5T_ORDER_BE!=dst.order && H5T_ORDER_VAX!=dst.order) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order"); - if (dst_p->shared->size>sizeof(dbuf)) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large"); - if (8*sizeof(expo)-1<src.u.f.esize) - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large"); + if(H5T_ORDER_LE != dst.order && H5T_ORDER_BE != dst.order && H5T_ORDER_VAX != dst.order) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unsupported byte order") + if(dst_p->shared->size > sizeof(dbuf)) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "destination size is too large") + if(8 * sizeof(expo) - 1 < src.u.f.esize) + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "exponent field is too large") cdata->need_bkg = H5T_BKG_NO; break; @@ -10361,9 +10362,8 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, case H5T_CONV_CONV: /* Get the datatypes */ - if (NULL==(src_p=(H5T_t*)H5I_object(src_id)) || - NULL==(dst_p=(H5T_t*)H5I_object(dst_id))) - HGOTO_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype"); + if(NULL == (src_p = (H5T_t *)H5I_object(src_id)) || NULL == (dst_p = (H5T_t *)H5I_object(dst_id))) + HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a datatype") src = src_p->shared->u.atomic; dst = dst_p->shared->u.atomic; @@ -10399,11 +10399,11 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, /* Get the plist structure */ if(NULL == (plist = H5P_object_verify(dxpl_id,H5P_DATASET_XFER))) - HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID"); + HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find property list for ID") /* Get conversion exception callback property */ - if (H5P_get(plist,H5D_XFER_CONV_CB_NAME,&cb_struct)<0) - HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback"); + if(H5P_get(plist,H5D_XFER_CONV_CB_NAME, &cb_struct) < 0) + HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "unable to get conversion exception callback") /* Allocate space for order-reversed source buffer */ src_rev = (uint8_t*)H5MM_calloc(src_p->shared->size); @@ -10696,16 +10696,17 @@ H5T_conv_i_f (hid_t src_id, hid_t dst_id, H5T_cdata_t *cdata, size_t nelmts, break; default: - HGOTO_ERROR (H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command"); - } + HGOTO_ERROR(H5E_DATATYPE, H5E_UNSUPPORTED, FAIL, "unknown conversion command") + } /* end switch */ done: if(int_buf) H5MM_xfree(int_buf); if(src_rev) H5MM_free(src_rev); + FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_conv_i_f() */ /*------------------------------------------------------------------------- diff --git a/src/H5Tnative.c b/src/H5Tnative.c index 5b685b1..3699757 100644 --- a/src/H5Tnative.c +++ b/src/H5Tnative.c @@ -94,8 +94,6 @@ H5T_init_native_interface(void) * Programmer: Raymond Lu * Oct 3, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ hid_t @@ -147,38 +145,39 @@ done: * Programmer: Raymond Lu * Oct 3, 2002 * - * Modifications: - * Raymond Lu - * 27 April 2010 - * I changed the way that the offset, alignment, and size of - * nested compound type are calculated by using H5T_cmp_offset. - * The old way had a bug in it (see bug #1850). - * *------------------------------------------------------------------------- */ -static H5T_t* +static H5T_t * H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size) { H5T_t *dt; /* Datatype to make native */ + H5T_t *super_type; /* Super type of VL, array and enum datatypes */ + H5T_t *nat_super_type; /* Native form of VL, array & enum super datatype */ + H5T_t *new_type = NULL; /* New native datatype */ + H5T_t *memb_type = NULL; /* Datatype of member */ + H5T_t **memb_list = NULL; /* List of compound member IDs */ + size_t *memb_offset = NULL; /* List of member offsets in compound type, including member size and alignment */ + char **comp_mname = NULL; /* List of member names in compound type */ + char *memb_name = NULL; /* Enum's member name */ + void *memb_value = NULL; /* Enum's member value */ + void *tmp_memb_value = NULL; /* Enum's member value */ + hsize_t *dims = NULL; /* Dimension sizes for array */ H5T_class_t h5_class; /* Class of datatype to make native */ size_t size; /* Size of datatype to make native */ size_t prec; /* Precision of datatype to make native */ int snmemb; /* Number of members in compound & enum types */ - unsigned nmemb; /* Number of members in compound & enum types */ - H5T_t *super_type; /* Super type of VL, array and enum datatypes */ - H5T_t *nat_super_type; /* Native form of VL, array & enum super datatype */ - H5T_t *new_type=NULL; /* New native datatype */ - unsigned i; /* Local index variable */ + unsigned nmemb = 0; /* Number of members in compound & enum types */ + unsigned u; /* Local index variable */ H5T_t *ret_value; /* Return value */ FUNC_ENTER_NOAPI(H5T_get_native_type, NULL) assert(dtype); - if((h5_class = H5T_get_class(dtype, FALSE)) == H5T_NO_CLASS) + if(H5T_NO_CLASS == (h5_class = H5T_get_class(dtype, FALSE))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid class") - if((size = H5T_get_size(dtype)) == 0) + if(0 == (size = H5T_get_size(dtype))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid size") switch(h5_class) { @@ -186,35 +185,36 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig { H5T_sign_t sign; /* Signedness of integer type */ - if((sign = H5T_get_sign(dtype))==H5T_SGN_ERROR) + if(H5T_SGN_ERROR == (sign = H5T_get_sign(dtype))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a valid signess") prec = dtype->shared->u.atomic.prec; - if((ret_value = H5T_get_native_integer(prec, sign, direction, struct_align, offset, comp_size))==NULL) + if(NULL == (ret_value = H5T_get_native_integer(prec, sign, direction, struct_align, offset, comp_size))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve integer type") - } + } /* end case */ break; case H5T_FLOAT: - if((ret_value = H5T_get_native_float(size, direction, struct_align, offset, comp_size))==NULL) + if(NULL == (ret_value = H5T_get_native_float(size, direction, struct_align, offset, comp_size))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type") break; case H5T_STRING: - if((ret_value=H5T_copy(dtype, H5T_COPY_TRANSIENT))==NULL) + if(NULL == (ret_value = H5T_copy(dtype, H5T_COPY_TRANSIENT))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type") if(H5T_IS_VL_STRING(dtype->shared)) { /* Update size, offset and compound alignment for parent. */ - if(H5T_cmp_offset(comp_size, offset, sizeof(char *), (size_t)1, H5T_POINTER_COMP_ALIGN_g, struct_align)<0) + if(H5T_cmp_offset(comp_size, offset, sizeof(char *), (size_t)1, H5T_POINTER_COMP_ALIGN_g, struct_align) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset") - } else { + } /* end if */ + else { /* Update size, offset and compound alignment for parent. */ - if(H5T_cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_COMP_ALIGN_g, struct_align)<0) + if(H5T_cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_COMP_ALIGN_g, struct_align) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset") - } + } /* end else */ break; /* The time type will be supported in the future. Simply return "not supported" @@ -226,17 +226,17 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig { prec = dtype->shared->u.atomic.prec; - if((ret_value = H5T_get_native_bitfield(prec, direction, struct_align, offset, comp_size))==NULL) + if(NULL == (ret_value = H5T_get_native_bitfield(prec, direction, struct_align, offset, comp_size))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve integer for bitfield type") - } + } /* end case */ break; case H5T_OPAQUE: - if((ret_value=H5T_copy(dtype, H5T_COPY_TRANSIENT))==NULL) + if(NULL == (ret_value = H5T_copy(dtype, H5T_COPY_TRANSIENT))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type") /* Update size, offset and compound alignment for parent. */ - if(H5T_cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_COMP_ALIGN_g, struct_align)<0) + if(H5T_cmp_offset(comp_size, offset, sizeof(char), size, H5T_NATIVE_SCHAR_COMP_ALIGN_g, struct_align) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset") break; @@ -246,11 +246,11 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig size_t ref_size; int not_equal; - if((ret_value=H5T_copy(dtype, H5T_COPY_TRANSIENT))==NULL) + if(NULL == (ret_value = H5T_copy(dtype, H5T_COPY_TRANSIENT))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot retrieve float type") /* Decide if the data type is object or dataset region reference. */ - if(NULL==(dt=(H5T_t *)H5I_object(H5T_STD_REF_OBJ_g))) + if(NULL == (dt = (H5T_t *)H5I_object(H5T_STD_REF_OBJ_g))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type") not_equal = H5T_cmp(ret_value, dt, FALSE); @@ -258,69 +258,65 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig if(!not_equal) { align = H5T_HOBJREF_COMP_ALIGN_g; ref_size = sizeof(hobj_ref_t); - } else { + } /* end if */ + else { align = H5T_HDSETREGREF_COMP_ALIGN_g; ref_size = sizeof(hdset_reg_ref_t); - } + } /* end else */ - if(H5T_cmp_offset(comp_size, offset, ref_size, (size_t)1, align, struct_align)<0) + if(H5T_cmp_offset(comp_size, offset, ref_size, (size_t)1, align, struct_align) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset") - } + } /* end case */ break; case H5T_COMPOUND: { - H5T_t *memb_type; /* Datatype of member */ - H5T_t **memb_list; /* List of compound member IDs */ - size_t *memb_offset; /* List of member offsets in compound type, including member size and alignment */ - size_t children_size=0;/* Total size of compound members */ - size_t children_st_align=0; /* The max alignment among compound members. This'll be the compound alignment */ - char **comp_mname; /* List of member names in compound type */ - - if((snmemb = H5T_get_nmembers(dtype))<=0) + size_t children_size = 0;/* Total size of compound members */ + size_t children_st_align = 0; /* The max alignment among compound members. This'll be the compound alignment */ + + if((snmemb = H5T_get_nmembers(dtype)) <= 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "compound data type doesn't have any member") - H5_ASSIGN_OVERFLOW(nmemb,snmemb,int,unsigned); + H5_ASSIGN_OVERFLOW(nmemb, snmemb, int, unsigned); - if((memb_list = (H5T_t**)H5MM_malloc(nmemb*sizeof(H5T_t*)))==NULL) + if(NULL == (memb_list = (H5T_t **)H5MM_calloc(nmemb * sizeof(H5T_t *)))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory") - if((memb_offset = (size_t*)H5MM_calloc(nmemb*sizeof(size_t)))==NULL) + if(NULL == (memb_offset = (size_t *)H5MM_calloc(nmemb * sizeof(size_t)))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory") - if((comp_mname = (char**)H5MM_malloc(nmemb*sizeof(char*)))==NULL) + if(NULL == (comp_mname = (char **)H5MM_calloc(nmemb * sizeof(char *)))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory") /* Construct child compound type and retrieve a list of their IDs, offsets, total size, and alignment for compound type. */ - for(i=0; i<nmemb; i++) { - if((memb_type = H5T_get_member_type(dtype, i, H5T_COPY_TRANSIENT))==NULL) + for(u = 0; u < nmemb; u++) { + if(NULL == (memb_type = H5T_get_member_type(dtype, u, H5T_COPY_TRANSIENT))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member type retrieval failed") - if((comp_mname[i] = H5T_get_member_name(dtype, i))==NULL) + if(NULL == (comp_mname[u] = H5T_get_member_name(dtype, u))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member type retrieval failed") - if((memb_list[i] = H5T_get_native_type(memb_type, direction, &children_st_align, &(memb_offset[i]), &children_size))==NULL) + if(NULL == (memb_list[u] = H5T_get_native_type(memb_type, direction, &children_st_align, &(memb_offset[u]), &children_size))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "member identifier retrieval failed") - if(H5T_close(memb_type)<0) + if(H5T_close(memb_type) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype") - } + } /* end for */ /* The alignment for whole compound type */ if(children_st_align && children_size % children_st_align) - children_size += children_st_align-(children_size % children_st_align); + children_size += children_st_align - (children_size % children_st_align); /* Construct new compound type based on native type */ - if((new_type=H5T_create(H5T_COMPOUND, children_size))==NULL) + if(NULL == (new_type = H5T_create(H5T_COMPOUND, children_size))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot create a compound type") /* Insert members for the new compound type */ - for(i=0; i<nmemb; i++) { - if(H5T_insert(new_type, comp_mname[i], memb_offset[i], memb_list[i])<0) + for(u = 0; u < nmemb; u++) + if(H5T_insert(new_type, comp_mname[u], memb_offset[u], memb_list[u]) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot insert member to compound datatype") - } /* Update size, offset and compound alignment for parent in the case of * nested compound type. The alignment for a compound type as one field in * a compound type is the biggest compound alignment among all its members. - * i.g. in the structure + * e.g. in the structure * typedef struct s1 { * char c; * int i; @@ -340,108 +336,105 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset") /* Close member data type */ - for(i=0; i<nmemb; i++) { - if(H5T_close(memb_list[i])<0) + for(u = 0; u < nmemb; u++) { + if(H5T_close(memb_list[u]) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype") /* Free member names in list */ - H5MM_xfree(comp_mname[i]); - } + comp_mname[u] = (char *)H5MM_xfree(comp_mname[u]); + } /* end for */ /* Free lists for members */ - H5MM_xfree(memb_list); - H5MM_xfree(memb_offset); - H5MM_xfree(comp_mname); + memb_list = (H5T_t **)H5MM_xfree(memb_list); + memb_offset = (size_t *)H5MM_xfree(memb_offset); + comp_mname = (char **)H5MM_xfree(comp_mname); ret_value = new_type; - } + } /* end case */ break; case H5T_ENUM: { - char *memb_name; /* Enum's member name */ - void *memb_value, *tmp_memb_value; /* Enum's member value */ hid_t super_type_id, nat_super_type_id; /* Don't need to do anything special for alignment, offset since the ENUM type usually is integer. */ /* Retrieve base type for enumerated type */ - if((super_type=H5T_get_super(dtype))==NULL) + if(NULL == (super_type = H5T_get_super(dtype))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get base type for enumerate type") - if((nat_super_type = H5T_get_native_type(super_type, direction, struct_align, offset, comp_size))==NULL) + if(NULL == (nat_super_type = H5T_get_native_type(super_type, direction, struct_align, offset, comp_size))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "base native type retrieval failed") - if((super_type_id=H5I_register(H5I_DATATYPE, super_type, FALSE))<0) + if((super_type_id = H5I_register(H5I_DATATYPE, super_type, FALSE)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot register datatype") - if((nat_super_type_id=H5I_register(H5I_DATATYPE, nat_super_type, FALSE))<0) + if((nat_super_type_id = H5I_register(H5I_DATATYPE, nat_super_type, FALSE)) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot register datatype") /* Allocate room for the enum values */ - if((tmp_memb_value = H5MM_calloc(H5T_get_size(super_type)))==NULL) + if(NULL == (tmp_memb_value = H5MM_calloc(H5T_get_size(super_type)))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory") - if((memb_value = H5MM_calloc(H5T_get_size(nat_super_type)))==NULL) + if(NULL == (memb_value = H5MM_calloc(H5T_get_size(nat_super_type)))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory") /* Construct new enum type based on native type */ - if((new_type=H5T_enum_create(nat_super_type))==NULL) + if(NULL == (new_type=H5T_enum_create(nat_super_type))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create enum type") /* Retrieve member info and insert members into new enum type */ - if((snmemb = H5T_get_nmembers(dtype))<=0) + if((snmemb = H5T_get_nmembers(dtype)) <= 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "enumerate data type doesn't have any member") - H5_ASSIGN_OVERFLOW(nmemb,snmemb,int,unsigned); - for(i=0; i<nmemb; i++) { - if((memb_name=H5T_get_member_name(dtype, i))==NULL) + H5_ASSIGN_OVERFLOW(nmemb, snmemb, int, unsigned); + for(u = 0; u < nmemb; u++) { + if(NULL == (memb_name = H5T_get_member_name(dtype, u))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member name") - if(H5T_get_member_value(dtype, i, tmp_memb_value)<0) + if(H5T_get_member_value(dtype, u, tmp_memb_value) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member value") HDmemcpy(memb_value, tmp_memb_value, H5T_get_size(super_type)); - if(H5Tconvert(super_type_id, nat_super_type_id, (size_t)1, memb_value, NULL, H5P_DEFAULT)<0) + if(H5Tconvert(super_type_id, nat_super_type_id, (size_t)1, memb_value, NULL, H5P_DEFAULT) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get member value") - if(H5T_enum_insert(new_type, memb_name, memb_value)<0) + if(H5T_enum_insert(new_type, memb_name, memb_value) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot insert member") - H5MM_xfree(memb_name); + memb_name = (char *)H5MM_xfree(memb_name); } - H5MM_xfree(memb_value); - H5MM_xfree(tmp_memb_value); + memb_value = H5MM_xfree(memb_value); + tmp_memb_value = H5MM_xfree(tmp_memb_value); /* Close base type */ - if(H5Tclose(nat_super_type_id)<0) + if(H5Tclose(nat_super_type_id) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype") /* Close super type */ - if(H5Tclose(super_type_id)<0) + if(H5Tclose(super_type_id) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype") ret_value = new_type; - } + } /* end case */ break; case H5T_ARRAY: { int sarray_rank; /* Array's rank */ unsigned array_rank; /* Array's rank */ - hsize_t *dims = NULL; /* Dimension sizes for array */ hsize_t nelems = 1; - size_t super_offset=0; - size_t super_size=0; - size_t super_align=0; + size_t super_offset = 0; + size_t super_size = 0; + size_t super_align = 0; /* Retrieve dimension information for array data type */ if((sarray_rank = H5T_get_array_ndims(dtype)) <= 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get dimension rank") H5_ASSIGN_OVERFLOW(array_rank, sarray_rank, int, unsigned); - if((dims = (hsize_t*)H5MM_malloc(array_rank * sizeof(hsize_t))) == NULL) + if(NULL == (dims = (hsize_t*)H5MM_malloc(array_rank * sizeof(hsize_t)))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot allocate memory") if(H5T_get_array_dims(dtype, dims) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot get dimension size") /* Retrieve base type for array type */ - if((super_type = H5T_get_super(dtype)) == NULL) + if(NULL == (super_type = H5T_get_super(dtype))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get parent type for array type") - if((nat_super_type = H5T_get_native_type(super_type, direction, &super_align, - &super_offset, &super_size)) == NULL) + if(NULL == (nat_super_type = H5T_get_native_type(super_type, direction, &super_align, + &super_offset, &super_size))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "parent native type retrieval failed") /* Close super type */ @@ -449,77 +442,98 @@ H5T_get_native_type(H5T_t *dtype, H5T_direction_t direction, size_t *struct_alig HGOTO_ERROR(H5E_ARGS, H5E_CLOSEERROR, NULL, "cannot close datatype") /* Create a new array type based on native type */ - if((new_type = H5T_array_create(nat_super_type, array_rank, dims)) == NULL) + if(NULL == (new_type = H5T_array_create(nat_super_type, array_rank, dims))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create array type") /* Close base type */ if(H5T_close(nat_super_type) < 0) HGOTO_ERROR(H5E_ARGS, H5E_CLOSEERROR, NULL, "cannot close datatype") - for(i = 0; i < array_rank; i++) - nelems *= dims[i]; + for(u = 0; u < array_rank; u++) + nelems *= dims[u]; H5_CHECK_OVERFLOW(nelems, hsize_t, size_t); if(H5T_cmp_offset(comp_size, offset, super_size, (size_t)nelems, super_align, struct_align) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset") - H5MM_xfree(dims); + dims = (hsize_t *)H5MM_xfree(dims); + ret_value = new_type; - } + } /* end case */ break; case H5T_VLEN: { size_t vl_align = 0; size_t vl_size = 0; - size_t super_size=0; + size_t super_size = 0; /* Retrieve base type for array type */ - if((super_type=H5T_get_super(dtype))==NULL) + if(NULL == (super_type = H5T_get_super(dtype))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to get parent type for VL type") /* Don't need alignment, offset information if this VL isn't a field of compound type. If it * is, go to a few steps below to compute the information directly. */ - if((nat_super_type = H5T_get_native_type(super_type, direction, NULL, NULL, &super_size))==NULL) + if(NULL == (nat_super_type = H5T_get_native_type(super_type, direction, NULL, NULL, &super_size))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "parent native type retrieval failed") /* Close super type */ - if(H5T_close(super_type)<0) + if(H5T_close(super_type) < 0) HGOTO_ERROR(H5E_ARGS, H5E_CLOSEERROR, NULL, "cannot close datatype") /* Create a new array type based on native type */ - if((new_type=H5T_vlen_create(nat_super_type))==NULL) + if(NULL == (new_type = H5T_vlen_create(nat_super_type))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "unable to create VL type") /* Close base type */ - if(H5T_close(nat_super_type)<0) + if(H5T_close(nat_super_type) < 0) HGOTO_ERROR(H5E_ARGS, H5E_CLOSEERROR, NULL, "cannot close datatype") /* Update size, offset and compound alignment for parent compound type directly. */ vl_align = H5T_HVL_COMP_ALIGN_g; vl_size = sizeof(hvl_t); - if(H5T_cmp_offset(comp_size, offset, vl_size, (size_t)1, vl_align, struct_align)<0) + if(H5T_cmp_offset(comp_size, offset, vl_size, (size_t)1, vl_align, struct_align) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset") ret_value = new_type; - } + } /* end case */ break; case H5T_NO_CLASS: case H5T_NCLASSES: default: HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "data type doesn't match any native type") - } + } /* end switch */ done: /* Error cleanup */ - if(ret_value==NULL) { + if(NULL == ret_value) { if(new_type) - if(H5T_close(new_type)<0) + if(H5T_close(new_type) < 0) HDONE_ERROR(H5E_DATATYPE, H5E_CLOSEERROR, NULL, "unable to release datatype") + + /* Free lists for members */ + if(memb_list) { + for(u = 0; u < nmemb; u++) + if(memb_list[u] && H5T_close(memb_list[u]) < 0) + HDONE_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot close datatype") + + memb_list = (H5T_t **)H5MM_xfree(memb_list); + } /* end if */ + memb_offset = (size_t *)H5MM_xfree(memb_offset); + if(comp_mname) { + for(u = 0; u < nmemb; u++) + if(comp_mname[u]) + H5MM_xfree(comp_mname[u]); + comp_mname = (char **)H5MM_xfree(comp_mname); + } /* end if */ + memb_name = (char *)H5MM_xfree(memb_name); + memb_value = H5MM_xfree(memb_value); + tmp_memb_value = H5MM_xfree(tmp_memb_value); + dims = (hsize_t *)H5MM_xfree(dims); } /* end if */ FUNC_LEAVE_NOAPI(ret_value) -} +} /* end H5T_get_native_type() */ /*------------------------------------------------------------------------- @@ -534,23 +548,16 @@ done: * Programmer: Raymond Lu * Oct 3, 2002 * - * Modifications: Pedro Vicente - * Sep 4, 2004 - * Choose the type based on the precision; this is to support cases - * like the Cray SV1, where the size of short is 8 but precision is 32 - * (e.g an INT (size 8, prec 64) would be converted to a SHORT - * (size 8, prec 32) if the size was the deciding factor) - * *------------------------------------------------------------------------- */ -static H5T_t* +static H5T_t * H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, size_t *struct_align, size_t *offset, size_t *comp_size) { H5T_t *dt; /* Appropriate native datatype to copy */ - hid_t tid=(-1); /* Datatype ID of appropriate native datatype */ - size_t align=0; /* Alignment necessary for native datatype */ - size_t native_size=0; /* Datatype size of the native type */ + hid_t tid = (-1); /* Datatype ID of appropriate native datatype */ + size_t align = 0; /* Alignment necessary for native datatype */ + size_t native_size = 0; /* Datatype size of the native type */ enum match_type { /* The different kinds of integers we can match */ H5T_NATIVE_INT_MATCH_CHAR, H5T_NATIVE_INT_MATCH_SHORT, @@ -558,46 +565,46 @@ H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, H5T_NATIVE_INT_MATCH_LONG, H5T_NATIVE_INT_MATCH_LLONG, H5T_NATIVE_INT_MATCH_UNKNOWN - } match=H5T_NATIVE_INT_MATCH_UNKNOWN; + } match = H5T_NATIVE_INT_MATCH_UNKNOWN; H5T_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5T_get_native_integer, NULL); + FUNC_ENTER_NOAPI(H5T_get_native_integer, NULL) if(direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) { - if(prec<=H5Tget_precision(H5T_NATIVE_SCHAR)) { - match=H5T_NATIVE_INT_MATCH_CHAR; + if(prec <= H5Tget_precision(H5T_NATIVE_SCHAR)) { + match = H5T_NATIVE_INT_MATCH_CHAR; native_size = sizeof(char); } else if(prec<=H5Tget_precision(H5T_NATIVE_SHORT)) { - match=H5T_NATIVE_INT_MATCH_SHORT; + match = H5T_NATIVE_INT_MATCH_SHORT; native_size = sizeof(short); } else if(prec<=H5Tget_precision(H5T_NATIVE_INT)) { - match=H5T_NATIVE_INT_MATCH_INT; + match = H5T_NATIVE_INT_MATCH_INT; native_size = sizeof(int); - } else if(prec<=H5Tget_precision(H5T_NATIVE_LONG)) { - match=H5T_NATIVE_INT_MATCH_LONG; + } else if(prec <= H5Tget_precision(H5T_NATIVE_LONG)) { + match = H5T_NATIVE_INT_MATCH_LONG; native_size = sizeof(long); - } else if(prec<=H5Tget_precision(H5T_NATIVE_LLONG)) { - match=H5T_NATIVE_INT_MATCH_LLONG; + } else if(prec <= H5Tget_precision(H5T_NATIVE_LLONG)) { + match = H5T_NATIVE_INT_MATCH_LLONG; native_size = sizeof(long long); } else { /* If no native type matches the querried datatype, simply choose the type of biggest size. */ - match=H5T_NATIVE_INT_MATCH_LLONG; + match = H5T_NATIVE_INT_MATCH_LLONG; native_size = sizeof(long long); } } else if(direction == H5T_DIR_DESCEND) { - if(prec>H5Tget_precision(H5T_NATIVE_LONG)) { - match=H5T_NATIVE_INT_MATCH_LLONG; + if(prec > H5Tget_precision(H5T_NATIVE_LONG)) { + match = H5T_NATIVE_INT_MATCH_LLONG; native_size = sizeof(long long); - } else if(prec>H5Tget_precision(H5T_NATIVE_INT)) { - match=H5T_NATIVE_INT_MATCH_LONG; + } else if(prec > H5Tget_precision(H5T_NATIVE_INT)) { + match = H5T_NATIVE_INT_MATCH_LONG; native_size = sizeof(long); - } else if(prec>H5Tget_precision(H5T_NATIVE_SHORT)) { - match=H5T_NATIVE_INT_MATCH_INT; + } else if(prec > H5Tget_precision(H5T_NATIVE_SHORT)) { + match = H5T_NATIVE_INT_MATCH_INT; native_size = sizeof(int); - } else if(prec>H5Tget_precision(H5T_NATIVE_SCHAR)) { - match=H5T_NATIVE_INT_MATCH_SHORT; + } else if(prec > H5Tget_precision(H5T_NATIVE_SCHAR)) { + match = H5T_NATIVE_INT_MATCH_SHORT; native_size = sizeof(short); } else { - match=H5T_NATIVE_INT_MATCH_CHAR; + match = H5T_NATIVE_INT_MATCH_CHAR; native_size = sizeof(char); } } @@ -605,7 +612,7 @@ H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, /* Set the appropriate native datatype information */ switch(match) { case H5T_NATIVE_INT_MATCH_CHAR: - if(sign==H5T_SGN_2) + if(sign == H5T_SGN_2) tid = H5T_NATIVE_SCHAR; else tid = H5T_NATIVE_UCHAR; @@ -614,7 +621,7 @@ H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, break; case H5T_NATIVE_INT_MATCH_SHORT: - if(sign==H5T_SGN_2) + if(sign == H5T_SGN_2) tid = H5T_NATIVE_SHORT; else tid = H5T_NATIVE_USHORT; @@ -622,7 +629,7 @@ H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, break; case H5T_NATIVE_INT_MATCH_INT: - if(sign==H5T_SGN_2) + if(sign == H5T_SGN_2) tid = H5T_NATIVE_INT; else tid = H5T_NATIVE_UINT; @@ -631,7 +638,7 @@ H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, break; case H5T_NATIVE_INT_MATCH_LONG: - if(sign==H5T_SGN_2) + if(sign == H5T_SGN_2) tid = H5T_NATIVE_LONG; else tid = H5T_NATIVE_ULONG; @@ -640,7 +647,7 @@ H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, break; case H5T_NATIVE_INT_MATCH_LLONG: - if(sign==H5T_SGN_2) + if(sign == H5T_SGN_2) tid = H5T_NATIVE_LLONG; else tid = H5T_NATIVE_ULLONG; @@ -654,21 +661,20 @@ H5T_get_native_integer(size_t prec, H5T_sign_t sign, H5T_direction_t direction, } /* end switch */ /* Create new native type */ - assert(tid>=0); - if(NULL==(dt=(H5T_t *)H5I_object(tid))) + HDassert(tid >= 0); + if(NULL == (dt = (H5T_t *)H5I_object(tid))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "not a data type") - if((ret_value=H5T_copy(dt, H5T_COPY_TRANSIENT))==NULL) + if(NULL == (ret_value = H5T_copy(dt, H5T_COPY_TRANSIENT))) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot copy type") /* compute size and offset of compound type member. */ - if(H5T_cmp_offset(comp_size, offset, native_size, (size_t)1, align, struct_align)<0) + if(H5T_cmp_offset(comp_size, offset, native_size, (size_t)1, align, struct_align) < 0) HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, NULL, "cannot compute compound offset") done: FUNC_LEAVE_NOAPI(ret_value) -} - +} /* end H5T_get_native_integer() */ /*------------------------------------------------------------------------- @@ -683,8 +689,6 @@ done: * Programmer: Raymond Lu * Oct 3, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ static H5T_t* @@ -810,8 +814,6 @@ done: * Programmer: Raymond Lu * 1 December 2009 * - * Modifications: - * *------------------------------------------------------------------------- */ static H5T_t* @@ -824,7 +826,7 @@ H5T_get_native_bitfield(size_t prec, H5T_direction_t direction, size_t *struct_a size_t native_size=0; /* Datatype size of the native type */ H5T_t *ret_value; /* Return value */ - FUNC_ENTER_NOAPI(H5T_get_native_bitfield, NULL); + FUNC_ENTER_NOAPI(H5T_get_native_bitfield, NULL) if(direction == H5T_DIR_DEFAULT || direction == H5T_DIR_ASCEND) { if(prec<=H5Tget_precision(H5T_NATIVE_B8)) { @@ -899,8 +901,6 @@ done: * Programmer: Raymond Lu * December 10, 2002 * - * Modifications: - * *------------------------------------------------------------------------- */ static herr_t diff --git a/src/H5Znbit.c b/src/H5Znbit.c index bcdd549..263b2cd 100644 --- a/src/H5Znbit.c +++ b/src/H5Znbit.c @@ -1365,17 +1365,17 @@ static void H5Z_nbit_compress_one_compound(unsigned char *data, size_t data_offs static void H5Z_nbit_compress(unsigned char *data, unsigned d_nelmts, unsigned char *buffer, size_t *buffer_size, const unsigned parms[]) { - /* i: index of data, j: index of buffer, + /* i: index of data, new_size: index of buffer, buf_len: number of bits to be filled in current byte */ - size_t i, j, size; + size_t i, size; + size_t new_size = 0; int buf_len; parms_atomic p; /* must initialize buffer to be zeros */ - for(j = 0; j < *buffer_size; j++) buffer[j] = 0; + HDmemset(buffer, 0, *buffer_size); /* initialization before the loop */ - j = 0; buf_len = sizeof(unsigned char) * 8; switch(parms[3]) { @@ -1387,14 +1387,14 @@ static void H5Z_nbit_compress(unsigned char *data, unsigned d_nelmts, unsigned c p.offset = parms[7]; for(i = 0; i < d_nelmts; i++) { - H5Z_nbit_compress_one_atomic(data, i*p.size, buffer, &j, &buf_len, p); + H5Z_nbit_compress_one_atomic(data, i*p.size, buffer, &new_size, &buf_len, p); } break; case H5Z_NBIT_ARRAY: size = parms[4]; parms_index = 4; for(i = 0; i < d_nelmts; i++) { - H5Z_nbit_compress_one_array(data, i*size, buffer, &j, &buf_len, parms); + H5Z_nbit_compress_one_array(data, i*size, buffer, &new_size, &buf_len, parms); parms_index = 4; } break; @@ -1402,10 +1402,14 @@ static void H5Z_nbit_compress(unsigned char *data, unsigned d_nelmts, unsigned c size = parms[4]; parms_index = 4; for(i = 0; i < d_nelmts; i++) { - H5Z_nbit_compress_one_compound(data, i*size, buffer, &j, &buf_len, parms); + H5Z_nbit_compress_one_compound(data, i*size, buffer, &new_size, &buf_len, parms); parms_index = 4; } break; } /* end switch */ + + /* Update the size to the new value after compression. If there are any bits hanging over in + * the last byte, increment the value by 1. */ + *buffer_size = new_size + 1; } #endif /* H5_HAVE_FILTER_NBIT */ diff --git a/src/H5Zscaleoffset.c b/src/H5Zscaleoffset.c index eb3c6e6..c524141 100644 --- a/src/H5Zscaleoffset.c +++ b/src/H5Zscaleoffset.c @@ -53,16 +53,16 @@ static size_t H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts, static void H5Z_scaleoffset_convert(void *buf, unsigned d_nelmts, size_t dtype_size); static unsigned H5Z_scaleoffset_log2(unsigned long long num); static void H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts, - enum H5Z_scaleoffset_t type, unsigned filavail, const void *filval_buf, + enum H5Z_scaleoffset_t type, unsigned filavail, const unsigned cd_values[], uint32_t *minbits, unsigned long long *minval); static void H5Z_scaleoffset_postdecompress_i(void *data, unsigned d_nelmts, - enum H5Z_scaleoffset_t type, unsigned filavail, const void *filval_buf, + enum H5Z_scaleoffset_t type, unsigned filavail, const unsigned cd_values[], uint32_t minbits, unsigned long long minval); static herr_t H5Z_scaleoffset_precompress_fd(void *data, unsigned d_nelmts, - enum H5Z_scaleoffset_t type, unsigned filavail, const void *filval_buf, + enum H5Z_scaleoffset_t type, unsigned filavail, const unsigned cd_values[], uint32_t *minbits, unsigned long long *minval, double D_val); static herr_t H5Z_scaleoffset_postdecompress_fd(void *data, unsigned d_nelmts, - enum H5Z_scaleoffset_t type, unsigned filavail, const void *filval_buf, + enum H5Z_scaleoffset_t type, unsigned filavail, const unsigned cd_values[], uint32_t minbits, unsigned long long minval, double D_val); static void H5Z_scaleoffset_next_byte(size_t *j, unsigned *buf_len); static void H5Z_scaleoffset_decompress_one_byte(unsigned char *data, size_t data_offset, @@ -119,24 +119,71 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ /* Store fill value in cd_values[] */ #define H5Z_scaleoffset_save_filval(type, cd_values, fill_val) \ { \ - unsigned char *fill_parm; /* Pointer to fill value parameter */ \ + unsigned _i = H5Z_SCALEOFFSET_PARM_FILVAL; /* index into cd_values */ \ + uint32_t _cd_value; /* Current cd_value */ \ + char *_fv_p; /* Pointer to current byte in fill_val */ \ + size_t _copy_size = 4; /* # of bytes to copy this iteration */ \ + size_t _size_rem = sizeof(type); /* # of bytes left to copy to cd_values */ \ \ /* Store the fill value as the last entry in cd_values[] \ * Store byte by byte from least significant byte to most significant byte \ * Plenty of space left for the fill value (from index 8 to 19) \ + * H5O_pline_encode will byte-swap each individual cd value, but we still \ + * need to swap the cd values as a whole if we are on a BE machine. Note \ + * that we need to make sure to put the data only in the lowest 4 bytes of \ + * each, if sizeof(unsigned) > 4. \ */ \ - fill_parm = (unsigned char *)&cd_values[H5Z_SCALEOFFSET_PARM_FILVAL]; \ - if(H5T_native_order_g == H5T_ORDER_LE) \ - HDmemcpy(fill_parm, &fill_val, sizeof(type)); \ - else { \ - unsigned char *fill_buf; /* Pointer to fill value in memory */ \ - unsigned u; /* index */ \ + if(H5T_native_order_g == H5T_ORDER_LE) { \ + _fv_p = (char *)&(fill_val); \ + /* Copy 4 bytes at a time to each cd value */ \ + do { \ + if(_size_rem < 4) { \ + /* Amount left to copy is smaller than a cd_value, adjust copy \ + * size and initialize cd_value as it will not be fully \ + * overwritten */ \ + _copy_size = _size_rem; \ + _cd_value = (uint32_t)0; \ + } /* end if */ \ + \ + /* Copy the value */ \ + HDmemcpy(&_cd_value, _fv_p, _copy_size); \ + (cd_values)[_i] = (unsigned)_cd_value; \ \ + /* Next field */ \ + _i++; \ + _fv_p += _copy_size; \ + _size_rem -= _copy_size; \ + } while(_size_rem); \ + } /* end if */ \ + else { \ HDassert(H5T_native_order_g == H5T_ORDER_BE); \ \ - fill_buf = (unsigned char *)&fill_val; \ - for(u = 0; u < sizeof(type); u++) \ - fill_parm[u] = fill_buf[sizeof(type) - (u + 1)]; \ + /* Copy 4 bytes at a time to each cd value, but start at the end \ + * (highest address) of fill_val */ \ + _fv_p = ((char *)&(fill_val)) + sizeof(type) - MIN(4, _size_rem); \ + while(_size_rem >= 4) { \ + /* Copy the value */ \ + HDmemcpy(&_cd_value, _fv_p, _copy_size); \ + (cd_values)[_i] = (unsigned)_cd_value; \ + \ + /* Next field */ \ + _i++; \ + _size_rem -= 4; \ + if(_size_rem >= 4) \ + _fv_p -= 4; \ + else \ + _fv_p -= _size_rem; \ + } /* end while */ \ + \ + HDassert(_fv_p == (char *)&(fill_val)); \ + if(_size_rem) { \ + /* Amount left to copy is smaller than a cd_value, initialize \ + * _cd_value as it will not be fully overwritten and copy to the end \ + * of _cd value as it is BE. */ \ + _cd_value = (uint32_t)0; \ + HDmemcpy((char *)&_cd_value + 4 - _size_rem, _fv_p, _size_rem); \ + (cd_values)[_i] = (unsigned)_cd_value; \ + } /* end if */ \ } /* end else */ \ } @@ -180,7 +227,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ HGOTO_ERROR(H5E_PLINE, H5E_CANTGET, FAIL, "unable to get fill value") \ \ /* Store the fill value as the last entry in cd_values[] */ \ - ((unsigned char *)&cd_values[H5Z_SCALEOFFSET_PARM_FILVAL])[0] = (unsigned char)fill_val; \ + (cd_values)[H5Z_SCALEOFFSET_PARM_FILVAL] = (unsigned)((unsigned char)fill_val); \ } /* Set the fill value parameter in cd_values[] for floating-point type */ @@ -199,33 +246,78 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* Get the fill value for integer type */ -#define H5Z_scaleoffset_get_filval_1(type, filval_buf, filval) \ -{ \ - const unsigned char *fill_parm; /* Pointer to fill value parameter */ \ - \ - /* retrieve fill value from corresponding positions of cd_values[] \ - * retrieve them corresponding to how they are stored \ - */ \ - fill_parm = (const unsigned char *)filval_buf; \ - if(H5T_native_order_g == H5T_ORDER_LE) \ - HDmemcpy(&filval, fill_parm, sizeof(type)); \ - else { \ - unsigned char *fill_buf; /* Pointer to fill value in memory */ \ - unsigned u; /* index */ \ - \ - HDassert(H5T_native_order_g == H5T_ORDER_BE); \ - \ - fill_buf = (unsigned char *)&filval; \ - for(u = 0; u < sizeof(type); u++) \ - fill_buf[u] = fill_parm[sizeof(type) - (u + 1)]; \ - } /* end else */ \ +#define H5Z_scaleoffset_get_filval_1(type, cd_values, fill_val) \ +{ \ + unsigned _i = H5Z_SCALEOFFSET_PARM_FILVAL; /* index into cd_values */ \ + uint32_t _cd_value; /* Current cd_value */ \ + char *_fv_p; /* Pointer to current byte in fill_val */ \ + size_t _copy_size = 4; /* # of bytes to copy this iteration */ \ + size_t _size_rem = sizeof(type); /* # of bytes left to copy to filval */ \ + \ + /* Retrieve the fill value from the last entry in cd_values[] \ + * Store byte by byte from least significant byte to most significant byte \ + * Plenty of space left for the fill value (from index 8 to 19) \ + * H5O_pline_encode will byte-swap each individual cd value, but we still \ + * need to swap the cd values as a whole if we are on a BE machine. Note \ + * that we need to make sure to put the data only in the lowest 4 bytes of \ + * each, if sizeof(unsigned) > 4. \ + */ \ + if(H5T_native_order_g == H5T_ORDER_LE) { \ + _fv_p = (char *)&(fill_val); \ + /* Copy 4 bytes at a time to each cd value */ \ + do { \ + if(_size_rem < 4) \ + /* Amount left to copy is smaller than a cd_value, adjust copy \ + * size and initialize cd_value as it will not be fully \ + * overwritten */ \ + _copy_size = _size_rem; \ + \ + /* Copy the value */ \ + _cd_value = (uint32_t)(cd_values)[_i]; \ + HDmemcpy(_fv_p, &_cd_value, _copy_size); \ + \ + /* Next field */ \ + _i++; \ + _fv_p += _copy_size; \ + _size_rem -= _copy_size; \ + } while(_size_rem); \ + } /* end if */ \ + else { \ + HDassert(H5T_native_order_g == H5T_ORDER_BE); \ + \ + /* Copy 4 bytes at a time to each cd value, but start at the end \ + * (highest address) of fill_val */ \ + _fv_p = ((char *)&(fill_val)) + sizeof(type) - MIN(4, _size_rem); \ + while(_size_rem >= 4) { \ + /* Copy the value */ \ + _cd_value = (uint32_t)(cd_values)[_i]; \ + HDmemcpy(_fv_p, &_cd_value, _copy_size); \ + \ + /* Next field */ \ + _i++; \ + _size_rem -= 4; \ + if(_size_rem >=4) \ + _fv_p -= 4; \ + else \ + _fv_p -= _size_rem; \ + } /* end while */ \ + \ + HDassert(_fv_p == (char *)&(fill_val)); \ + if(_size_rem) { \ + /* Amount left to copy is smaller than a cd_value, initialize \ + * _cd_value as it will not be fully overwritten and copy to the end \ + * of _cd value as it is BE. */ \ + _cd_value = (uint32_t)(cd_values)[_i]; \ + HDmemcpy(_fv_p, (char *)&_cd_value + 4 - _size_rem, _size_rem); \ + } /* end if */ \ + } /* end else */ \ } /* Get the fill value for floating-point type */ -#define H5Z_scaleoffset_get_filval_2(type, filval_buf, filval) \ +#define H5Z_scaleoffset_get_filval_2(type, cd_values, filval) \ { \ if(sizeof(type) <= sizeof(long long)) \ - H5Z_scaleoffset_get_filval_1(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_1(type, cd_values, filval) \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } @@ -258,7 +350,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ i = 0; while(i < d_nelmts && HDfabs(buf[i] - filval) < HDpow(10.0, -D_val)) i++; \ if(i < d_nelmts) min = max = buf[i]; \ for(; i < d_nelmts; i++) { \ - if(HDfabs(buf[i] - filval) < HDpow(10.0, -D_val)) \ + if(HDfabs(buf[i] - filval) < HDpow(10.0, -D_val)) \ continue; /* ignore fill value */ \ if(buf[i] > max) max = buf[i]; \ if(buf[i] < min) min = buf[i]; \ @@ -321,13 +413,13 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* Precompress for unsigned integer type */ -#define H5Z_scaleoffset_precompress_1(type, data, d_nelmts, filavail, filval_buf, minbits, minval)\ +#define H5Z_scaleoffset_precompress_1(type, data, d_nelmts, filavail, cd_values, minbits, minval)\ { \ type *buf = (type *)data, min = 0, max = 0, span, filval = 0; \ unsigned i; \ \ if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \ - H5Z_scaleoffset_get_filval_1(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_1(type, cd_values, filval) \ if(*minbits == H5Z_SO_INT_MINBITS_DEFAULT) { /* minbits not set yet, calculate max, min, and minbits */ \ H5Z_scaleoffset_max_min_1(i, d_nelmts, buf, filval, max, min) \ H5Z_scaleoffset_check_1(type, max, min, minbits) \ @@ -354,13 +446,13 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* Precompress for signed integer type */ -#define H5Z_scaleoffset_precompress_2(type, data, d_nelmts, filavail, filval_buf, minbits, minval)\ +#define H5Z_scaleoffset_precompress_2(type, data, d_nelmts, filavail, cd_values, minbits, minval)\ { \ type *buf = (type *)data, min = 0, max = 0, filval = 0; \ unsigned type span; unsigned i; \ \ if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \ - H5Z_scaleoffset_get_filval_1(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_1(type, cd_values, filval) \ if(*minbits == H5Z_SO_INT_MINBITS_DEFAULT) { /* minbits not set yet, calculate max, min, and minbits */ \ H5Z_scaleoffset_max_min_1(i, d_nelmts, buf, filval, max, min) \ H5Z_scaleoffset_check_2(type, max, min, minbits) \ @@ -423,15 +515,15 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ if(sizeof(type)==sizeof(int)) \ for(i = 0; i < d_nelmts; i++) \ *(int *)&buf[i] = H5Z_scaleoffset_rnd( \ - buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \ + buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \ else if(sizeof(type)==sizeof(long)) \ for(i = 0; i < d_nelmts; i++) \ *(long *)&buf[i] = H5Z_scaleoffset_rnd( \ - buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \ + buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \ else if(sizeof(type)==sizeof(long long)) \ for(i = 0; i < d_nelmts; i++) \ *(long long *)&buf[i] = H5Z_scaleoffset_rnd( \ - buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \ + buf[i]*HDpow(10.0, D_val) - min*HDpow(10.0, D_val)); \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype")\ } @@ -439,38 +531,33 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ /* Save the minimum value for floating-point type */ #define H5Z_scaleoffset_save_min(i, type, minval, min) \ { \ - if(sizeof(type) <= sizeof(long long)) { \ - unsigned char *min_parm; /* Pointer to min value parameter */ \ - \ - min_parm = (unsigned char *)minval; \ + if(sizeof(type) <= sizeof(long long)) \ + /* Save min value to corresponding position \ + * byte-order will be swapped as appropriate, but be sure to \ + * account for offset in BE if sizes differ \ + */ \ if(H5T_native_order_g == H5T_ORDER_LE) \ - HDmemcpy(min_parm, &min, sizeof(type)); \ + HDmemcpy(minval, &min, sizeof(type)); \ else { \ - unsigned char *min_buf; /* Pointer to min value in memory */ \ - unsigned u; /* index */ \ - \ HDassert(H5T_native_order_g == H5T_ORDER_BE); \ - \ - min_buf = (unsigned char *)&min; \ - for(u = 0; u < sizeof(type); u++) \ - min_parm[u] = min_buf[sizeof(type) - (u + 1)]; \ + HDmemcpy(((char *)minval) + (sizeof(long long) - sizeof(type)), \ + &min, sizeof(type)); \ } /* end else */ \ - } /* end if */ \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } /* Precompress for floating-point type using variable-minimum-bits method */ -#define H5Z_scaleoffset_precompress_3(type, data, d_nelmts, filavail, filval_buf, \ +#define H5Z_scaleoffset_precompress_3(type, data, d_nelmts, filavail, cd_values, \ minbits, minval, D_val) \ { \ - type *buf = (type *)data, min = 0, max = 0, filval = 0; \ + type *buf = (type *)data, min = 0, max = 0, filval = 0; \ unsigned long long span; \ unsigned i; \ \ *minval = 0; \ if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \ - H5Z_scaleoffset_get_filval_2(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_2(type, cd_values, filval) \ H5Z_scaleoffset_max_min_3(i, d_nelmts, buf, filval, max, min, D_val) \ H5Z_scaleoffset_check_3(i, type, max, min, minbits, D_val) \ span = H5Z_scaleoffset_rnd(max * HDpow(10.0, D_val) - min * HDpow(10.0, D_val)) + 1; \ @@ -489,12 +576,12 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* Postdecompress for unsigned integer type */ -#define H5Z_scaleoffset_postdecompress_1(type, data, d_nelmts, filavail, filval_buf, minbits, minval)\ +#define H5Z_scaleoffset_postdecompress_1(type, data, d_nelmts, filavail, cd_values, minbits, minval)\ { \ type *buf = (type *)data, filval = 0; unsigned i; \ \ if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \ - H5Z_scaleoffset_get_filval_1(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_1(type, cd_values, filval) \ for(i = 0; i < d_nelmts; i++) \ buf[i] = (type)((buf[i] == (((type)1 << minbits) - 1)) ? filval : (buf[i] + minval)); \ } else /* fill value undefined */ \ @@ -502,13 +589,13 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* Postdecompress for signed integer type */ -#define H5Z_scaleoffset_postdecompress_2(type, data, d_nelmts, filavail, filval_buf, minbits, minval)\ +#define H5Z_scaleoffset_postdecompress_2(type, data, d_nelmts, filavail, cd_values, minbits, minval)\ { \ type *buf = (type *)data, filval = 0; \ unsigned i; \ \ if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \ - H5Z_scaleoffset_get_filval_1(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_1(type, cd_values, filval) \ for(i = 0; i < d_nelmts; i++) \ buf[i] = (type)(((unsigned type)buf[i] == (((unsigned type)1 << minbits) - 1)) ? filval : (buf[i] + minval));\ } else /* fill value undefined */ \ @@ -519,26 +606,18 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ /* Retrive minimum value of floating-point type */ #define H5Z_scaleoffset_get_min(type, minval, min) \ { \ - if(sizeof(type) <= sizeof(long long)) { \ - const unsigned char *min_parm; /* Pointer to min value parameter */ \ - \ - /* retrieve min value from corresponding positions \ - * retrieve them corresponding to how they are stored \ + if(sizeof(type) <= sizeof(long long)) \ + /* retrieve min value from corresponding position \ + * byte-order has already been swapped as appropriate, but be sure to \ + * account for offset in BE if sizes differ \ */ \ - min_parm = (const unsigned char *)&minval; \ if(H5T_native_order_g == H5T_ORDER_LE) \ - HDmemcpy(&min, min_parm, sizeof(type)); \ + HDmemcpy(&min, &minval, sizeof(type)); \ else { \ - unsigned char *min_buf; /* Pointer to min value in memory */ \ - unsigned u; /* index */ \ - \ HDassert(H5T_native_order_g == H5T_ORDER_BE); \ - \ - min_buf = (unsigned char *)&min; \ - for(u = 0; u < sizeof(type); u++) \ - min_buf[u] = min_parm[sizeof(type) - (u + 1)]; \ + HDmemcpy(&min, ((char *)&minval) + (sizeof(long long) \ + - sizeof(type)), sizeof(type)); \ } /* end else */ \ - } /* end if */ \ else \ HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, FAIL, "cannot find matched integer dataype") \ } @@ -579,7 +658,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ } /* Postdecompress for floating-point type using variable-minimum-bits method */ -#define H5Z_scaleoffset_postdecompress_3(type, data, d_nelmts, filavail, filval_buf, \ +#define H5Z_scaleoffset_postdecompress_3(type, data, d_nelmts, filavail, cd_values, \ minbits, minval, D_val) \ { \ type *buf = (type *)data, filval = 0, min = 0; \ @@ -588,7 +667,7 @@ H5Z_class2_t H5Z_SCALEOFFSET[1] = {{ H5Z_scaleoffset_get_min(type, minval, min) \ \ if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ \ - H5Z_scaleoffset_get_filval_2(type, filval_buf, filval) \ + H5Z_scaleoffset_get_filval_2(type, cd_values, filval) \ H5Z_scaleoffset_modify_3(i, type, buf, d_nelmts, filval, minbits, min, D_val) \ } else /* fill value undefined */ \ H5Z_scaleoffset_modify_4(i, type, buf, d_nelmts, min, D_val) \ @@ -1125,12 +1204,12 @@ H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_value /* postprocess after decompression */ if(dtype_class==H5Z_SCALEOFFSET_CLS_INTEGER) H5Z_scaleoffset_postdecompress_i(outbuf, d_nelmts, type, filavail, - &cd_values[H5Z_SCALEOFFSET_PARM_FILVAL], minbits, minval); + cd_values, minbits, minval); if(dtype_class==H5Z_SCALEOFFSET_CLS_FLOAT) if(scale_type==0) { /* variable-minimum-bits method */ if(H5Z_scaleoffset_postdecompress_fd(outbuf, d_nelmts, type, filavail, - &cd_values[H5Z_SCALEOFFSET_PARM_FILVAL], minbits, minval, D_val)==FAIL) + cd_values, minbits, minval, D_val)==FAIL) HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, 0, "post-decompression failed") } @@ -1153,12 +1232,12 @@ H5Z_filter_scaleoffset(unsigned flags, size_t cd_nelmts, const unsigned cd_value /* preprocess before compression */ if(dtype_class==H5Z_SCALEOFFSET_CLS_INTEGER) H5Z_scaleoffset_precompress_i(*buf, d_nelmts, type, filavail, - &cd_values[H5Z_SCALEOFFSET_PARM_FILVAL], &minbits, &minval); + cd_values, &minbits, &minval); if(dtype_class==H5Z_SCALEOFFSET_CLS_FLOAT) if(scale_type==0) { /* variable-minimum-bits method */ if(H5Z_scaleoffset_precompress_fd(*buf, d_nelmts, type, filavail, - &cd_values[H5Z_SCALEOFFSET_PARM_FILVAL], &minbits, &minval, D_val)==FAIL) + cd_values, &minbits, &minval, D_val)==FAIL) HGOTO_ERROR(H5E_PLINE, H5E_BADTYPE, 0, "pre-compression failed") } @@ -1308,30 +1387,30 @@ H5Z_scaleoffset_log2(unsigned long long num) /* precompress for integer type */ static void H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_t type, - unsigned filavail, const void *filval_buf, uint32_t *minbits, unsigned long long *minval) + unsigned filavail, const unsigned cd_values[], uint32_t *minbits, unsigned long long *minval) { if(type == t_uchar) H5Z_scaleoffset_precompress_1(unsigned char, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_ushort) H5Z_scaleoffset_precompress_1(unsigned short, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_uint) H5Z_scaleoffset_precompress_1(unsigned int, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_ulong) H5Z_scaleoffset_precompress_1(unsigned long, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_ulong_long) H5Z_scaleoffset_precompress_1(unsigned long long, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_schar) { signed char *buf = (signed char *)data, min = 0, max = 0, filval = 0; unsigned char span; unsigned i; if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ - H5Z_scaleoffset_get_filval_1(signed char, filval_buf, filval); + H5Z_scaleoffset_get_filval_1(signed char, cd_values, filval); if(*minbits == H5Z_SO_INT_MINBITS_DEFAULT) { /* minbits not set yet, calculate max, min, and minbits */ H5Z_scaleoffset_max_min_1(i, d_nelmts, buf, filval, max, min) if((unsigned char)(max - min) > (unsigned char)(~(unsigned char)0 - 2)) { @@ -1365,46 +1444,46 @@ H5Z_scaleoffset_precompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleoffse } else if(type == t_short) H5Z_scaleoffset_precompress_2(short, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_int) H5Z_scaleoffset_precompress_2(int, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_long) H5Z_scaleoffset_precompress_2(long, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) else if(type == t_long_long) H5Z_scaleoffset_precompress_2(long long, data, d_nelmts, - filavail, filval_buf, minbits, minval) + filavail, cd_values, minbits, minval) } /* postdecompress for integer type */ static void H5Z_scaleoffset_postdecompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_t type, - unsigned filavail, const void *filval_buf, uint32_t minbits, unsigned long long minval) + unsigned filavail, const unsigned cd_values[], uint32_t minbits, unsigned long long minval) { long long sminval = *(long long*)&minval; /* for signed integer types */ if(type == t_uchar) H5Z_scaleoffset_postdecompress_1(unsigned char, data, d_nelmts, filavail, - filval_buf, minbits, minval) + cd_values, minbits, minval) else if(type == t_ushort) H5Z_scaleoffset_postdecompress_1(unsigned short, data, d_nelmts, filavail, - filval_buf, minbits, minval) + cd_values, minbits, minval) else if(type == t_uint) H5Z_scaleoffset_postdecompress_1(unsigned int, data, d_nelmts, filavail, - filval_buf, minbits, minval) + cd_values, minbits, minval) else if(type == t_ulong) H5Z_scaleoffset_postdecompress_1(unsigned long, data, d_nelmts, filavail, - filval_buf, minbits, minval) + cd_values, minbits, minval) else if(type == t_ulong_long) H5Z_scaleoffset_postdecompress_1(unsigned long long, data, d_nelmts, filavail, - filval_buf, minbits, minval) + cd_values, minbits, minval) else if(type == t_schar) { signed char *buf = (signed char *)data, filval = 0; unsigned i; if(filavail == H5Z_SCALEOFFSET_FILL_DEFINED) { /* fill value defined */ - H5Z_scaleoffset_get_filval_1(signed char, filval_buf, filval) + H5Z_scaleoffset_get_filval_1(signed char, cd_values, filval) for(i = 0; i < d_nelmts; i++) buf[i] = (signed char)((buf[i] == (((unsigned char)1 << minbits) - 1)) ? filval : (buf[i] + sminval)); } else /* fill value undefined */ @@ -1413,23 +1492,23 @@ H5Z_scaleoffset_postdecompress_i(void *data, unsigned d_nelmts, enum H5Z_scaleof } else if(type == t_short) H5Z_scaleoffset_postdecompress_2(short, data, d_nelmts, filavail, - filval_buf, minbits, sminval) + cd_values, minbits, sminval) else if(type == t_int) H5Z_scaleoffset_postdecompress_2(int, data, d_nelmts, filavail, - filval_buf, minbits, sminval) + cd_values, minbits, sminval) else if(type == t_long) H5Z_scaleoffset_postdecompress_2(long, data, d_nelmts, filavail, - filval_buf, minbits, sminval) + cd_values, minbits, sminval) else if(type == t_long_long) H5Z_scaleoffset_postdecompress_2(long long, data, d_nelmts, filavail, - filval_buf, minbits, sminval) + cd_values, minbits, sminval) } /* precompress for floating-point type, variable-minimum-bits method success: non-negative, failure: negative 4/15/05 */ static herr_t H5Z_scaleoffset_precompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_t type, - unsigned filavail, const void *filval_buf, uint32_t *minbits, + unsigned filavail, const unsigned cd_values[], uint32_t *minbits, unsigned long long *minval, double D_val) { herr_t ret_value=SUCCEED; /* Return value */ @@ -1438,10 +1517,10 @@ H5Z_scaleoffset_precompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleoffs if(type == t_float) H5Z_scaleoffset_precompress_3(float, data, d_nelmts, - filavail, filval_buf, minbits, minval, D_val) + filavail, cd_values, minbits, minval, D_val) else if(type == t_double) H5Z_scaleoffset_precompress_3(double, data, d_nelmts, - filavail, filval_buf, minbits, minval, D_val) + filavail, cd_values, minbits, minval, D_val) done: FUNC_LEAVE_NOAPI(ret_value) @@ -1451,7 +1530,7 @@ done: success: non-negative, failure: negative 4/15/05 */ static herr_t H5Z_scaleoffset_postdecompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleoffset_t type, - unsigned filavail, const void *filval_buf, uint32_t minbits, + unsigned filavail, const unsigned cd_values[], uint32_t minbits, unsigned long long minval, double D_val) { long long sminval = (long long)minval; /* for signed integer types */ @@ -1461,10 +1540,10 @@ H5Z_scaleoffset_postdecompress_fd(void *data, unsigned d_nelmts, enum H5Z_scaleo if(type == t_float) H5Z_scaleoffset_postdecompress_3(float, data, d_nelmts, filavail, - filval_buf, minbits, sminval, D_val) + cd_values, minbits, sminval, D_val) else if(type == t_double) H5Z_scaleoffset_postdecompress_3(double, data, d_nelmts, filavail, - filval_buf, minbits, sminval, D_val) + cd_values, minbits, sminval, D_val) done: FUNC_LEAVE_NOAPI(ret_value) diff --git a/src/H5api_adpt.h b/src/H5api_adpt.h index dbd8d94..fc0b467 100644 --- a/src/H5api_adpt.h +++ b/src/H5api_adpt.h @@ -235,7 +235,7 @@ #define H5_FCDLLVAR extern #endif /* H5_FCDLL */ -#if defined(hdf5_f90Ctest_EXPORTS) +#if defined(hdf5_test_f90cstub_EXPORTS) #if defined (_MSC_VER) /* MSVC Compiler Case */ #define H5_FCTESTDLL __declspec(dllexport) #define H5_FCTESTDLLVAR extern __declspec(dllexport) @@ -281,10 +281,26 @@ #define HDF5_HL_F90CSTUBDLLVAR extern #endif /* HDF5_HL_F90CSTUBDLL */ +#elif defined(H5_BUILT_AS_STATIC_LIB) + #define H5_DLL + #define H5_HLDLL + #define H5_HLCPPDLL + #define HDF5_HL_F90CSTUBDLL + #define H5_DLLVAR extern + #define H5_DLLCPP + #define H5TEST_DLL + #define H5TEST_DLLVAR extern + #define H5TOOLS_DLL + #define H5TOOLS_DLLVAR extern + #define H5_FCDLL + #define H5_FCDLLVAR extern + #define H5_FCTESTDLL + #define H5_FCTESTDLLVAR extern + #else /* This is the original HDFGroup defined preprocessor code which should still work * with the VS projects that are maintained by "The HDF Group" - * This will be removed after the next release. + * The Visual Studio project files will not be supported in the next major release of 1.10. */ #if defined(_WIN32) diff --git a/src/H5private.h b/src/H5private.h index f13ad84..9cebdaa 100644 --- a/src/H5private.h +++ b/src/H5private.h @@ -403,11 +403,6 @@ # error "nothing appropriate for int32_t" #endif -/* Definition of uint32_t was moved to H5public.h */ - -/* Definition of int64_t was moved to H5public.h */ -/* Definition of uint64_t was moved to H5public.h */ - /* * Maximum and minimum values. These should be defined in <limits.h> for the * most part. diff --git a/src/H5public.h b/src/H5public.h index 076069e..47fe27b 100644 --- a/src/H5public.h +++ b/src/H5public.h @@ -75,10 +75,10 @@ extern "C" { /* Version numbers */ #define H5_VERS_MAJOR 1 /* For major interface/format changes */ #define H5_VERS_MINOR 9 /* For minor interface/format changes */ -#define H5_VERS_RELEASE 79 /* For tweaks, bug-fixes, or development */ +#define H5_VERS_RELEASE 80 /* For tweaks, bug-fixes, or development */ #define H5_VERS_SUBRELEASE "FA_a5" /* For pre-releases like snap0 */ /* Empty string for real releases. */ -#define H5_VERS_INFO "HDF5 library version: 1.9.79-FA_a5" /* Full version string */ +#define H5_VERS_INFO "HDF5 library version: 1.9.80-FA_a5" /* Full version string */ #define H5check() H5check_version(H5_VERS_MAJOR,H5_VERS_MINOR, \ H5_VERS_RELEASE) diff --git a/src/H5trace.c b/src/H5trace.c index 8e645af..67a85c5 100644 --- a/src/H5trace.c +++ b/src/H5trace.c @@ -1974,6 +1974,10 @@ H5_trace(const double *returning, const char *func, const char *type, ...) fprintf(out, "H5T_ORDER_VAX"); break; + case H5T_ORDER_MIXED: + fprintf(out, "H5T_ORDER_MIXED"); + break; + case H5T_ORDER_NONE: fprintf(out, "H5T_ORDER_NONE"); break; diff --git a/src/H5win32defs.h b/src/H5win32defs.h index d478e4c..fb37059 100644 --- a/src/H5win32defs.h +++ b/src/H5win32defs.h @@ -56,12 +56,7 @@ typedef __int64 h5_stat_size_t; #endif /* H5_HAVE_GETTIMEOFDAY */ #define HDgetdrive() _getdrive() #define HDlseek(F,O,W) _lseeki64(F,O,W) -#if !defined(__MWERKS__) -# /*MSVC*/ -# define HDoff_t __int64 -#else -# define HDoff_t off_t -#endif +#define HDoff_t __int64 #define HDmemset(X,C,Z) memset((void*)(X),C,Z) #define HDmkdir(S,M) _mkdir(S) #define HDopen(S,F,M) _open(S,F|_O_BINARY,M) diff --git a/src/Makefile.am b/src/Makefile.am index b6acdd6..9d27bbf 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -53,8 +53,8 @@ libhdf5_la_SOURCES= H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ - H5F.c H5Faccum.c H5Fdbg.c H5Fdeprec.c H5Ffake.c H5Fio.c H5Fmount.c \ - H5Fmpi.c H5Fquery.c \ + H5F.c H5Faccum.c H5Fdbg.c H5Fdeprec.c H5Fefc.c H5Ffake.c H5Fio.c \ + H5Fmount.c H5Fmpi.c H5Fquery.c \ H5Fsfile.c H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \ H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \ H5FAstat.c H5FAtest.c \ diff --git a/src/Makefile.in b/src/Makefile.in index 5e9040c..1e72c64 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -108,15 +108,15 @@ am_libhdf5_la_OBJECTS = H5.lo H5checksum.lo H5dbg.lo H5system.lo \ H5EAcache.lo H5EAdbg.lo H5EAdblkpage.lo H5EAdblock.lo \ H5EAhdr.lo H5EAiblock.lo H5EAint.lo H5EAsblock.lo H5EAstat.lo \ H5EAtest.lo H5F.lo H5Faccum.lo H5Fdbg.lo H5Fdeprec.lo \ - H5Ffake.lo H5Fio.lo H5Fmount.lo H5Fmpi.lo H5Fquery.lo \ - H5Fsfile.lo H5Fsuper.lo H5Fsuper_cache.lo H5Ftest.lo H5FA.lo \ - H5FAcache.lo H5FAdbg.lo H5FAdblock.lo H5FAdblkpage.lo \ - H5FAhdr.lo H5FAstat.lo H5FAtest.lo H5FD.lo H5FDcore.lo \ - H5FDdirect.lo H5FDfamily.lo H5FDint.lo H5FDlog.lo H5FDmpi.lo \ - H5FDmpio.lo H5FDmpiposix.lo H5FDmulti.lo H5FDsec2.lo \ - H5FDspace.lo H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo H5FScache.lo \ - H5FSdbg.lo H5FSsection.lo H5FSstat.lo H5FStest.lo H5G.lo \ - H5Gbtree2.lo H5Gcache.lo H5Gcompact.lo H5Gdense.lo \ + H5Fefc.lo H5Ffake.lo H5Fio.lo H5Fmount.lo H5Fmpi.lo \ + H5Fquery.lo H5Fsfile.lo H5Fsuper.lo H5Fsuper_cache.lo \ + H5Ftest.lo H5FA.lo H5FAcache.lo H5FAdbg.lo H5FAdblock.lo \ + H5FAdblkpage.lo H5FAhdr.lo H5FAstat.lo H5FAtest.lo H5FD.lo \ + H5FDcore.lo H5FDdirect.lo H5FDfamily.lo H5FDint.lo H5FDlog.lo \ + H5FDmpi.lo H5FDmpio.lo H5FDmpiposix.lo H5FDmulti.lo \ + H5FDsec2.lo H5FDspace.lo H5FDstdio.lo H5FL.lo H5FO.lo H5FS.lo \ + H5FScache.lo H5FSdbg.lo H5FSsection.lo H5FSstat.lo H5FStest.lo \ + H5G.lo H5Gbtree2.lo H5Gcache.lo H5Gcompact.lo H5Gdense.lo \ H5Gdeprec.lo H5Gent.lo H5Gint.lo H5Glink.lo H5Gloc.lo \ H5Gname.lo H5Gnode.lo H5Gobj.lo H5Goh.lo H5Groot.lo H5Gstab.lo \ H5Gtest.lo H5Gtraverse.lo H5HF.lo H5HFbtree2.lo H5HFcache.lo \ @@ -231,6 +231,7 @@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DEPRECATED_SYMBOLS = @DEPRECATED_SYMBOLS@ DIRECT_VFD = @DIRECT_VFD@ +DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ DYNAMIC_DIRS = @DYNAMIC_DIRS@ @@ -292,6 +293,7 @@ LTLIBOBJS = @LTLIBOBJS@ LT_STATIC_EXEC = @LT_STATIC_EXEC@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ MPE = @MPE@ MPI_GET_SIZE = @MPI_GET_SIZE@ @@ -348,6 +350,7 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ @@ -458,7 +461,7 @@ CHECK_CLEANFILES = *.chkexe *.chklog *.clog # Add libtool shared library version numbers to the HDF5 library # See libtool versioning documentation online. LT_VERS_INTERFACE = 6 -LT_VERS_REVISION = 69 +LT_VERS_REVISION = 70 LT_VERS_AGE = 0 H5detect_CFLAGS = -g $(AM_CFLAGS) @@ -486,8 +489,8 @@ libhdf5_la_SOURCES = H5.c H5checksum.c H5dbg.c H5system.c H5timer.c H5trace.c \ H5E.c H5Edeprec.c H5Eint.c \ H5EA.c H5EAcache.c H5EAdbg.c H5EAdblkpage.c H5EAdblock.c H5EAhdr.c \ H5EAiblock.c H5EAint.c H5EAsblock.c H5EAstat.c H5EAtest.c \ - H5F.c H5Faccum.c H5Fdbg.c H5Fdeprec.c H5Ffake.c H5Fio.c H5Fmount.c \ - H5Fmpi.c H5Fquery.c \ + H5F.c H5Faccum.c H5Fdbg.c H5Fdeprec.c H5Fefc.c H5Ffake.c H5Fio.c \ + H5Fmount.c H5Fmpi.c H5Fquery.c \ H5Fsfile.c H5Fsuper.c H5Fsuper_cache.c H5Ftest.c \ H5FA.c H5FAcache.c H5FAdbg.c H5FAdblock.c H5FAdblkpage.c H5FAhdr.c \ H5FAstat.c H5FAtest.c \ @@ -772,6 +775,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Faccum.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdbg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fdeprec.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fefc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Ffake.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fio.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/H5Fmount.Plo@am__quote@ |