tcl.git - Tcl is a high-level, general-purpose, interpreted, dynamic programming language. It was designed with the goal of being very simple but powerful.
/* * tclThread.c -- * * This file implements Platform independent thread operations. Most of * the real work is done in the platform dependent files. * * Copyright (c) 1998 by Sun Microsystems, Inc. * Copyright (c) 2008 by George Peter Staplin * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */#include"tclInt.h"/* * There are three classes of synchronization objects: mutexes, thread data * keys, and condition variables. The following are used to record the memory * used for these objects so they can be finalized. * * These statics are guarded by the mutex in the caller of * TclRememberThreadData, e.g., TclpThreadDataKeyInit */typedefstruct{int num;/* Number of objects remembered */int max;/* Max size of the array */void**list;/* List of pointers */} SyncObjRecord;static SyncObjRecord keyRecord = {0,0, NULL};static SyncObjRecord mutexRecord = {0,0, NULL};static SyncObjRecord condRecord = {0,0, NULL};/* * Prototypes of functions used only in this file. */static voidForgetSyncObject(void*objPtr, SyncObjRecord *recPtr);static voidRememberSyncObject(void*objPtr,
SyncObjRecord *recPtr);/* * Several functions are #defined to nothing in tcl.h if TCL_THREADS is not * specified. Here we undo that so the functions are defined in the stubs * table. */#ifndef TCL_THREADS#undef Tcl_MutexLock#undef Tcl_MutexUnlock#undef Tcl_MutexFinalize#undef Tcl_ConditionNotify#undef Tcl_ConditionWait#undef Tcl_ConditionFinalize#endif/* *---------------------------------------------------------------------- * * Tcl_GetThreadData -- * * This function allocates and initializes a chunk of thread local * storage. * * Results: * A thread-specific pointer to the data structure. * * Side effects: * Will allocate memory the first time this thread calls for this chunk * of storage. * *---------------------------------------------------------------------- */void*Tcl_GetThreadData(
Tcl_ThreadDataKey *keyPtr,/* Identifier for the data chunk */int size)/* Size of storage block */{void*result;#ifdef TCL_THREADS/* * Initialize the key for this thread. */
result =TclThreadStorageKeyGet(keyPtr);if(result == NULL) {
result =ckalloc(size);memset(result,0, (size_t) size);TclThreadStorageKeySet(keyPtr, result);}#else/* TCL_THREADS */if(*keyPtr == NULL) {
result =ckalloc(size);memset(result,0, (size_t)size);*keyPtr = result;RememberSyncObject(keyPtr, &keyRecord);}else{
result = *keyPtr;}#endif/* TCL_THREADS */return result;}/* *---------------------------------------------------------------------- * * TclThreadDataKeyGet -- * * This function returns a pointer to a block of thread local storage. * * Results: * A thread-specific pointer to the data structure, or NULL if the memory * has not been assigned to this key for this thread. * * Side effects: * None. * *---------------------------------------------------------------------- */void*TclThreadDataKeyGet(
Tcl_ThreadDataKey *keyPtr)/* Identifier for the data chunk. */{#ifdef TCL_THREADSreturnTclThreadStorageKeyGet(keyPtr);#else/* TCL_THREADS */return*keyPtr;#endif/* TCL_THREADS */}/* *---------------------------------------------------------------------- * * RememberSyncObject * * Keep a list of (mutexes/condition variable/data key) used during * finalization. * * Assume master lock is held. * * Results: * None. * * Side effects: * Add to the appropriate list. * *---------------------------------------------------------------------- */static voidRememberSyncObject(void*objPtr,/* Pointer to sync object */
SyncObjRecord *recPtr)/* Record of sync objects */{void**newList;int i, j;/* * Reuse any free slot in the list. */for(i=0; i < recPtr->num ; ++i) {if(recPtr->list[i] == NULL) {
recPtr->list[i] = objPtr;return;}}/* * Grow the list of pointers if necessary, copying only non-NULL * pointers to the new list. */if(recPtr->num >= recPtr->max) {
recPtr->max +=8;
newList =ckalloc(recPtr->max *sizeof(void*));for(i=0,j=0; i<recPtr->num ; i++) {if(recPtr->list[i] != NULL) {
newList[j++] = recPtr->list[i];}}if(recPtr->list != NULL) {ckfree(recPtr->list);}
recPtr->list = newList;
recPtr->num = j;}
recPtr->list[recPtr->num] = objPtr;
recPtr->num++;}/* *---------------------------------------------------------------------- * * ForgetSyncObject * * Remove a single object from the list. * Assume master lock is held. * * Results: * None. * * Side effects: * Remove from the appropriate list. * *---------------------------------------------------------------------- */static voidForgetSyncObject(void*objPtr,/* Pointer to sync object */
SyncObjRecord *recPtr)/* Record of sync objects */{int i;for(i=0; i<recPtr->num ; i++) {if(objPtr == recPtr->list[i]) {
recPtr->list[i] = NULL;return;}}}/* *---------------------------------------------------------------------- * * TclRememberMutex * * Keep a list of mutexes used during finalization. * Assume master lock is held. * * Results: * None. * * Side effects: * Add to the mutex list. * *---------------------------------------------------------------------- */voidTclRememberMutex(
Tcl_Mutex *mutexPtr){RememberSyncObject(mutexPtr, &mutexRecord);}/* *---------------------------------------------------------------------- * * Tcl_MutexFinalize -- * * Finalize a single mutex and remove it from the list of remembered * objects. * * Results: * None. * * Side effects: * Remove the mutex from the list. * *---------------------------------------------------------------------- */voidTcl_MutexFinalize(
Tcl_Mutex *mutexPtr){#ifdef TCL_THREADSTclpFinalizeMutex(mutexPtr);#endifTclpMasterLock();ForgetSyncObject(mutexPtr, &mutexRecord);TclpMasterUnlock();}/* *---------------------------------------------------------------------- * * TclRememberCondition * * Keep a list of condition variables used during finalization. * Assume master lock is held. * * Results: * None. * * Side effects: * Add to the condition variable list. * *---------------------------------------------------------------------- */voidTclRememberCondition(
Tcl_Condition *condPtr){RememberSyncObject(condPtr, &condRecord);}/* *---------------------------------------------------------------------- * * Tcl_ConditionFinalize -- * * Finalize a single condition variable and remove it from the list of * remembered objects. * * Results: * None. * * Side effects: * Remove the condition variable from the list. * *---------------------------------------------------------------------- */voidTcl_ConditionFinalize(
Tcl_Condition *condPtr){#ifdef TCL_THREADSTclpFinalizeCondition(condPtr);#endifTclpMasterLock();ForgetSyncObject(condPtr, &condRecord);TclpMasterUnlock();}/* *---------------------------------------------------------------------- * * TclFinalizeThreadData -- * * This function cleans up the thread-local storage. This is called once * for each thread. * * Results: * None. * * Side effects: * Frees up all thread local storage. * *---------------------------------------------------------------------- */voidTclFinalizeThreadData(void){TclFinalizeThreadDataThread();}/* *---------------------------------------------------------------------- * * TclFinalizeSynchronization -- * * This function cleans up all synchronization objects: mutexes, * condition variables, and thread-local storage. * * Results: * None. * * Side effects: * Frees up the memory. * *---------------------------------------------------------------------- */voidTclFinalizeSynchronization(void){int i;void*blockPtr;
Tcl_ThreadDataKey *keyPtr;#ifdef TCL_THREADS
Tcl_Mutex *mutexPtr;
Tcl_Condition *condPtr;TclpMasterLock();#endif/* * If we're running unthreaded, the TSD blocks are simply stored inside * their thread data keys. Free them here. */if(keyRecord.list != NULL) {for(i=0; i<keyRecord.num ; i++) {
keyPtr = (Tcl_ThreadDataKey *) keyRecord.list[i];
blockPtr = *keyPtr;ckfree(blockPtr);}ckfree(keyRecord.list);
keyRecord.list = NULL;}
keyRecord.max =0;
keyRecord.num =0;#ifdef TCL_THREADS/* * Call thread storage master cleanup. */TclFinalizeThreadStorage();for(i=0; i<mutexRecord.num ; i++) {
mutexPtr = (Tcl_Mutex *)mutexRecord.list[i];if(mutexPtr != NULL) {TclpFinalizeMutex(mutexPtr);}}if(mutexRecord.list != NULL) {ckfree(mutexRecord.list);
mutexRecord.list = NULL;}
mutexRecord.max =0;
mutexRecord.num =0;for(i=0; i<condRecord.num ; i++) {
condPtr = (Tcl_Condition *) condRecord.list[i];if(condPtr != NULL) {TclpFinalizeCondition(condPtr);}}if(condRecord.list != NULL) {ckfree(condRecord.list);
condRecord.list = NULL;}
condRecord.max =0;
condRecord.num =0;TclpMasterUnlock();#endif/* TCL_THREADS */}/* *---------------------------------------------------------------------- * * Tcl_ExitThread -- * * This function is called to terminate the current thread. This should * be used by extensions that create threads with additional interpreters * in them. * * Results: * None. * * Side effects: * All thread exit handlers are invoked, then the thread dies. * *---------------------------------------------------------------------- */voidTcl_ExitThread(int status){Tcl_FinalizeThread();#ifdef TCL_THREADSTclpThreadExit(status);#endif}#ifndef TCL_THREADS/* *---------------------------------------------------------------------- * * Tcl_ConditionWait, et al. -- * * These noop functions are provided so the stub table does not have to * be conditionalized for threads. The real implementations of these * functions live in the platform specific files. * * Results: * None. * * Side effects: * None. * *---------------------------------------------------------------------- */#undef Tcl_ConditionWaitvoidTcl_ConditionWait(
Tcl_Condition *condPtr,/* Really (pthread_cond_t **) */
Tcl_Mutex *mutexPtr,/* Really (pthread_mutex_t **) */const Tcl_Time *timePtr)/* Timeout on waiting period */{}#undef Tcl_ConditionNotifyvoidTcl_ConditionNotify(
Tcl_Condition *condPtr){}#undef Tcl_MutexLockvoidTcl_MutexLock(
Tcl_Mutex *mutexPtr){}#undef Tcl_MutexUnlockvoidTcl_MutexUnlock(
Tcl_Mutex *mutexPtr){}#endif/* !TCL_THREADS *//* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ** 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 COPYING file, which can be found at the root of the source code * * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases. * * If you do not have access to either file, you may request a copy from * * help@hdfgroup.org. ** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */#include <stdlib.h>#include <string.h>#include"H5LTprivate.h"#include"H5TBprivate.h"/*-------------------------------------------------------------------------** internal functions**-------------------------------------------------------------------------*/static hbool_t H5TB_find_field(const char*field,const char*field_list);static herr_t H5TB_attach_attributes(const char*table_title,
hid_t loc_id,const char*dset_name,
hsize_t nfields,
hid_t tid);static hid_t H5TB_create_type(hid_t loc_id,const char*dset_name,size_t type_size,const size_t*field_offset,const size_t*field_sizes,
hid_t ftype_id);/*-------------------------------------------------------------------------** Create functions**-------------------------------------------------------------------------*//*-------------------------------------------------------------------------* Function: H5TBmake_table** Purpose: Make a table** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu* Quincey Koziol** Date: January 17, 2001** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBmake_table(const char*table_title,
hid_t loc_id,const char*dset_name,
hsize_t nfields,
hsize_t nrecords,size_t type_size,const char*field_names[],const size_t*field_offset,const hid_t *field_types,
hsize_t chunk_size,void*fill_data,int compress,const void*buf){
hid_t did = H5I_BADID;
hid_t sid = H5I_BADID;
hid_t mem_type_id = H5I_BADID;
hid_t plist_id = H5I_BADID;
hid_t attr_id = H5I_BADID;
hsize_t dims[1];
hsize_t dims_chunk[1];
hsize_t maxdims[1] = {H5S_UNLIMITED};char attr_name[255];char*member_name = NULL;unsigned char*tmp_buf = NULL;
hsize_t i;
herr_t ret_val = -1;/* check the arguments */if(table_title == NULL) {goto out;}if(dset_name == NULL) {goto out;}if(field_names == NULL) {goto out;}
dims[0] = nrecords;
dims_chunk[0] = chunk_size;/* create the memory data type. */if((mem_type_id =H5Tcreate(H5T_COMPOUND, type_size)) <0)goto out;/* insert fields. */for(i =0; i < nfields; i++)if(H5Tinsert(mem_type_id, field_names[i], field_offset[i], field_types[i] ) <0)goto out;/* create a simple data space with unlimited size */if((sid =H5Screate_simple(1, dims, maxdims)) <0)goto out;/* modify dataset creation properties, i.e. enable chunking */if((plist_id =H5Pcreate(H5P_DATASET_CREATE)) <0)goto out;if(H5Pset_chunk(plist_id,1, dims_chunk) <0)goto out;/* set the fill value using a struct as the data type. */if(fill_data)if(H5Pset_fill_value(plist_id, mem_type_id, fill_data) <0)goto out;/* dataset creation property list is modified to use GZIP compression with the compression effort set to 6. */if(compress)if(H5Pset_deflate(plist_id,6) <0)goto out;/* create the dataset. */if((did =H5Dcreate2(loc_id, dset_name, mem_type_id, sid, H5P_DEFAULT, plist_id, H5P_DEFAULT)) <0)goto out;/* only write if there is something to write */if(buf)if(H5Dwrite(did, mem_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, buf) <0)goto out;/* terminate access to the data space. */if(H5Sclose(sid) <0)goto out;
sid = H5I_BADID;/* end access to the dataset */if(H5Dclose(did) <0)goto out;
did = H5I_BADID;/* end access to the property list */if(H5Pclose(plist_id) <0)goto out;
plist_id = H5I_BADID;/*------------------------------------------------------------------------- * set the conforming table attributes *------------------------------------------------------------------------- *//* attach the CLASS attribute */if(H5LTset_attribute_string(loc_id, dset_name,"CLASS", TABLE_CLASS) <0)goto out;/* attach the VERSION attribute */if(H5LTset_attribute_string(loc_id, dset_name,"VERSION", TABLE_VERSION) <0)goto out;/* attach the TITLE attribute */if(H5LTset_attribute_string(loc_id, dset_name,"TITLE", table_title) <0)goto out;/* attach the FIELD_ name attribute */for(i =0; i < nfields; i++) {/* get the member name */if(NULL == (member_name =H5Tget_member_name(mem_type_id, (unsigned)i)))goto out;HDsnprintf(attr_name,sizeof(attr_name),"FIELD_%d_NAME", (int)i);/* attach the attribute */if(H5LTset_attribute_string(loc_id, dset_name, attr_name, member_name) <0)goto out;H5free_memory(member_name);
member_name = NULL;}/* end for *//* attach the FIELD_ fill value attribute */if(fill_data) {
tmp_buf = (unsigned char*)fill_data;/* open the dataset. */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;if((sid =H5Screate(H5S_SCALAR)) <0)goto out;for(i =0; i < nfields; i++) {HDsnprintf(attr_name,sizeof(attr_name),"FIELD_%d_FILL", (int)i);if((attr_id =H5Acreate2(did, attr_name, field_types[i], sid, H5P_DEFAULT, H5P_DEFAULT)) <0)goto out;if(H5Awrite(attr_id, field_types[i], tmp_buf + field_offset[i]) <0)goto out;if(H5Aclose(attr_id) <0)goto out;
attr_id = H5I_BADID;}/* end for *//* terminate access to the data space. */if(H5Sclose(sid) <0)goto out;
sid = H5I_BADID;/* end access to the dataset */if(H5Dclose(did) <0)goto out;
did = H5I_BADID;}/* end if *//* release the datatype. */if(H5Tclose(mem_type_id) <0)goto out;
mem_type_id = H5I_BADID;
ret_val =0;
out:if(member_name)H5free_memory(member_name);if(attr_id >0)if(H5Aclose(attr_id) <0)
ret_val = -1;if(plist_id >0)if(H5Pclose(plist_id) <0)
ret_val = -1;if(sid >0)if(H5Sclose(sid) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;if(mem_type_id >0)if(H5Tclose(mem_type_id) <0)
ret_val = -1;return ret_val;}/* end H5TBmake_table() *//*-------------------------------------------------------------------------** Write functions**-------------------------------------------------------------------------*//*-------------------------------------------------------------------------* Function: H5TBappend_records** Purpose: Appends records to a table** Return: Success: 0, Failure: -1** Programmers:* Pedro Vicente, pvn@ncsa.uiuc.edu* Quincey Koziol** Date: November 19, 2001** Comments: Uses memory offsets**-------------------------------------------------------------------------*/
herr_t H5TBappend_records(hid_t loc_id,const char*dset_name,
hsize_t nrecords,size_t type_size,const size_t*field_offset,const size_t*field_sizes,const void*buf){
hid_t did = H5I_BADID;
hid_t tid = H5I_BADID;
hid_t mem_type_id = H5I_BADID;
hsize_t nrecords_orig;
hsize_t nfields;
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;/* get the original number of records and fields */if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords_orig) <0)goto out;/* open the dataset. */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the datatypes */if((tid =H5Dget_type(did)) <0)goto out;if((mem_type_id =H5TB_create_type(loc_id, dset_name, type_size, field_offset, field_sizes, tid)) <0)goto out;/* append the records */if((H5TB_common_append_records(did, mem_type_id, (size_t)nrecords, nrecords_orig, buf)) <0)goto out;
ret_val =0;
out:if(tid >0)if(H5Tclose(tid) <0)
ret_val = -1;if(mem_type_id >0)if(H5Tclose(mem_type_id) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBappend_records() *//*-------------------------------------------------------------------------* Function: H5TBwrite_records** Purpose: Writes records** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: November 19, 2001** Comments: Uses memory offsets**-------------------------------------------------------------------------*/
herr_t H5TBwrite_records(hid_t loc_id,const char*dset_name,
hsize_t start,
hsize_t nrecords,size_t type_size,const size_t*field_offset,const size_t*field_sizes,const void*buf){
hid_t did = H5I_BADID;
hid_t tid = H5I_BADID;
hid_t sid = H5I_BADID;
hid_t m_sid = H5I_BADID;
hid_t mem_type_id = H5I_BADID;
hsize_t count[1];
hsize_t offset[1];
hsize_t mem_size[1];
hsize_t dims[1];
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;/* open the dataset. */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((tid =H5Dget_type(did)) <0)goto out;if((mem_type_id =H5TB_create_type(loc_id, dset_name, type_size, field_offset, field_sizes, tid)) <0)goto out;/* get the dataspace handle */if((sid =H5Dget_space(did)) <0)goto out;/* get records */if(H5Sget_simple_extent_dims(sid, dims, NULL) <0)goto out;if(start + nrecords > dims[0])goto out;/* define a hyperslab in the dataset of the size of the records */
offset[0] = start;
count[0] = nrecords;if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;/* create a memory dataspace handle */
mem_size[0] = count[0];if((m_sid =H5Screate_simple(1, mem_size, NULL)) <0)goto out;if(H5Dwrite(did, mem_type_id, m_sid, sid, H5P_DEFAULT, buf) <0)goto out;
ret_val =0;
out:if(m_sid >0)if(H5Sclose(m_sid) <0)
ret_val = -1;if(sid >0)if(H5Sclose(sid) <0)
ret_val = -1;if(tid >0)if(H5Tclose(tid) <0)
ret_val = -1;if(mem_type_id >0)if(H5Tclose(mem_type_id) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBwrite_records() *//*-------------------------------------------------------------------------* Function: H5TBwrite_fields_name** Purpose: Writes fields** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: November 21, 2001** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBwrite_fields_name(hid_t loc_id,const char*dset_name,const char*field_names,
hsize_t start,
hsize_t nrecords,size_t type_size,const size_t*field_offset,const size_t*field_sizes,const void*buf){
hid_t did = H5I_BADID;
hid_t tid = H5I_BADID;
hid_t write_type_id = H5I_BADID;
hid_t member_type_id = H5I_BADID;
hid_t nmtype_id = H5I_BADID;
hid_t m_sid = H5I_BADID;
hid_t file_space_id = H5I_BADID;
hid_t preserve_id = H5I_BADID;
hssize_t nfields;
hssize_t i, j;
hsize_t count[1];
hsize_t offset[1];char*member_name = NULL;size_t size_native;
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;if(field_names == NULL)goto out;/* create xfer properties to preserve initialized data */if((preserve_id =H5Pcreate(H5P_DATASET_XFER)) <0)goto out;if(H5Pset_preserve(preserve_id,1) <0)goto out;/* open the dataset. */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((tid =H5Dget_type(did)) <0)goto out;/* get the number of fields */if((nfields =H5Tget_nmembers(tid)) <0)goto out;/* create a write id */if((write_type_id =H5Tcreate(H5T_COMPOUND, type_size)) <0)goto out;
j =0;/* iterate though the members */for(i =0; i < nfields; i++) {/* get the member name */if(NULL == (member_name =H5Tget_member_name(tid, (unsigned)i)))goto out;if(H5TB_find_field(member_name, field_names)) {/* get the member type */if((member_type_id =H5Tget_member_type(tid, (unsigned)i)) <0)goto out;/* convert to native type */if((nmtype_id =H5Tget_native_type(member_type_id, H5T_DIR_DEFAULT)) <0)goto out;if(0== (size_native =H5Tget_size(nmtype_id)))goto out;/* adjust, if necessary */if(field_sizes[j] != size_native)if(H5Tset_size(nmtype_id, field_sizes[j]) <0)goto out;/* the field in the file is found by its name */if(field_offset) {if(H5Tinsert(write_type_id, member_name, field_offset[j], nmtype_id) <0)goto out;}/* end if *//* only one field */else{if(H5Tinsert(write_type_id, member_name, (size_t)0, nmtype_id) <0)goto out;}/* end else */
j++;/* close */if(H5Tclose(member_type_id) <0)goto out;
member_type_id = H5I_BADID;if(H5Tclose(nmtype_id) <0)goto out;
nmtype_id = H5I_BADID;}/* end if */H5free_memory(member_name);
member_name = NULL;}/* end for *//* get the dataspace handle */if((file_space_id =H5Dget_space(did)) <0)goto out;if((m_sid =H5Screate_simple(1, &nrecords, NULL)) <0)goto out;/* define a hyperslab in the dataset */
offset[0] = start;
count[0] = nrecords;if(H5Sselect_hyperslab(file_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;/* write */if(H5Dwrite(did, write_type_id, m_sid, file_space_id, preserve_id, buf) <0)goto out;
ret_val =0;
out:if(member_name)H5free_memory(member_name);if(preserve_id >0)if(H5Pclose(preserve_id) <0)
ret_val = -1;if(write_type_id >0)if(H5Tclose(write_type_id) <0)
ret_val = -1;if(tid >0)if(H5Tclose(tid) <0)
ret_val = -1;if(file_space_id >0)if(H5Sclose(file_space_id) <0)
ret_val = -1;if(m_sid >0)if(H5Sclose(m_sid) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBwrite_fields_name() *//*-------------------------------------------------------------------------* Function: H5TBwrite_fields_index** Purpose: Writes fields** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: November 21, 2001** Comments: Uses memory offsets**-------------------------------------------------------------------------*/
herr_t H5TBwrite_fields_index(hid_t loc_id,const char*dset_name,
hsize_t nfields,const int*field_index,
hsize_t start,
hsize_t nrecords,size_t type_size,const size_t*field_offset,const size_t*field_sizes,const void*buf){
hid_t did = H5I_BADID;
hid_t tid = H5I_BADID;
hid_t write_type_id = H5I_BADID;
hid_t member_type_id = H5I_BADID;
hid_t nmtype_id = H5I_BADID;
hid_t m_sid = H5I_BADID;
hid_t file_space_id = H5I_BADID;
hid_t preserve_id = H5I_BADID;
hsize_t count[1];
hsize_t offset[1];
hsize_t i;size_t size_native;char*member_name = NULL;
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;/* create xfer properties to preserve initialized data */if((preserve_id =H5Pcreate(H5P_DATASET_XFER)) <0)goto out;if(H5Pset_preserve(preserve_id,1) <0)goto out;/* open the dataset. */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((tid =H5Dget_type(did)) <0)goto out;/* create a write id */if((write_type_id =H5Tcreate(H5T_COMPOUND, type_size)) <0)goto out;/* iterate tru the members */for(i =0; i < nfields; i++) {unsigned j;/* Range check value */if(field_index[i] <0)goto out;
j = (unsigned)field_index[i];/* get the member name */if(NULL == (member_name =H5Tget_member_name(tid, j)))goto out;/* get the member type */if((member_type_id =H5Tget_member_type(tid, j)) <0)goto out;/* convert to native type */if((nmtype_id =H5Tget_native_type(member_type_id,H5T_DIR_DEFAULT)) <0)goto out;if(0== (size_native =H5Tget_size(nmtype_id)))goto out;if(field_sizes[i] != size_native)if(H5Tset_size(nmtype_id, field_sizes[i]) <0)goto out;/* the field in the file is found by its name */if(field_offset) {if(H5Tinsert(write_type_id, member_name, field_offset[i], nmtype_id) <0)goto out;}/* end if *//* only one field */else{if(H5Tinsert(write_type_id, member_name, (size_t)0, nmtype_id) <0)goto out;}/* end else *//* close */if(H5Tclose(member_type_id) <0)goto out;
member_type_id = H5I_BADID;if(H5Tclose(nmtype_id) <0)goto out;
nmtype_id = H5I_BADID;H5free_memory(member_name);
member_name = NULL;}/* end for *//* get the dataspace handles */if((file_space_id =H5Dget_space(did)) <0)goto out;if((m_sid =H5Screate_simple(1, &nrecords, NULL)) <0)goto out;/* define a hyperslab in the dataset */
offset[0] = start;
count[0] = nrecords;if(H5Sselect_hyperslab(file_space_id, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;/* write */if(H5Dwrite(did, write_type_id, m_sid, file_space_id, preserve_id, buf) <0)goto out;
ret_val =0;
out:if(member_name)H5free_memory(member_name);if(preserve_id >0)if(H5Pclose(preserve_id) <0)
ret_val = -1;if(write_type_id >0)if(H5Tclose(write_type_id) <0)
ret_val = -1;if(member_type_id >0)if(H5Tclose(member_type_id) <0)
ret_val = -1;if(nmtype_id >0)if(H5Tclose(nmtype_id) <0)
ret_val = -1;if(tid >0)if(H5Tclose(tid) <0)
ret_val = -1;if(file_space_id >0)if(H5Sclose(file_space_id) <0)
ret_val = -1;if(m_sid >0)if(H5Sclose(m_sid) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBwrite_fields_index() *//*-------------------------------------------------------------------------** Read functions**-------------------------------------------------------------------------*//*-------------------------------------------------------------------------* Function: H5TBread_table** Purpose: Reads a table** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: November 20, 2001** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBread_table(hid_t loc_id,const char*dset_name,size_t type_size,const size_t*field_offset,const size_t*field_sizes,void*dst_buf){
hid_t did = H5I_BADID;
hid_t ftype_id = H5I_BADID;
hid_t mem_type_id = H5I_BADID;
hid_t sid = H5I_BADID;
hsize_t dims[1];
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;/* open the dataset. */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the dataspace handle */if((sid =H5Dget_space(did)) <0)goto out;/* get dimensions */if(H5Sget_simple_extent_dims(sid, dims, NULL) <0)goto out;/* get the datatypes */if((ftype_id =H5Dget_type(did)) <0)goto out;if((mem_type_id =H5TB_create_type(loc_id, dset_name, type_size, field_offset, field_sizes, ftype_id)) <0)goto out;/* read */if(H5Dread(did, mem_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, dst_buf) <0)goto out;
ret_val =0;
out:if(mem_type_id >0)if(H5Tclose(mem_type_id) <0)
ret_val = -1;if(ftype_id >0)if(H5Tclose(ftype_id) <0)
ret_val = -1;if(sid >0)if(H5Sclose(sid) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBread_table() *//*-------------------------------------------------------------------------* Function: H5TBread_records** Purpose: Reads records** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: November 19, 2001** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBread_records(hid_t loc_id,const char*dset_name,
hsize_t start,
hsize_t nrecords,size_t type_size,const size_t*field_offset,const size_t*field_sizes,void*buf){
hid_t did = H5I_BADID;
hid_t ftype_id = H5I_BADID;
hid_t mem_type_id = H5I_BADID;
hsize_t nrecords_orig;
hsize_t nfields;
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;/* get the number of records and fields */if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords_orig) <0)goto out;/* open the dataset */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the datatypes */if((ftype_id =H5Dget_type(did)) <0)goto out;if((mem_type_id =H5TB_create_type(loc_id, dset_name, type_size, field_offset, field_sizes, ftype_id)) <0)goto out;/* read the records */if((H5TB_common_read_records(did, mem_type_id, start, (size_t)nrecords, nrecords_orig, buf)) <0)goto out;
ret_val =0;
out:if(mem_type_id >0)if(H5Tclose(mem_type_id) <0)
ret_val = -1;if(ftype_id >0)if(H5Tclose(ftype_id) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBread_records() *//*-------------------------------------------------------------------------* Function: H5TBread_fields_name** Purpose: Reads fields** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: November 19, 2001** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBread_fields_name(hid_t loc_id,const char*dset_name,const char*field_names,
hsize_t start,
hsize_t nrecords,size_t type_size,const size_t*field_offset,const size_t*field_sizes,void*buf){
hid_t did = H5I_BADID;
hid_t ftype_id = H5I_BADID;
hid_t mem_type_id = H5I_BADID;
hid_t mtype_id = H5I_BADID;
hid_t nmtype_id = H5I_BADID;
hid_t sid = H5I_BADID;
hid_t m_sid = H5I_BADID;
hssize_t nfields;
hsize_t count[1];
hsize_t offset[1];
hsize_t mem_size[1];size_t size_native;char*member_name = NULL;
hssize_t i, j;
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;if(field_names == NULL)goto out;/* open the dataset */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((ftype_id =H5Dget_type(did)) <0)goto out;/* get the number of fields */if((nfields =H5Tget_nmembers(ftype_id)) <0)goto out;/* create a memory read id */if((mem_type_id =H5Tcreate(H5T_COMPOUND, type_size)) <0)goto out;/* iterate through the members */for(i =0, j =0; i < nfields; i++) {/* get the member name */if(NULL == (member_name =H5Tget_member_name(ftype_id, (unsigned)i)))goto out;if(H5TB_find_field(member_name, field_names)) {/* get the member type */if((mtype_id =H5Tget_member_type(ftype_id, (unsigned)i)) <0)goto out;/* convert to native type */if((nmtype_id =H5Tget_native_type(mtype_id, H5T_DIR_DEFAULT)) <0)goto out;if(0== (size_native =H5Tget_size(nmtype_id)))goto out;if(field_sizes[j] != size_native)if(H5Tset_size(nmtype_id, field_sizes[j]) <0)goto out;/* the field in the file is found by its name */if(field_offset) {if(H5Tinsert(mem_type_id, member_name, field_offset[j], nmtype_id) <0)goto out;}/* end if */else{if(H5Tinsert(mem_type_id, member_name, (size_t)0, nmtype_id) <0)goto out;}/* end else *//* close */if(H5Tclose(mtype_id) <0)goto out;
mtype_id = H5I_BADID;if(H5Tclose(nmtype_id) <0)goto out;
nmtype_id = H5I_BADID;
j++;}/* end if */H5free_memory(member_name);
member_name = NULL;}/* end for *//* check to make sure field was found, no reason to continue if it does not exist */if(j ==0)goto out;/* get the dataspace handle */if((sid =H5Dget_space(did)) <0)goto out;/* define a hyperslab in the dataset */
offset[0] = start;
count[0] = nrecords;if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;/* create a memory dataspace handle */
mem_size[0] = count[0];if((m_sid =H5Screate_simple(1, mem_size, NULL)) <0)goto out;/* read */if(H5Dread(did, mem_type_id, m_sid, sid, H5P_DEFAULT, buf) <0)goto out;
ret_val =0;
out:if(member_name)H5free_memory(member_name);if(mtype_id >0)if(H5Tclose(mtype_id) <0)
ret_val = -1;if(nmtype_id >0)if(H5Tclose(nmtype_id) <0)
ret_val = -1;if(mem_type_id >0)if(H5Tclose(mem_type_id) <0)
ret_val = -1;if(ftype_id >0)if(H5Tclose(ftype_id) <0)
ret_val = -1;if(m_sid >0)if(H5Sclose(m_sid) <0)
ret_val = -1;if(sid >0)if(H5Sclose(sid) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBread_fields_name() *//*-------------------------------------------------------------------------* Function: H5TBread_fields_index** Purpose: Reads fields** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: November 19, 2001** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBread_fields_index(hid_t loc_id,const char*dset_name,
hsize_t nfields,const int*field_index,
hsize_t start,
hsize_t nrecords,size_t type_size,const size_t*field_offset,const size_t*field_sizes,void*buf){
hid_t did = H5I_BADID;
hid_t tid = H5I_BADID;
hid_t read_type_id = H5I_BADID;
hid_t member_type_id = H5I_BADID;
hid_t nmtype_id = H5I_BADID;
hid_t sid = H5I_BADID;
hid_t m_sid = H5I_BADID;
hsize_t count[1];
hsize_t offset[1];
hsize_t mem_size[1];
hsize_t i;size_t size_native;char*member_name = NULL;
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;/* open the dataset. */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((tid =H5Dget_type(did)) <0)goto out;/* create a read id */if((read_type_id =H5Tcreate(H5T_COMPOUND, type_size)) <0)goto out;/* iterate tru the members */for(i =0; i < nfields; i++) {unsigned j;/* Range check */if(field_index[i] <0)goto out;
j = (unsigned)field_index[i];/* get the member name */if(NULL == (member_name =H5Tget_member_name(tid, (unsigned)j)))goto out;/* get the member type */if((member_type_id =H5Tget_member_type(tid, (unsigned)j)) <0)goto out;/* convert to native type */if((nmtype_id =H5Tget_native_type(member_type_id, H5T_DIR_DEFAULT)) <0)goto out;if(0== (size_native =H5Tget_size(nmtype_id)))goto out;if(field_sizes[i] != size_native)if(H5Tset_size(nmtype_id, field_sizes[i]) <0)goto out;/* the field in the file is found by its name */if(field_offset) {if(H5Tinsert(read_type_id, member_name, field_offset[i], nmtype_id) <0)goto out;}/* end if */else{if(H5Tinsert(read_type_id, member_name, (size_t)0, nmtype_id) <0)goto out;}/* end else *//* close the member type */if(H5Tclose(member_type_id) <0)goto out;
member_type_id = H5I_BADID;if(H5Tclose(nmtype_id) <0)goto out;
nmtype_id = H5I_BADID;H5free_memory(member_name);
member_name = NULL;}/* end for *//* get the dataspace handle */if((sid =H5Dget_space(did)) <0)goto out;/* define a hyperslab in the dataset */
offset[0] = start;
count[0] = nrecords;if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;/* create a memory dataspace handle */
mem_size[0] = count[0];if((m_sid =H5Screate_simple(1, mem_size, NULL)) <0)goto out;/* read */if(H5Dread( did, read_type_id, m_sid, sid, H5P_DEFAULT, buf) <0)goto out;
ret_val =0;
out:if(member_name)H5free_memory(member_name);if(read_type_id >0)if(H5Tclose(read_type_id) <0)
ret_val = -1;if(member_type_id >0)if(H5Tclose(member_type_id) <0)
ret_val = -1;if(nmtype_id >0)if(H5Tclose(nmtype_id) <0)
ret_val = -1;if(tid >0)if(H5Tclose(tid) <0)
ret_val = -1;if(m_sid >0)if(H5Sclose(m_sid) <0)
ret_val = -1;if(sid >0)if(H5Sclose(sid) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBread_fields_index() *//*-------------------------------------------------------------------------** Manipulation functions**-------------------------------------------------------------------------*//*-------------------------------------------------------------------------* Function: H5TBdelete_record** Purpose: Delete records from middle of table ("pulling up" all the records after it)** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: November 26, 2001**-------------------------------------------------------------------------*/
herr_t H5TBdelete_record(hid_t loc_id,const char*dset_name,
hsize_t start,
hsize_t nrecords){
hid_t did = H5I_BADID;
hid_t tid = H5I_BADID;
hid_t sid = H5I_BADID;
hid_t m_sid = H5I_BADID;
hid_t mem_type_id = H5I_BADID;
hsize_t nfields;
hsize_t ntotal_records;
hsize_t read_start;
hsize_t read_nrecords;
hsize_t count[1];
hsize_t offset[1];
hsize_t mem_size[1];
hsize_t dims[1];size_t src_size;size_t*src_offset = NULL;size_t*src_sizes = NULL;unsigned char*tmp_buf = NULL;
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;/*------------------------------------------------------------------------- * first we get information about type size and offsets on disk *------------------------------------------------------------------------- *//* get the number of records and fields */if(H5TBget_table_info(loc_id, dset_name, &nfields, &ntotal_records) <0)goto out;if(NULL == (src_offset = (size_t*)HDmalloc((size_t)nfields *sizeof(size_t))))goto out;if(NULL == (src_sizes = (size_t*)HDmalloc((size_t)nfields *sizeof(size_t))))goto out;/* get field info */if(H5TBget_field_info(loc_id, dset_name, NULL, src_sizes, src_offset, &src_size) <0)goto out;/* open the dataset. */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/*------------------------------------------------------------------------- * read the records after the deleted one(s) *------------------------------------------------------------------------- */
read_start = start + nrecords;
read_nrecords = ntotal_records - read_start;if(read_nrecords) {if(NULL == (tmp_buf = (unsigned char*)HDcalloc((size_t)read_nrecords, src_size)))goto out;/* read the records after the deleted one(s) */if(H5TBread_records(loc_id, dset_name, read_start, read_nrecords, src_size, src_offset, src_sizes, tmp_buf) <0)goto out;/*------------------------------------------------------------------------- * write the records in another position *------------------------------------------------------------------------- *//* get the datatype */if((tid =H5Dget_type(did)) <0)goto out;/* get the dataspace handle */if((sid =H5Dget_space(did)) <0)goto out;/* create the memory data type. */if((mem_type_id =H5TB_create_type( loc_id, dset_name, src_size, src_offset, src_sizes, tid)) <0)goto out;/* define a hyperslab in the dataset of the size of the records */
offset[0] = start;
count[0] = read_nrecords;if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;/* create a memory dataspace handle */
mem_size[0] = count[0];if((m_sid =H5Screate_simple(1, mem_size, NULL)) <0)goto out;if(H5Dwrite(did, mem_type_id, m_sid, sid, H5P_DEFAULT, tmp_buf) <0)goto out;/* close */if(H5Sclose(m_sid) <0)goto out;
m_sid = H5I_BADID;if(H5Tclose(mem_type_id) <0)goto out;
mem_type_id = H5I_BADID;if(H5Sclose(sid) <0)goto out;
sid = H5I_BADID;if(H5Tclose(tid) <0)goto out;
tid = H5I_BADID;}/* read_nrecords *//*------------------------------------------------------------------------- * change the dataset dimension *------------------------------------------------------------------------- */
dims[0] = ntotal_records - nrecords;if(H5Dset_extent(did, dims) <0)goto out;
ret_val =0;
out:if(tmp_buf)HDfree(tmp_buf);if(src_offset)HDfree(src_offset);if(src_sizes)HDfree(src_sizes);if(mem_type_id >0)if(H5Tclose(mem_type_id) <0)
ret_val = -1;if(tid >0)if(H5Tclose(tid) <0)
ret_val = -1;if(m_sid >0)if(H5Sclose(m_sid) <0)
ret_val = -1;if(sid >0)if(H5Sclose(sid) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBdelete_record() *//*-------------------------------------------------------------------------* Function: H5TBinsert_record** Purpose: Inserts records into middle of table ("pushing down" all the records after it)** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: November 26, 2001** Comments: Uses memory offsets**-------------------------------------------------------------------------*/
herr_t H5TBinsert_record(hid_t loc_id,const char*dset_name,
hsize_t start,
hsize_t nrecords,size_t type_size,const size_t*field_offset,const size_t*field_sizes,void*buf){
hid_t did = H5I_BADID;
hid_t tid = H5I_BADID;
hid_t mem_type_id = H5I_BADID;
hid_t sid = H5I_BADID;
hid_t m_sid = H5I_BADID;
hsize_t nfields;
hsize_t ntotal_records;
hsize_t read_nrecords;
hsize_t count[1];
hsize_t offset[1];
hsize_t dims[1];
hsize_t mem_dims[1];unsigned char*tmp_buf = NULL;
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;/*------------------------------------------------------------------------- * read the records after the inserted one(s) *------------------------------------------------------------------------- *//* get the dimensions */if(H5TBget_table_info(loc_id, dset_name, &nfields, &ntotal_records) <0)goto out;/* open the dataset. */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((tid =H5Dget_type(did)) <0)goto out;/* create the memory data type. */if((mem_type_id =H5TB_create_type(loc_id, dset_name, type_size, field_offset, field_sizes, tid)) <0)goto out;
read_nrecords = ntotal_records - start;if(NULL == (tmp_buf = (unsigned char*)HDcalloc((size_t) read_nrecords, type_size)))goto out;/* read the records after the inserted one(s) */if(H5TBread_records(loc_id, dset_name, start, read_nrecords, type_size, field_offset, field_sizes, tmp_buf) <0)goto out;/* extend the dataset */
dims[0] = ntotal_records + nrecords;if(H5Dset_extent(did, dims) <0)goto out;/*------------------------------------------------------------------------- * write the inserted records *------------------------------------------------------------------------- *//* create a simple memory data space */
mem_dims[0] = nrecords;if((m_sid =H5Screate_simple(1, mem_dims, NULL)) <0)goto out;/* get the file data space */if((sid =H5Dget_space(did)) <0)goto out;/* define a hyperslab in the dataset to write the new data */
offset[0] = start;
count[0] = nrecords;if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;if(H5Dwrite(did, mem_type_id, m_sid, sid, H5P_DEFAULT, buf) <0)goto out;/* terminate access to the dataspace */if(H5Sclose(m_sid) <0)goto out;
m_sid = H5I_BADID;if(H5Sclose(sid) <0)goto out;
sid = H5I_BADID;/*------------------------------------------------------------------------- * write the "pushed down" records *------------------------------------------------------------------------- *//* create a simple memory data space */
mem_dims[0] = read_nrecords;if((m_sid =H5Screate_simple(1, mem_dims, NULL)) <0)goto out;/* get the file data space */if((sid =H5Dget_space(did)) <0)goto out;/* define a hyperslab in the dataset to write the new data */
offset[0] = start + nrecords;
count[0] = read_nrecords;if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;if(H5Dwrite(did, mem_type_id, m_sid, sid, H5P_DEFAULT, tmp_buf) <0)goto out;
ret_val =0;
out:if(tmp_buf)HDfree(tmp_buf);if(sid >0)if(H5Sclose(sid) <0)
ret_val = -1;if(m_sid >0)if(H5Sclose(m_sid) <0)
ret_val = -1;if(mem_type_id >0)if(H5Tclose(mem_type_id) <0)
ret_val = -1;if(tid >0)if(H5Tclose(tid) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBinsert_record() *//*-------------------------------------------------------------------------* Function: H5TBadd_records_from** Purpose: Add records from first table to second table** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: December 5, 2001** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBadd_records_from(hid_t loc_id,const char*dset_name1,
hsize_t start1,
hsize_t nrecords,const char*dset_name2,
hsize_t start2){
hid_t did = H5I_BADID;
hid_t tid = H5I_BADID;
hid_t sid = H5I_BADID;
hid_t m_sid = H5I_BADID;
hsize_t count[1];
hsize_t offset[1];
hsize_t mem_size[1];
hsize_t nfields;
hsize_t ntotal_records;size_t type_size1;size_t src_size;size_t*src_offset = NULL;size_t*src_sizes = NULL;unsigned char*tmp_buf = NULL;
herr_t ret_val = -1;/* check the arguments */if(dset_name1 == NULL)goto out;if(dset_name2 == NULL)goto out;/*------------------------------------------------------------------------- * first we get information about type size and offsets on disk *------------------------------------------------------------------------- *//* get the number of records and fields */if(H5TBget_table_info(loc_id, dset_name1, &nfields, &ntotal_records) <0)goto out;if(NULL == (src_offset = (size_t*)HDmalloc((size_t)nfields *sizeof(size_t))))goto out;if(NULL == (src_sizes = (size_t*)HDmalloc((size_t)nfields *sizeof(size_t))))goto out;/* get field info */if(H5TBget_field_info(loc_id, dset_name1, NULL, src_sizes, src_offset, &src_size) <0)goto out;/*------------------------------------------------------------------------- * Get information about the first table and read it *------------------------------------------------------------------------- *//* open the 1st dataset. */if((did =H5Dopen2(loc_id, dset_name1, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((tid =H5Dget_type(did)) <0)goto out;/* get the dataspace handle */if((sid =H5Dget_space(did)) <0)goto out;/* get the size of the datatype */if(0== (type_size1 =H5Tget_size(tid)))goto out;if(NULL == (tmp_buf = (unsigned char*)HDcalloc((size_t)nrecords, type_size1)))goto out;/* define a hyperslab in the dataset of the size of the records */
offset[0] = start1;
count[0] = nrecords;if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;/* create a memory dataspace handle */
mem_size[0] = count[0];if((m_sid =H5Screate_simple(1, mem_size, NULL)) <0)goto out;if(H5Dread(did, tid, m_sid, sid, H5P_DEFAULT, tmp_buf) <0)goto out;/*------------------------------------------------------------------------- * add to the second table *------------------------------------------------------------------------- */if(H5TBinsert_record(loc_id, dset_name2, start2, nrecords, src_size, src_offset, src_sizes, tmp_buf) <0)goto out;
ret_val =0;
out:if(tmp_buf)HDfree(tmp_buf);if(src_offset)HDfree(src_offset);if(src_sizes)HDfree(src_sizes);if(tid >0)if(H5Tclose(tid) <0)
ret_val = -1;if(sid >0)if(H5Sclose(sid) <0)
ret_val = -1;if(m_sid >0)if(H5Sclose(m_sid) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBadd_records_from() *//*-------------------------------------------------------------------------* Function: H5TBcombine_tables** Purpose: Combine records from two tables into a third** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: December 10, 2001** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBcombine_tables(hid_t loc_id1,const char*dset_name1,
hid_t loc_id2,const char*dset_name2,const char*dset_name3){/* identifiers for the 1st dataset. */
hid_t did_1 = H5I_BADID;
hid_t tid_1 = H5I_BADID;
hid_t sid_1 = H5I_BADID;
hid_t pid_1 = H5I_BADID;/* identifiers for the 2nd dataset. */
hid_t did_2 = H5I_BADID;
hid_t tid_2 = H5I_BADID;
hid_t sid_2 = H5I_BADID;
hid_t pid_2 = H5I_BADID;/* identifiers for the 3rd dataset. */
hid_t did_3 = H5I_BADID;
hid_t tid_3 = H5I_BADID;
hid_t sid_3 = H5I_BADID;
hid_t pid_3 = H5I_BADID;
hid_t sid = H5I_BADID;
hid_t m_sid = H5I_BADID;
hid_t member_type_id = H5I_BADID;
hid_t attr_id = H5I_BADID;
hsize_t count[1];
hsize_t offset[1];
hsize_t mem_size[1];
hsize_t nfields;
hsize_t nrecords;
hsize_t dims[1];
hsize_t maxdims[1] = {H5S_UNLIMITED};
hsize_t i;size_t type_size;size_t member_offset;size_t src_size;size_t*src_offset = NULL;size_t*src_sizes = NULL;char attr_name[255];unsigned char*tmp_buf = NULL;unsigned char*tmp_fill_buf = NULL;
htri_t has_fill;
herr_t ret_val = -1;/* check the arguments */if(dset_name1 == NULL)goto out;if(dset_name2 == NULL)goto out;if(dset_name3 == NULL)goto out;/*------------------------------------------------------------------------- * first we get information about type size and offsets on disk *------------------------------------------------------------------------- *//* get the number of records and fields */if(H5TBget_table_info(loc_id1, dset_name1, &nfields, &nrecords) <0)goto out;if(NULL == (src_offset = (size_t*)HDmalloc((size_t)nfields *sizeof(size_t))))goto out;if(NULL == (src_sizes = (size_t*)HDmalloc((size_t)nfields *sizeof(size_t))))goto out;/* get field info */if(H5TBget_field_info(loc_id1, dset_name1, NULL, src_sizes, src_offset, &src_size) <0)goto out;/*------------------------------------------------------------------------- * get information about the first table *------------------------------------------------------------------------- *//* open the 1st dataset. */if((did_1 =H5Dopen2(loc_id1, dset_name1, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((tid_1 =H5Dget_type(did_1)) <0)goto out;/* get the dataspace handle */if((sid_1 =H5Dget_space(did_1)) <0)goto out;/* get creation properties list */if((pid_1 =H5Dget_create_plist(did_1)) <0)goto out;/* get the dimensions */if(H5TBget_table_info(loc_id1, dset_name1, &nfields, &nrecords) <0)goto out;/*------------------------------------------------------------------------- * make the merged table with no data originally *------------------------------------------------------------------------- *//* clone the property list */if((pid_3 =H5Pcopy(pid_1)) <0)goto out;/* clone the type id */if((tid_3 =H5Tcopy(tid_1)) <0)goto out;/*------------------------------------------------------------------------- * here we do not clone the file space from the 1st dataset, because we want to create * an empty table. Instead we create a new dataspace with zero records and expandable. *------------------------------------------------------------------------- */
dims[0] =0;/* create a simple data space with unlimited size */if((sid_3 =H5Screate_simple(1, dims, maxdims)) <0)goto out;/* create the dataset */if((did_3 =H5Dcreate2(loc_id1, dset_name3, tid_3, sid_3, H5P_DEFAULT, pid_3, H5P_DEFAULT)) <0)goto out;/*------------------------------------------------------------------------- * attach the conforming table attributes *------------------------------------------------------------------------- */if(H5TB_attach_attributes("Merge table", loc_id1, dset_name3, nfields, tid_3) <0)goto out;/*------------------------------------------------------------------------- * get attributes *------------------------------------------------------------------------- */if(0== (type_size =H5Tget_size(tid_3)))goto out;/* alloc fill value attribute buffer */if(NULL == (tmp_fill_buf = (unsigned char*)HDmalloc(type_size)))goto out;/* get the fill value attributes */if((has_fill =H5TBAget_fill(loc_id1, dset_name1, did_1, tmp_fill_buf)) <0)goto out;/*------------------------------------------------------------------------- * attach the fill attributes from previous table *------------------------------------------------------------------------- */if(has_fill) {if((sid =H5Screate(H5S_SCALAR)) <0)goto out;for(i =0; i < nfields; i++) {/* get the member type */if((member_type_id =H5Tget_member_type(tid_3, (unsigned)i)) <0)goto out;/* get the member offset */
member_offset =H5Tget_member_offset(tid_3, (unsigned)i);HDsnprintf(attr_name,sizeof(attr_name),"FIELD_%d_FILL", (int)i);if((attr_id =H5Acreate2(did_3, attr_name, member_type_id, sid, H5P_DEFAULT, H5P_DEFAULT)) <0)goto out;if(H5Awrite(attr_id, member_type_id, tmp_fill_buf + member_offset) <0)goto out;if(H5Aclose(attr_id) <0)goto out;
attr_id = H5I_BADID;if(H5Tclose(member_type_id) <0)goto out;
member_type_id = H5I_BADID;}/* end for *//* close data space. */if(H5Sclose(sid) <0)goto out;
sid = H5I_BADID;}/* end if *//*------------------------------------------------------------------------- * read data from 1st table *------------------------------------------------------------------------- */if(NULL == (tmp_buf = (unsigned char*)HDcalloc((size_t)nrecords, type_size)))goto out;/* define a hyperslab in the dataset of the size of the records */
offset[0] =0;
count[0] = nrecords;if(H5Sselect_hyperslab(sid_1, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;/* create a memory dataspace handle */
mem_size[0] = count[0];if((m_sid =H5Screate_simple(1, mem_size, NULL)) <0)goto out;if(H5Dread(did_1, tid_1, m_sid, sid_1, H5P_DEFAULT, tmp_buf) <0)goto out;/*------------------------------------------------------------------------- * save data from 1st table into new table *------------------------------------------------------------------------- *//* append the records to the new table */if(H5TBappend_records(loc_id1, dset_name3, nrecords, src_size, src_offset, src_sizes, tmp_buf) <0)goto out;/*------------------------------------------------------------------------- * release temporary resources *------------------------------------------------------------------------- */if(H5Sclose(m_sid) <0)goto out;
m_sid = H5I_BADID;HDfree(tmp_buf);
tmp_buf = NULL;/*------------------------------------------------------------------------- * get information about the 2nd table *------------------------------------------------------------------------- *//* open the dataset. */if((did_2 =H5Dopen2(loc_id2, dset_name2, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((tid_2 =H5Dget_type(did_2)) <0)goto out;/* get the dataspace handle */if((sid_2 =H5Dget_space(did_2)) <0)goto out;/* get the property list handle */if((pid_2 =H5Dget_create_plist(did_2)) <0)goto out;/* get the dimensions */if(H5TBget_table_info(loc_id2, dset_name2, &nfields, &nrecords) <0)goto out;/*------------------------------------------------------------------------- * read data from 2nd table *------------------------------------------------------------------------- */if(NULL == (tmp_buf = (unsigned char*)HDcalloc((size_t)nrecords, type_size)))goto out;/* define a hyperslab in the dataset of the size of the records */
offset[0] =0;
count[0] = nrecords;if(H5Sselect_hyperslab(sid_2, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;/* create a memory dataspace handle */
mem_size[0] = count[0];if((m_sid =H5Screate_simple(1, mem_size, NULL)) <0)goto out;if(H5Dread(did_2, tid_2, m_sid, sid_2, H5P_DEFAULT, tmp_buf) <0)goto out;/*------------------------------------------------------------------------- * save data from 2nd table into new table *------------------------------------------------------------------------- *//* append the records to the new table */if(H5TBappend_records(loc_id1, dset_name3, nrecords, src_size, src_offset, src_sizes, tmp_buf) <0)goto out;
ret_val =0;
out:if(tmp_buf)HDfree(tmp_buf);if(tmp_fill_buf)HDfree(tmp_fill_buf);if(src_offset)HDfree(src_offset);if(src_sizes)HDfree(src_sizes);if(member_type_id >0)if(H5Tclose(member_type_id) <0)
ret_val = -1;if(attr_id >0)if(H5Aclose(attr_id) <0)
ret_val = -1;if(sid >0)if(H5Sclose(sid) <0)
ret_val = -1;if(m_sid >0)if(H5Sclose(m_sid) <0)
ret_val = -1;if(sid_1 >0)if(H5Sclose(sid_1) <0)
ret_val = -1;if(tid_1 >0)if(H5Tclose(tid_1) <0)
ret_val = -1;if(pid_1 >0)if(H5Pclose(pid_1) <0)
ret_val = -1;if(did_1 >0)if(H5Dclose(did_1) <0)
ret_val = -1;if(sid_2 >0)if(H5Sclose(sid_2) <0)
ret_val = -1;if(tid_2 >0)if(H5Tclose(tid_2) <0)
ret_val = -1;if(pid_2 >0)if(H5Pclose(pid_2) <0)
ret_val = -1;if(did_2 >0)if(H5Dclose(did_2) <0)
ret_val = -1;if(sid_3 >0)if(H5Sclose(sid_3) <0)
ret_val = -1;if(tid_3 >0)if(H5Tclose(tid_3) <0)
ret_val = -1;if(pid_3 >0)if(H5Pclose(pid_3) <0)
ret_val = -1;if(did_3 >0)if(H5Dclose(did_3) <0)
ret_val = -1;return ret_val;}/* end H5TBcombine_tables() *//*-------------------------------------------------------------------------* Function: H5TBinsert_field** Purpose: Inserts a field** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: January 30, 2002** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBinsert_field(hid_t loc_id,const char*dset_name,const char*field_name,
hid_t field_type,
hsize_t position,const void*fill_data,const void*buf){/* identifiers for the 1st, original dataset */
hid_t did_1 = H5I_BADID;
hid_t tid_1 = H5I_BADID;
hid_t sid_1 = H5I_BADID;
hid_t pid_1 = H5I_BADID;
hid_t msid_1 = H5I_BADID;/* identifiers for the 2nd, new dataset */
hid_t did_2 = H5I_BADID;
hid_t tid_2 = H5I_BADID;
hid_t sid_2 = H5I_BADID;
hid_t pid_2 = H5I_BADID;
hid_t msid_2 = H5I_BADID;/* identifiers for the 3rd, final dataset */
hid_t did_3 = H5I_BADID;
hid_t tid_3 = H5I_BADID;
hid_t sid_3 = H5I_BADID;
hid_t member_type_id = H5I_BADID;
hid_t write_type_id = H5I_BADID;
hid_t preserve_id = H5I_BADID;
hid_t attr_id = H5I_BADID;size_t member_size;size_t new_member_size =0;size_t total_size;size_t curr_offset;
hsize_t nfields;
hsize_t nrecords;
hsize_t dims_chunk[1];
hsize_t dims[1];
hsize_t maxdims[1] = { H5S_UNLIMITED };
hsize_t count[1];
hsize_t offset[1];
hsize_t mem_size[1];
hsize_t i;char table_title[255];char attr_name[255];char*member_name = NULL;unsigned char*tmp_buf = NULL;unsigned char*tmp_fill_buf = NULL;
hbool_t inserted;
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;if(field_name == NULL)goto out;/* get the number of records and fields */if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords) <0)goto out;/*------------------------------------------------------------------------- * get information about the old data type *------------------------------------------------------------------------- *//* open the dataset. */if((did_1 =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get creation properties list */if((pid_1 =H5Dget_create_plist(did_1)) <0)goto out;/* get the datatype */if((tid_1 =H5Dget_type(did_1)) <0)goto out;/* get the size of the datatype */if(0== (total_size =H5Tget_size(tid_1)))goto out;/* get the dataspace handle */if((sid_1 =H5Dget_space(did_1)) <0)goto out;/* get dimension */if(H5Sget_simple_extent_dims(sid_1, dims, NULL) <0)goto out;/*------------------------------------------------------------------------- * get attributes *------------------------------------------------------------------------- *//* get the table title */if((H5TBAget_title(did_1, table_title)) <0)goto out;/* alloc fill value attribute buffer */if(NULL == (tmp_fill_buf = (unsigned char*)HDmalloc(total_size)))goto out;/* get the fill value attributes */if((H5TBAget_fill(loc_id, dset_name, did_1, tmp_fill_buf)) <0)goto out;/*------------------------------------------------------------------------- * create a new data type *------------------------------------------------------------------------- *//* get the new member size */if(0== (member_size =H5Tget_size(field_type)))goto out;/* create the data type. */if((tid_2 =H5Tcreate(H5T_COMPOUND, (size_t)(total_size + member_size))) <0)goto out;
curr_offset =0;
inserted = FALSE;/* insert the old fields, counting with the new one */for(i =0; i < nfields +1; i++) {
hsize_t idx;
idx = i;if(inserted)
idx = i -1;if(i == position) {/* get the new member size */if(0== (new_member_size =H5Tget_size(field_type)))goto out;/* insert the new field type */if(H5Tinsert(tid_2, field_name, curr_offset, field_type) <0)goto out;
curr_offset += new_member_size;
inserted = TRUE;}/* end if */else{/* get the member name */if(NULL == (member_name =H5Tget_member_name(tid_1, (unsigned)idx)))goto out;/* get the member type */if((member_type_id =H5Tget_member_type(tid_1, (unsigned)idx)) <0)goto out;/* get the member size */if(0== (member_size =H5Tget_size(member_type_id)))goto out;/* insert it into the new type */if(H5Tinsert(tid_2, member_name, curr_offset, member_type_id) <0)goto out;
curr_offset += member_size;H5free_memory(member_name);
member_name = NULL;/* close the member type */if(H5Tclose(member_type_id) <0)goto out;
member_type_id = H5I_BADID;}/* end else */}/* end for *//*------------------------------------------------------------------------- * create a new temporary dataset *------------------------------------------------------------------------- *//* retrieve the size of chunk */if(H5Pget_chunk(pid_1,1, dims_chunk) <0)goto out;/* create a new simple data space with unlimited size, using the dimension */if((sid_2 =H5Screate_simple(1, dims, maxdims)) <0)goto out;/* modify dataset creation properties, i.e. enable chunking */if((pid_2 =H5Pcreate(H5P_DATASET_CREATE)) <0)goto out;if(H5Pset_chunk(pid_2,1, dims_chunk) <0)goto out;/* create the dataset. */if((did_2 =H5Dcreate2(loc_id,"new", tid_2, sid_2, H5P_DEFAULT, pid_2, H5P_DEFAULT)) <0)goto out;/*------------------------------------------------------------------------- * read data from 1st table *------------------------------------------------------------------------- */if(NULL == (tmp_buf = (unsigned char*)HDcalloc((size_t)nrecords, (size_t)total_size)))goto out;/* define a hyperslab in the dataset of the size of the records */
offset[0] =0;
count[0] = nrecords;if(H5Sselect_hyperslab(sid_1, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;/* create a memory dataspace handle */
mem_size[0] = count[0];if((msid_1 =H5Screate_simple(1, mem_size, NULL)) <0)goto out;if(H5Dread(did_1, tid_1, msid_1, H5S_ALL, H5P_DEFAULT, tmp_buf) <0)goto out;/*------------------------------------------------------------------------- * save data from 1st table into new table, using the 1st type id *------------------------------------------------------------------------- *//* write */if(H5Dwrite(did_2, tid_1, msid_1, H5S_ALL, H5P_DEFAULT, tmp_buf) <0)goto out;/*------------------------------------------------------------------------- * save the function supplied data of the new field *------------------------------------------------------------------------- *//* create a write id */if((write_type_id =H5Tcreate(H5T_COMPOUND, (size_t)new_member_size)) <0)goto out;/* the field in the file is found by its name */if(H5Tinsert(write_type_id, field_name, (size_t)0, field_type) <0)goto out;/* create xfer properties to preserve initialized data */if((preserve_id =H5Pcreate(H5P_DATASET_XFER)) <0)goto out;if(H5Pset_preserve(preserve_id,1) <0)goto out;/* only write if there is something to write */if(buf) {/* create a memory dataspace handle */if((msid_2 =H5Screate_simple(1, mem_size, NULL)) <0)goto out;/* write */if(H5Dwrite(did_2, write_type_id, msid_2, sid_2, preserve_id, buf) <0)goto out;}/* end if *//*------------------------------------------------------------------------- * delete 1st table *------------------------------------------------------------------------- */if(H5Ldelete(loc_id, dset_name, H5P_DEFAULT) <0)goto out;/*------------------------------------------------------------------------- * rename 2nd table *------------------------------------------------------------------------- */if(H5Lmove(loc_id,"new", H5L_SAME_LOC, dset_name, H5P_DEFAULT, H5P_DEFAULT) <0)goto out;/*------------------------------------------------------------------------- * attach the conforming table attributes *------------------------------------------------------------------------- *//* get the number of records and fields */if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords) <0)goto out;/* open the dataset. */if((did_3 =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((tid_3 =H5Dget_type(did_3)) <0)goto out;/* set the attributes */if(H5TB_attach_attributes(table_title, loc_id, dset_name, (hsize_t)nfields, tid_3) <0)goto out;/*------------------------------------------------------------------------- * attach the fill attributes from previous table *------------------------------------------------------------------------- */if((sid_3 =H5Screate(H5S_SCALAR)) <0)goto out;for(i =0; i < (nfields -1); i++) {size_t member_offset;/* get the member type */if((member_type_id =H5Tget_member_type(tid_3, (unsigned)i)) <0)goto out;/* get the member offset */
member_offset =H5Tget_member_offset(tid_3, (unsigned)i);HDsnprintf(attr_name,sizeof(attr_name),"FIELD_%d_FILL", (int)i);if((attr_id =H5Acreate2(did_3, attr_name, member_type_id, sid_3, H5P_DEFAULT, H5P_DEFAULT)) <0)goto out;if(H5Awrite(attr_id, member_type_id, tmp_fill_buf + member_offset) <0)goto out;if(H5Aclose(attr_id) <0)goto out;
attr_id = H5I_BADID;/* close the member type */if(H5Tclose(member_type_id) <0)goto out;
member_type_id = H5I_BADID;}/* end for *//*------------------------------------------------------------------------- * attach the fill attribute from the new field, if present *------------------------------------------------------------------------- */if(fill_data) {HDsnprintf(attr_name,sizeof(attr_name),"FIELD_%d_FILL", (int)(nfields -1));/* get the member type */if((member_type_id =H5Tget_member_type(tid_3, (unsigned)nfields -1)) <0)goto out;if((attr_id =H5Acreate2(did_3, attr_name, member_type_id, sid_3, H5P_DEFAULT, H5P_DEFAULT)) <0)goto out;if(H5Awrite(attr_id, member_type_id, fill_data) <0)goto out;if(H5Aclose(attr_id) <0)goto out;
attr_id = H5I_BADID;if(H5Tclose(member_type_id) <0)goto out;
member_type_id = H5I_BADID;}/* end fill_data */
ret_val =0;
out:if(member_name)H5free_memory(member_name);if(tmp_buf)HDfree(tmp_buf);if(tmp_fill_buf)HDfree(tmp_fill_buf);if(preserve_id >0)if(H5Pclose(preserve_id) <0)
ret_val = -1;if(msid_1 >0)if(H5Sclose(msid_1) <0)
ret_val = -1;if(tid_1 >0)if(H5Tclose(tid_1) <0)
ret_val = -1;if(pid_1 >0)if(H5Pclose(pid_1) <0)
ret_val = -1;if(sid_1 >0)if(H5Sclose(sid_1) <0)
ret_val = -1;if(did_1 >0)if(H5Dclose(did_1) <0)
ret_val = -1;if(msid_2 >0)if(H5Sclose(msid_2) <0)
ret_val = -1;if(sid_2 >0)if(H5Sclose(sid_2) <0)
ret_val = -1;if(tid_2 >0)if(H5Tclose(tid_2) <0)
ret_val = -1;if(pid_2 >0)if(H5Pclose(pid_2) <0)
ret_val = -1;if(did_2 >0)if(H5Dclose(did_2) <0)
ret_val = -1;if(sid_3 >0)if(H5Sclose(sid_3) <0)
ret_val = -1;if(tid_3 >0)if(H5Tclose(tid_3) <0)
ret_val = -1;if(did_3 >0)if(H5Dclose(did_3) <0)
ret_val = -1;return ret_val;}/* end H5TBinsert_field() *//*-------------------------------------------------------------------------* Function: H5TBdelete_field** Purpose: Deletes a field** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: January 30, 2002** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBdelete_field(hid_t loc_id,const char*dset_name,const char*field_name){/* identifiers for the 1st original dataset */
hid_t did_1 = H5I_BADID;
hid_t tid_1 = H5I_BADID;
hid_t sid_1 = H5I_BADID;
hid_t pid_1 = H5I_BADID;/* identifiers for the 2nd new dataset */
hid_t did_2 = H5I_BADID;
hid_t tid_2 = H5I_BADID;
hid_t sid_2 = H5I_BADID;
hid_t pid_2 = H5I_BADID;/* identifiers for the 3rd final dataset */
hid_t did_3 = H5I_BADID;
hid_t tid_3 = H5I_BADID;
hid_t member_type_id = H5I_BADID;
hid_t preserve_id = H5I_BADID;
hid_t read_type_id = H5I_BADID;
hid_t write_type_id = H5I_BADID;
hid_t attr_id = H5I_BADID;size_t member_size;size_t type_size1;size_t type_size2;size_t curr_offset;size_t delete_member_size =0;size_t member_offset;
hsize_t nfields;
hsize_t nrecords;
hsize_t dims_chunk[1];
hsize_t dims[1];
hsize_t maxdims[1] = { H5S_UNLIMITED };
hsize_t i;char attr_name[255];char table_title[255];char*member_name = NULL;unsigned char*tmp_buf = NULL;unsigned char*tmp_fill_buf = NULL;
htri_t has_fill = FALSE;
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;if(field_name == NULL)goto out;/* get the number of records and fields */if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords) <0)goto out;/*------------------------------------------------------------------------- * get information about the old data type *------------------------------------------------------------------------- *//* open the dataset. */if((did_1 =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get creation properties list */if((pid_1 =H5Dget_create_plist(did_1)) <0)goto out;/* get the datatype */if((tid_1 =H5Dget_type(did_1)) <0)goto out;/* get the size of the datatype */if(0== (type_size1 =H5Tget_size(tid_1)))goto out;/* get the dataspace handle */if((sid_1 =H5Dget_space(did_1)) <0)goto out;/* get dimension */if(H5Sget_simple_extent_dims(sid_1, dims, NULL) <0)goto out;/*------------------------------------------------------------------------- * create a new data type; first we find the size of the datatype to delete *------------------------------------------------------------------------- *//* check out the field */for(i =0; i < nfields; i++) {/* get the member name */if(NULL == (member_name =H5Tget_member_name(tid_1, (unsigned)i)))goto out;/* we want to find the field to delete */if(H5TB_find_field(member_name, field_name)) {/* get the member type */if((member_type_id =H5Tget_member_type(tid_1, (unsigned)i)) <0)goto out;/* get the member size */if(0== (delete_member_size =H5Tget_size(member_type_id)))goto out;/* close the member type */if(H5Tclose(member_type_id) <0)goto out;
member_type_id = H5I_BADID;H5free_memory(member_name);
member_name = NULL;break;}/* end if */H5free_memory(member_name);
member_name = NULL;}/* end for *//* no field to delete was found */if(delete_member_size ==0)goto out;/*------------------------------------------------------------------------- * create a new data type; we now insert all the fields into the new type *------------------------------------------------------------------------- */
type_size2 = type_size1 - delete_member_size;/* create the data type. */if((tid_2 =H5Tcreate(H5T_COMPOUND, type_size2)) <0)goto out;
curr_offset =0;/* alloc fill value attribute buffer */if(NULL == (tmp_fill_buf = (unsigned char*)HDmalloc((size_t)type_size2)))goto out;/*------------------------------------------------------------------------- * get attributes from previous table in the process *------------------------------------------------------------------------- *//* get the table title */if((H5TBAget_title(did_1, table_title)) <0)goto out;/* insert the old fields except the one to delete */for(i =0; i < nfields; i++) {/* get the member name */if(NULL == (member_name =H5Tget_member_name(tid_1, (unsigned)i)))goto out;/* we want to skip the field to delete */if(!H5TB_find_field(member_name, field_name)) {/* get the member type */if((member_type_id =H5Tget_member_type(tid_1, (unsigned)i)) <0)goto out;/* get the member size */if(0== (member_size =H5Tget_size(member_type_id)))goto out;/* insert it into the new type */if(H5Tinsert(tid_2, member_name, curr_offset, member_type_id) <0)goto out;/*------------------------------------------------------------------------- * get the fill value information *------------------------------------------------------------------------- */HDsnprintf(attr_name,sizeof(attr_name),"FIELD_%d_FILL", (int)i);/* check if we have the _FILL attribute */if((has_fill =H5LT_find_attribute(did_1, attr_name)) <0)goto out;/* get it */if(has_fill)if(H5LT_get_attribute_disk(did_1, attr_name, tmp_fill_buf + curr_offset) <0)goto out;
curr_offset += member_size;/* close the member type */if(H5Tclose(member_type_id) <0)goto out;
member_type_id = H5I_BADID;}/* end if */H5free_memory(member_name);
member_name = NULL;}/* end for *//*------------------------------------------------------------------------- * create a new temporary dataset *------------------------------------------------------------------------- *//* retrieve the size of chunk */if(H5Pget_chunk(pid_1,1, dims_chunk) <0)goto out;/* create a new simple data space with unlimited size, using the dimension */if((sid_2 =H5Screate_simple(1, dims, maxdims)) <0)goto out;/* modify dataset creation properties, i.e. enable chunking */
pid_2 =H5Pcreate(H5P_DATASET_CREATE);if(H5Pset_chunk(pid_2,1, dims_chunk) <0)goto out;/* create the dataset. */if((did_2 =H5Dcreate2(loc_id,"new", tid_2, sid_2, H5P_DEFAULT, pid_2, H5P_DEFAULT)) <0)goto out;/*------------------------------------------------------------------------- * we have to read field by field of the old dataset and save it into the new one *------------------------------------------------------------------------- */for(i =0; i < nfields; i++) {/* get the member name */if(NULL == (member_name =H5Tget_member_name(tid_1, (unsigned)i)))goto out;/* skip the field to delete */if(!H5TB_find_field(member_name, field_name)) {/* get the member type */if((member_type_id =H5Tget_member_type(tid_1, (unsigned)i)) <0)goto out;/* get the member size */if(0== (member_size =H5Tget_size(member_type_id)))goto out;/* create a read id */if((read_type_id =H5Tcreate(H5T_COMPOUND, member_size)) <0)goto out;/* insert it into the new type */if(H5Tinsert(read_type_id, member_name, (size_t)0, member_type_id) <0)goto out;if(NULL == (tmp_buf = (unsigned char*)HDcalloc((size_t)nrecords, member_size)))goto out;/* read */if(H5Dread(did_1, read_type_id, H5S_ALL, H5S_ALL, H5P_DEFAULT, tmp_buf) <0)goto out;/* create a write id */if((write_type_id =H5Tcreate(H5T_COMPOUND, member_size)) <0)goto out;/* the field in the file is found by its name */if(H5Tinsert(write_type_id, member_name, (size_t)0, member_type_id) <0)goto out;/* create xfer properties to preserve initialized data */if((preserve_id =H5Pcreate(H5P_DATASET_XFER)) <0)goto out;if(H5Pset_preserve(preserve_id,1) <0)goto out;/* write */if(H5Dwrite(did_2, write_type_id, H5S_ALL, H5S_ALL, preserve_id, tmp_buf) <0)goto out;/* end access to the property list */if(H5Pclose(preserve_id) <0)goto out;
preserve_id = H5I_BADID;/* close the member type */if(H5Tclose(member_type_id) <0)goto out;
member_type_id = H5I_BADID;/* close the read type */if(H5Tclose(read_type_id) <0)goto out;
read_type_id = H5I_BADID;/* close the write type */if(H5Tclose(write_type_id) <0)goto out;
write_type_id = H5I_BADID;HDfree(tmp_buf);
tmp_buf = NULL;}/* end if *//* release resources. */H5free_memory(member_name);
member_name = NULL;}/* end for *//*------------------------------------------------------------------------- * delete 1st table *------------------------------------------------------------------------- */if(H5Ldelete(loc_id, dset_name, H5P_DEFAULT) <0)goto out;/*------------------------------------------------------------------------- * rename 2nd table *------------------------------------------------------------------------- */if(H5Lmove(loc_id,"new", H5L_SAME_LOC, dset_name, H5P_DEFAULT, H5P_DEFAULT) <0)goto out;/*------------------------------------------------------------------------- * attach the conforming table attributes *------------------------------------------------------------------------- *//* get the number of records and fields */if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords) <0)goto out;/* open the dataset. */if((did_3 =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((tid_3 =H5Dget_type(did_3)) <0)goto out;/* set the attributes */if(H5TB_attach_attributes(table_title, loc_id, dset_name, nfields, tid_3) <0)goto out;/*------------------------------------------------------------------------- * attach the fill attributes from previous table *------------------------------------------------------------------------- */if(has_fill) {if((sid_1 =H5Screate(H5S_SCALAR)) <0)goto out;for(i =0; i < nfields; i++) {/* get the member type */if((member_type_id =H5Tget_member_type(tid_3, (unsigned)i)) <0)goto out;/* get the member offset */
member_offset =H5Tget_member_offset(tid_3, (unsigned)i);HDsnprintf(attr_name,sizeof(attr_name),"FIELD_%d_FILL", (int)i);if((attr_id =H5Acreate2(did_3, attr_name, member_type_id, sid_1, H5P_DEFAULT, H5P_DEFAULT)) <0)goto out;if(H5Awrite(attr_id, member_type_id, tmp_fill_buf + member_offset) <0)goto out;if(H5Aclose(attr_id) <0)goto out;
attr_id = H5I_BADID;/* close the member type */if(H5Tclose(member_type_id) <0)goto out;
member_type_id = H5I_BADID;}/* end for *//* close data space. */if(H5Sclose(sid_1) <0)goto out;
sid_1 = H5I_BADID;}/* end if */
ret_val =0;
out:if(member_name)H5free_memory(member_name);if(tmp_fill_buf)HDfree(tmp_fill_buf);if(tmp_buf)HDfree(tmp_buf);if(attr_id >0)if(H5Aclose(attr_id) <0)
ret_val = -1;if(preserve_id >0)if(H5Pclose(preserve_id) <0)
ret_val = -1;if(member_type_id >0)if(H5Tclose(member_type_id) <0)
ret_val = -1;if(read_type_id >0)if(H5Tclose(read_type_id) <0)
ret_val = -1;if(write_type_id >0)if(H5Tclose(write_type_id) <0)
ret_val = -1;if(tid_1 >0)if(H5Tclose(tid_1) <0)
ret_val = -1;if(pid_1 >0)if(H5Pclose(pid_1) <0)
ret_val = -1;if(sid_1 >0)if(H5Sclose(sid_1) <0)
ret_val = -1;if(did_1 >0)if(H5Dclose(did_1) <0)
ret_val = -1;if(sid_2 >0)if(H5Sclose(sid_2) <0)
ret_val = -1;if(tid_2 >0)if(H5Tclose(tid_2) <0)
ret_val = -1;if(pid_2 >0)if(H5Pclose(pid_2) <0)
ret_val = -1;if(did_2 >0)if(H5Dclose(did_2) <0)
ret_val = -1;if(tid_3 >0)if(H5Tclose(tid_3) <0)
ret_val = -1;if(did_3 >0)if(H5Dclose(did_3) <0)
ret_val = -1;return ret_val;}/* end H5TBdelete_field() *//*-------------------------------------------------------------------------** Table attribute functions**-------------------------------------------------------------------------*//*-------------------------------------------------------------------------* Function: H5TBAget_title** Purpose: Read the table title** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: January 30, 2001** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBAget_title(hid_t loc_id,char*table_title){/* Get the TITLE attribute */if(H5LT_get_attribute_disk(loc_id,"TITLE", table_title) <0)return-1;return0;}/*-------------------------------------------------------------------------* Function: H5TBAget_fill** Purpose: Read the table attribute fill values** Return: Success: TRUE/FALSE, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: January 30, 2002** Comments:**-------------------------------------------------------------------------*/
htri_t H5TBAget_fill(hid_t loc_id,const char*dset_name,
hid_t dset_id,unsigned char*dst_buf){
hsize_t nfields;
hsize_t nrecords;
hsize_t i;size_t*src_offset = NULL;char attr_name[255];
htri_t has_fill = FALSE;
htri_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;/* get the number of records and fields */if(H5TBget_table_info(loc_id, dset_name, &nfields, &nrecords) <0)goto out;if(NULL == (src_offset = (size_t*)HDmalloc((size_t)nfields *sizeof(size_t))))goto out;/* get field info */if(H5TBget_field_info(loc_id, dset_name, NULL, NULL, src_offset, NULL) <0)goto out;for(i =0; i < nfields; i++) {HDsnprintf(attr_name,sizeof(attr_name),"FIELD_%d_FILL", (int)i);/* check if we have the _FILL attribute */if((has_fill =H5LT_find_attribute(dset_id, attr_name)) <0)goto out;/* get it */if(has_fill)if(H5LT_get_attribute_disk(dset_id, attr_name, dst_buf + src_offset[i]) <0)goto out;}/* end for */
ret_val = has_fill;
out:if(src_offset)HDfree(src_offset);return ret_val;}/* end H5TBAget_fill() *//*-------------------------------------------------------------------------** Inquiry functions**-------------------------------------------------------------------------*//*-------------------------------------------------------------------------* Function: H5TBget_table_info** Purpose: Gets the number of records and fields of a table** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: November 19, 2001** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBget_table_info(hid_t loc_id,const char*dset_name,
hsize_t *nfields,
hsize_t *nrecords){
hid_t tid = H5I_BADID;
hid_t sid = H5I_BADID;
hid_t did = H5I_BADID;
hsize_t dims[1];int num_members;
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;/* open the dataset. */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((tid =H5Dget_type(did)) <0)goto out;/* get the number of members */if((num_members =H5Tget_nmembers(tid)) <0)goto out;/*------------------------------------------------------------------------- * get number of nfields *------------------------------------------------------------------------- */if(nfields)*nfields = (hsize_t)num_members;/*------------------------------------------------------------------------- * get number of records *------------------------------------------------------------------------- */if(nrecords) {/* get the dataspace handle */if((sid =H5Dget_space(did)) <0)goto out;/* get dimension */if(H5Sget_simple_extent_dims(sid, dims, NULL) <0)goto out;/* terminate access to the dataspace */if(H5Sclose(sid) <0)goto out;
sid = H5I_BADID;*nrecords = dims[0];}/* end if */
ret_val =0;
out:if(sid >0)if(H5Sclose(sid) <0)
ret_val = -1;if(tid >0)if(H5Tclose(tid) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBget_table_info() *//*-------------------------------------------------------------------------* Function: H5TBget_field_info** Purpose: Get information about fields** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: November 19, 2001** Comments:**-------------------------------------------------------------------------*/
herr_t H5TBget_field_info(hid_t loc_id,const char*dset_name,char*field_names[],size_t*field_sizes,size_t*field_offsets,size_t*type_size){
hid_t did = H5I_BADID;/* dataset ID */
hid_t tid = H5I_BADID;/* file type ID */
hid_t n_tid = H5I_BADID;/* native type ID */
hid_t m_tid = H5I_BADID;/* member type ID */
hid_t nm_tid = H5I_BADID;/* native member ID */
hssize_t nfields;
hssize_t i;
herr_t ret_val = -1;/* check the arguments */if(dset_name == NULL)goto out;/* open the dataset. */if((did =H5Dopen2(loc_id, dset_name, H5P_DEFAULT)) <0)goto out;/* get the datatype */if((tid =H5Dget_type(did)) <0)goto out;if((n_tid =H5Tget_native_type(tid, H5T_DIR_DEFAULT)) <0)goto out;/* get the type size */if(type_size)if(0== (*type_size =H5Tget_size(n_tid)))goto out;/* get the number of members */if((nfields =H5Tget_nmembers(tid)) <0)goto out;/* iterate tru the members */for(i =0; i < nfields; i++) {/* get the member name */if(field_names) {char*member_name;if(NULL == (member_name =H5Tget_member_name(tid, (unsigned)i)))goto out;strcpy(field_names[i], member_name);H5free_memory(member_name);}/* end if *//* get the member type */if((m_tid =H5Tget_member_type(tid, (unsigned)i)) <0)goto out;if((nm_tid =H5Tget_native_type(m_tid, H5T_DIR_DEFAULT)) <0)goto out;/* get the member size */if(field_sizes)if(0== (field_sizes[i] =H5Tget_size(nm_tid)))goto out;/* get the member offset */if(field_offsets)
field_offsets[i] =H5Tget_member_offset(n_tid, (unsigned) i);/* close the member types */if(H5Tclose(m_tid) <0)goto out;
m_tid = H5I_BADID;if(H5Tclose(nm_tid) <0)goto out;
nm_tid = H5I_BADID;}/* end for */
ret_val =0;
out:if(tid >0)if(H5Tclose(tid) <0)
ret_val = -1;if(n_tid >0)if(H5Tclose(n_tid) <0)
ret_val = -1;if(m_tid >0)if(H5Tclose(m_tid) <0)
ret_val = -1;if(nm_tid >0)if(H5Tclose(nm_tid) <0)
ret_val = -1;if(did >0)if(H5Dclose(did) <0)
ret_val = -1;return ret_val;}/* end H5TBget_field_info() *//*-------------------------------------------------------------------------** internal functions**-------------------------------------------------------------------------*//*-------------------------------------------------------------------------* Function: H5TB_find_field** Purpose: Find a string field** Return: Success: TRUE/FALSE, Failure: N/A** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: November 19, 2001**-------------------------------------------------------------------------*/
H5_ATTR_PURE static
hbool_t H5TB_find_field(const char*field,const char*field_list){const char*start = field_list;const char*end;/* check the arguments */if(field == NULL)return FALSE;if(field_list == NULL)return FALSE;while((end =HDstrstr(start,",")) !=0) {ptrdiff_t count = end - start;if(HDstrncmp(start, field, (size_t)count) ==0&& (size_t)count ==HDstrlen(field))return TRUE;
start = end +1;}/* end while */if(HDstrncmp(start, field,HDstrlen(field)) ==0)return TRUE;return FALSE;}/* end H5TB_find_field() *//*-------------------------------------------------------------------------* Function: H5TB_attach_attributes** Purpose: Private function that creates the conforming table attributes;* Used by H5TBcombine_tables; not used by H5TBmake_table, which does not read* the fill value attributes from an existing table** Return: Success: 0, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: December 6, 2001** Comments:**-------------------------------------------------------------------------*/static
herr_t H5TB_attach_attributes(const char*table_title,
hid_t loc_id,const char*dset_name,
hsize_t nfields,
hid_t tid){char attr_name[255];char*member_name = NULL;
hsize_t i;
herr_t ret_val = -1;/* attach the CLASS attribute */if(H5LTset_attribute_string(loc_id, dset_name,"CLASS", TABLE_CLASS) <0)goto out;/* attach the VERSION attribute */if(H5LTset_attribute_string(loc_id, dset_name,"VERSION", TABLE_VERSION) <0)goto out;/* attach the TITLE attribute */if(H5LTset_attribute_string(loc_id, dset_name,"TITLE", table_title) <0)goto out;/* attach the FIELD_ name attribute */for(i =0; i < nfields; i++) {/* get the member name */if(NULL == (member_name =H5Tget_member_name(tid, (unsigned)i)))goto out;HDsnprintf(attr_name,sizeof(attr_name),"FIELD_%d_NAME", (int)i);/* attach the attribute */if(H5LTset_attribute_string(loc_id, dset_name, attr_name, member_name) <0)goto out;H5free_memory(member_name);
member_name = NULL;}/* end for */
ret_val =0;
out:if(member_name)H5free_memory(member_name);return ret_val;}/* end H5TB_attach_attributes() *//*-------------------------------------------------------------------------* Function: H5TB_create_type** Purpose: Private function that creates a memory type ID** Return: Success: the memory type ID, Failure: -1** Programmer: Pedro Vicente, pvn@ncsa.uiuc.edu** Date: March 31, 2004** Comments:**-------------------------------------------------------------------------*/static
hid_t H5TB_create_type(hid_t loc_id,const char*dset_name,size_t type_size,const size_t*field_offset,const size_t*field_sizes,
hid_t ftype_id){
hid_t mem_type_id = H5I_BADID;
hid_t mtype_id = H5I_BADID;
hid_t nmtype_id = H5I_BADID;size_t size_native;
hsize_t nfields =0;char**fnames = NULL;unsigned i;
hid_t ret_val = -1;/* get the number of fields */if(H5TBget_table_info(loc_id, dset_name, &nfields, NULL) <0)goto out;if(NULL == (fnames = (char**)HDcalloc(sizeof(char*), (size_t)nfields)))goto out;for(i =0; i < nfields; i++)if(NULL == (fnames[i] = (char*)HDmalloc(HLTB_MAX_FIELD_LEN)))goto out;/* get field info */if(H5TBget_field_info(loc_id, dset_name, fnames, NULL, NULL, NULL) <0)goto out;/* create the memory data type */if((mem_type_id =H5Tcreate(H5T_COMPOUND, type_size)) <0)goto out;/* get each field ID and adjust its size, if necessary */for(i =0; i < nfields; i++) {if((mtype_id =H5Tget_member_type(ftype_id, i)) <0)goto out;if((nmtype_id =H5Tget_native_type(mtype_id, H5T_DIR_DEFAULT)) <0)goto out;if(0== (size_native =H5Tget_size(nmtype_id)))goto out;if(field_sizes[i] != size_native)if(H5Tset_size(nmtype_id, field_sizes[i]) <0)goto out;if(H5Tinsert(mem_type_id, fnames[i], field_offset[i], nmtype_id) <0)goto out;if(H5Tclose(mtype_id) <0)goto out;
mtype_id = H5I_BADID;if(H5Tclose(nmtype_id) <0)goto out;
nmtype_id = H5I_BADID;}/* end for */
ret_val = mem_type_id;
out:if(fnames) {for(i =0; i < nfields; i++)if(fnames[i])HDfree(fnames[i]);HDfree(fnames);}/* end if */if(mtype_id >0)if(H5Tclose(mtype_id) <0)
ret_val = -1;if(nmtype_id >0)if(H5Tclose(nmtype_id) <0)
ret_val = -1;if(ret_val <0&& mem_type_id >0)H5Tclose(mem_type_id);return ret_val;}/* end H5TB_create_type() *//*-------------------------------------------------------------------------** Functions shared between H5TB and H5PT**-------------------------------------------------------------------------*//*-------------------------------------------------------------------------* Function: H5TB_common_append_records** Purpose: Common code for reading records shared between H5PT and H5TB** Return: Success: 0, Failure: -1** Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu* James Laird, jlaird@ncsa.uiuc.edu** Date: March 8, 2004** Comments: Called by H5TBappend_records and H5PTappend_records**-------------------------------------------------------------------------*/
herr_t H5TB_common_append_records(hid_t dataset_id,
hid_t mem_type_id,size_t nrecords,
hsize_t orig_table_size,const void*buf){
hid_t sid = H5I_BADID;
hid_t m_sid = H5I_BADID;
hsize_t count[1];
hsize_t offset[1];
hsize_t dims[1];
hsize_t mem_dims[1];
herr_t ret_val = -1;/* extend the dataset */
dims[0] = nrecords + orig_table_size;if(H5Dset_extent(dataset_id, dims) <0)goto out;/* create a simple memory data space */
mem_dims[0] = nrecords;if((m_sid =H5Screate_simple(1, mem_dims, NULL)) <0)goto out;/* get a copy of the new file data space for writing */if((sid =H5Dget_space(dataset_id)) <0)goto out;/* define a hyperslab in the dataset */
offset[0] = orig_table_size;
count[0] = nrecords;if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;/* write the records */if(H5Dwrite(dataset_id, mem_type_id, m_sid, sid, H5P_DEFAULT, buf) <0)goto out;
ret_val =0;
out:if(m_sid >0)if(H5Sclose(m_sid) <0)
ret_val = -1;if(sid >0)if(H5Sclose(sid) <0)
ret_val = -1;return ret_val;}/* end H5TB_common_append_records() *//*-------------------------------------------------------------------------* Function: H5TB_common_read_records** Purpose: Common code for reading records shared between H5PT and H5TB** Return: Success: 0, Failure: -1** Programmer: Nat Furrer, nfurrer@ncsa.uiuc.edu* James Laird, jlaird@ncsa.uiuc.edu** Date: March 8, 2004** Comments: Called by H5TBread_records and H5PTread_records**-------------------------------------------------------------------------*/
herr_t H5TB_common_read_records(hid_t dataset_id,
hid_t mem_type_id,
hsize_t start,size_t nrecords,
hsize_t table_size,void*buf){
hid_t sid = H5I_BADID;
hid_t m_sid = H5I_BADID;
hsize_t count[1];
hsize_t offset[1];
hsize_t mem_size[1];
herr_t ret_val = -1;/* make sure the read request is in bounds */if(start + nrecords > table_size)goto out;/* get the dataspace handle */if((sid =H5Dget_space(dataset_id)) <0)goto out;/* define a hyperslab in the dataset of the size of the records */
offset[0] = start;
count[0] = nrecords;if(H5Sselect_hyperslab(sid, H5S_SELECT_SET, offset, NULL, count, NULL) <0)goto out;/* create a memory dataspace handle */
mem_size[0] = count[0];if((m_sid =H5Screate_simple(1, mem_size, NULL)) <0)goto out;if((H5Dread(dataset_id, mem_type_id, m_sid, sid, H5P_DEFAULT, buf)) <0)goto out;
ret_val =0;
out:if(m_sid >0)if(H5Sclose(m_sid) <0)
ret_val = -1;if(sid >0)if(H5Sclose(sid) <0)
ret_val = -1;return ret_val;}/* end H5TB_common_read_records() */