/*******************************************************************/ /* XDMF */ /* eXtensible Data Model and Format */ /* */ /* Id : Id */ /* Date : $Date$ */ /* Version : $Revision$ */ /* */ /* Author: */ /* Jerry A. Clarke */ /* clarke@arl.army.mil */ /* US Army Research Laboratory */ /* Aberdeen Proving Ground, MD */ /* */ /* Copyright @ 2007 US Army Research Laboratory */ /* All Rights Reserved */ /* See Copyright.txt or http://www.arl.hpc.mil/ice for details */ /* */ /* This software is distributed WITHOUT ANY WARRANTY; without */ /* even the implied warranty of MERCHANTABILITY or FITNESS */ /* FOR A PARTICULAR PURPOSE. See the above copyright notice */ /* for more information. */ /* */ /*******************************************************************/ /* * * Purpose: A driver which stores the HDF5 data in DSM using * only the HDF5 public API. This driver is useful for distributed * access to hdf5 files. * Derived from the "core" driver. */ #include "XdmfH5Driver.h" #include "XdmfDsmBuffer.h" #include "XdmfDsmComm.h" #include "assert.h" #include "vtk_hdf5.h" #include #include #define HDF_IO_DEBUG 1 #undef HDF_IO_DEBUG #ifndef FAIL #define FAIL -1 #endif #undef MAX #define MAX(X,Y) ((X)>(Y)?(X):(Y)) #undef MIN #define MIN(X,Y) ((X)<(Y)?(X):(Y)) namespace xdmf2 { /* The driver identification number, initialized at runtime */ static hid_t H5FD_DSM_g = 0; /* * 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 * of the file (the current size of the underlying memory). */ typedef struct H5FD_dsm_t { H5FD_t pub; /*public stuff, must be first */ char *name; /*for equivalence testing */ haddr_t eoa; /*end of allocated region */ haddr_t eof; /*current allocated size */ size_t increment; /*multiples for mem allocation */ XdmfInt64 entry_addr; /* DSM Address of this entry*/ XdmfInt64 start; /* Current DSM Start Address */ XdmfInt64 end; /* Current DSM End Address */ char entry_name[80]; /* Should be the same as name */ char entry[80]; int dirty; XdmfDsmBuffer *DsmBuffer; } H5FD_dsm_t; /* Driver-specific file access properties */ typedef struct H5FD_dsm_fapl_t { size_t increment; /*how much to grow memory */ XdmfDsmBuffer *buffer; /* Default DSM Buffer*/ } H5FD_dsm_fapl_t; /* * 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. * * ADDR_OVERFLOW: Checks whether a file address of type `haddr_t' * is too large to be represented by the second argument * of the file seek function. * * SIZE_OVERFLOW: Checks whether a buffer size of type `hsize_t' is too * large to be represented by the `size_t' type. * * REGION_OVERFLOW: Checks whether an address and size pair describe data * which can be addressed entirely in memory. */ #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&(H5_VERS_MINOR>=6)) #ifdef H5_HAVE_LSEEK64 # define file_offset_t off64_t # define file_seek lseek64 # define file_truncate ftruncate64 #elif defined (WIN32) && !defined(__MWERKS__) # /*MSVC*/ # define file_offset_t __int64 # define file_seek _lseeki64 # define file_truncate _ftruncatei64 #else # define file_offset_t off_t # define file_seek lseek # define file_truncate HDftruncate #endif #define MAXADDR (((haddr_t)1<<(8*sizeof(file_offset_t)-1))-1) #define DSM_HSIZE_T size_t #else #define MAXADDR ((haddr_t)~(size_t)0 - 1) #define DSM_HSIZE_T hsize_t #endif #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) || \ HADDR_UNDEF==(A)+(Z) || \ (size_t)((A)+(Z))<(size_t)(A)) /* Prototypes */ extern "C" { static void *H5FD_dsm_fapl_get(H5FD_t *_file); static H5FD_t *H5FD_dsm_open(const char *name, unsigned flags, hid_t fapl_id, haddr_t maxaddr); static herr_t H5FD_dsm_close(H5FD_t *_file); #ifdef XDMF_NOT_USED static herr_t H5FD_dsm_flush(H5FD_t *_file); #endif static int H5FD_dsm_cmp(const H5FD_t *_f1, const H5FD_t *_f2); #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&(H5_VERS_MINOR>=8)) static haddr_t H5FD_dsm_get_eoa(const H5FD_t *_file, H5FD_mem_t type); static herr_t H5FD_dsm_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr); #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&(H5_VERS_MINOR>=10)) static haddr_t H5FD_dsm_get_eof(const H5FD_t *_file, H5FD_mem_t type); #else static haddr_t H5FD_dsm_get_eof(const H5FD_t *_file); #endif #else static haddr_t H5FD_dsm_get_eoa(H5FD_t *_file); static herr_t H5FD_dsm_set_eoa(H5FD_t *_file, haddr_t addr); static haddr_t H5FD_dsm_get_eof(H5FD_t *_file); #endif static herr_t H5FD_dsm_read(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, DSM_HSIZE_T size, void *buf); static herr_t H5FD_dsm_write(H5FD_t *_file, H5FD_mem_t type, hid_t fapl_id, haddr_t addr, DSM_HSIZE_T size, const void *buf); } static const H5FD_class_t H5FD_dsm_g = { #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&((H5_VERS_MINOR>13)||((H5_VERS_MINOR==13)&&(H5_VERS_RELEASE>=2)))) 0, /*version */ #endif #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&(H5_VERS_MINOR>=13)) H5_VFD_RESERVED + 0xd3f2, /*value */ #endif "dsm", /*name */ MAXADDR, /*maxaddr */ H5F_CLOSE_WEAK, /*fc_degree */ #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&(H5_VERS_MINOR>=10)) NULL, /*terminate */ #endif NULL, /*sb_size */ NULL, /*sb_encode */ NULL, /*sb_decode */ sizeof(H5FD_dsm_fapl_t), /*fapl_size */ H5FD_dsm_fapl_get, /*fapl_get */ NULL, /*fapl_copy */ NULL, /*fapl_free */ 0, /*dxpl_size */ NULL, /*dxpl_copy */ NULL, /*dxpl_free */ H5FD_dsm_open, /*open */ H5FD_dsm_close, /*close */ H5FD_dsm_cmp, /*cmp */ NULL, /*query */ #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&(H5_VERS_MINOR>=8)) NULL, /* get_type_map */ #endif NULL, /*alloc */ NULL, /*free */ H5FD_dsm_get_eoa, /*get_eoa */ H5FD_dsm_set_eoa, /*set_eoa */ H5FD_dsm_get_eof, /*get_eof */ NULL, /*get_handle */ H5FD_dsm_read, /*read */ H5FD_dsm_write, /*write */ #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&((H5_VERS_MINOR>13)||((H5_VERS_MINOR==13)&&(H5_VERS_RELEASE>=2)))) NULL, /*read_vector */ NULL, /*write_vector */ NULL, /*read_selection */ NULL, /*write_selection */ #endif NULL, /*flush */ #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&(H5_VERS_MINOR>=8)) NULL, /* truncate */ #endif NULL, /*lock */ NULL, /*unlock */ #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&(H5_VERS_MINOR>=13)) NULL, /*del */ NULL, /*ctl */ #endif H5FD_FLMAP_SINGLE /*fl_map */ }; #define WORD_CMP(a, b) ((b) == NULL ? 1 : strncmp((a), (b), strlen(b))) /**********************************/ /********** Support ***************/ /**********************************/ #define XDMF_DSM_MAGIC 0xDEFBABE typedef struct { XdmfInt64 magic; XdmfInt64 start; XdmfInt64 end; } DsmEntry; XdmfInt32 DsmUpdateEntry(H5FD_dsm_t *file){ XdmfInt32 status; XdmfInt64 addr; DsmEntry entry; #ifdef HDF_IO_DEBUG cout << "(" << file->DsmBuffer->GetComm()->GetId() << ") DsmUpdateEntry()" << endl; #endif if(!file->DsmBuffer) return(XDMF_FAIL); file->end = MAX(((XdmfInt64)(file->start + file->eof)), file->end); file->eof = file->end - file->start; entry.magic = XDMF_DSM_MAGIC; entry.start = file->start; entry.end = file->end; addr = file->DsmBuffer->GetTotalLength() - sizeof(entry) - sizeof(XdmfInt64); #ifdef HDF_IO_DEBUG cout << "(" << file->DsmBuffer->GetComm()->GetId() << ") DsmUpdateEntry start " << file->start << " end " << file->end << " addr " << addr << endl; #endif status = file->DsmBuffer->Put(addr, sizeof(entry), &entry); if(status == XDMF_SUCCESS){ // Send is non blocking, make sure it's there status = file->DsmBuffer->Get(addr, sizeof(entry), &entry); } return(status); } XdmfInt32 DsmGetEntry(H5FD_dsm_t *file){ XdmfInt32 status; XdmfInt64 addr; DsmEntry entry; #ifdef HDF_IO_DEBUG cout << "(" << file->DsmBuffer->GetComm()->GetId() << ") DsmGetEntry()" << endl; #endif if(!file->DsmBuffer) return(XDMF_FAIL); addr = file->DsmBuffer->GetTotalLength() - sizeof(entry) - sizeof(XdmfInt64); status = file->DsmBuffer->Get(addr, sizeof(entry), &entry); if((status != XDMF_SUCCESS) || (entry.magic != XDMF_DSM_MAGIC)){ #ifdef HDF_IO_DEBUG cout << "(" << file->DsmBuffer->GetComm()->GetId() << ") DsmGetEntry Magic = " << entry.magic << endl; #endif return(XDMF_FAIL); } file->start = entry.start; file->end = entry.end; #ifdef HDF_IO_DEBUG cout << "(" << file->DsmBuffer->GetComm()->GetId() << ") DsmGetEntry start " << file->start << " end " << file->end << " addr " << addr << endl; #endif return(XDMF_SUCCESS); } /**********************************/ /********** End Support ***********/ /**********************************/ /*------------------------------------------------------------------------- * Function: H5FD_dsm_init * * Purpose: Initialize this driver by registering the driver with the * library. * * Return: Success: The driver ID for the dsm driver. * * Failure: Negative. * * Programmer: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ hid_t H5FD_dsm_init(void) { #ifdef HDF_IO_DEBUG cout << "In H5FD_dsm_init()" << endl; #endif if (H5I_VFL!=H5Iget_type(H5FD_DSM_g)) { H5FD_DSM_g = H5FDregister(&H5FD_dsm_g); } return H5FD_DSM_g; } /*------------------------------------------------------------------------- * Function: H5Pset_fapl_dsm * * Purpose: Modify the file access property list to use the H5FD_DSM * driver defined in this source file. The INCREMENT specifies * how much to grow the memory each time we need more. * * Return: Non-negative on success/Negative on failure * * Programmer: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ herr_t H5Pset_fapl_dsm(hid_t fapl_id, size_t increment, XdmfDsmBuffer *buffer ) { H5FD_dsm_fapl_t fa; #ifdef HDF_IO_DEBUG #endif fa.increment = increment; fa.buffer = buffer; return H5Pset_driver(fapl_id, H5FD_DSM, &fa); } /*------------------------------------------------------------------------- * Function: H5Pget_fapl_dsm * * Purpose: Queries properties set by the H5Pset_fapl_dsm() function. * * Return: Success: Non-negative * * Failure: Negative * * Programmer: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ herr_t H5Pget_fapl_dsm(hid_t fapl_id, size_t *increment/*out*/, XdmfDsmBuffer **buffer /* out */ ) { H5FD_dsm_fapl_t *fa; #ifdef HDF_IO_DEBUG printf("Getting fapl\n"); #endif /*NO TRACE*/ if (H5P_FILE_ACCESS!=H5Pget_class(fapl_id)) return -1; if (H5FD_DSM!=H5Pget_driver(fapl_id)) return -1; if (NULL==(fa=(H5FD_dsm_fapl_t *)H5Pget_driver_info(fapl_id))) return -1; if (increment) *increment = fa->increment; if( buffer ) *buffer = fa->buffer; return 0; } /*------------------------------------------------------------------------- * Function: H5FD_dsm_fapl_get * * Purpose: Returns a copy of the file access properties. * * Return: Success: Ptr to new file access properties. * * Failure: NULL * * Programmer: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ static void * H5FD_dsm_fapl_get(H5FD_t *_file) { H5FD_dsm_t *file = (H5FD_dsm_t*)_file; H5FD_dsm_fapl_t *fa = (H5FD_dsm_fapl_t *)calloc(1, sizeof(H5FD_dsm_fapl_t)); #ifdef HDF_IO_DEBUG printf("Fapl Get\n"); #endif fa->increment = file->increment; return fa; } /*------------------------------------------------------------------------- * Function: H5FD_dsm_open * * Purpose: Create memory as an HDF5 file. * * 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: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ static H5FD_t * H5FD_dsm_open(const char *name, unsigned flags/*unused*/, hid_t fapl_id, haddr_t maxaddr) { H5FD_dsm_t *file=NULL; H5FD_dsm_fapl_t *fa=NULL; XdmfInt32 status; //XdmfInt64 addr; /* Check arguments */ if (0==maxaddr || HADDR_UNDEF==maxaddr) return NULL; #ifdef HDF_IO_DEBUG // printf("Opening %s ... Checking maxaddr \n", name); #endif if (ADDR_OVERFLOW(maxaddr)) return NULL; #ifdef HDF_IO_DEBUG // printf("Opening %s .... Setting Driver\n", name); #endif if (H5P_DEFAULT!=fapl_id) fa = (H5FD_dsm_fapl_t *)H5Pget_driver_info(fapl_id); #ifdef HDF_IO_DEBUG // printf("Opening %s\n", name); #endif // One HDF5 file @ Address 0 /* Create the new file struct */ file = (H5FD_dsm_t *)calloc(1, sizeof(H5FD_dsm_t)); if (name && *name) { XDMF_STRING_DUPLICATE(file->name, name); } /* See if it exists */ file->DsmBuffer = fa->buffer; #ifdef HDF_IO_DEBUG cout << "(" << file->DsmBuffer->GetComm()->GetId() << ") Opening " << name << endl; #endif status = DsmGetEntry(file); #ifdef HDF_IO_DEBUG if( status == XDMF_SUCCESS ){ cout << "(" << file->DsmBuffer->GetComm()->GetId() << ") Opened from Entry " << name << " Start " << file->start << " End " << file->end << endl; } #endif if(H5F_ACC_CREAT & flags){ if (status == XDMF_FAIL){ #ifdef HDF_IO_DEBUG cout << "(" << file->DsmBuffer->GetComm()->GetId() << ") Creating " << name << endl; #endif DsmUpdateEntry(file); } file->eof = file->end - file->start; } else { /* Must Already Exist */ if(status == XDMF_FAIL){ free( file ); return( NULL ); } if(H5F_ACC_RDWR & flags) { /* Read and Write */ file->eof = file->end - file->start; } else { /* Read Only */ file->eof = file->end - file->start; } } /* * The increment comes from either the file access property list or the * default value. But if the file access property list was zero then use * the default value instead. */ file->increment = (fa && fa->increment>0) ? fa->increment : H5FD_DSM_INCREMENT; #ifdef HDF_IO_DEBUG cout << "(" << file->DsmBuffer->GetComm()->GetId() << ") Opened " << name << " Start " << file->start << " End " << file->end << " Eoa " << file->eoa << " Eof " << file->eof << endl; #endif file->dirty = 0; #ifdef HDF_IO_DEBUG // fprintf(stderr, "Returning (H5FD_t*)fil = <%p>\n", file); #endif return (H5FD_t*)file; } /*------------------------------------------------------------------------- * Function: H5FD_dsm_flush * * Purpose: Flush the file. * * Return: Success: 0 * * Failure: -1 * * Programmer: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ #ifdef XDMF_NOT_USED static herr_t H5FD_dsm_flush(H5FD_t *_file) { H5FD_dsm_t *file = (H5FD_dsm_t*)_file; XdmfInt64 size; int status; file->dirty = 0; return( 0 ); } #endif /*------------------------------------------------------------------------- * Function: H5FD_dsm_close * * Purpose: Closes the file. * * Return: Success: 0 * * Failure: -1 * * Programmer: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ static herr_t H5FD_dsm_close(H5FD_t *_file) { H5FD_dsm_t *file = (H5FD_dsm_t*)_file; int status; #ifdef HDF_IO_DEBUG cout << "(" << file->DsmBuffer->GetComm()->GetId() << ") Closing Start " << file->start << " End " << file->end << " Eoa " << file->eoa << " Eof " << file->eof << endl; #endif status = DsmUpdateEntry( file ); if( status != XDMF_SUCCESS) return -1; if (file->name) free(file->name); memset(file, 0, sizeof(H5FD_dsm_t)); free(file); return 0; } /*------------------------------------------------------------------------- * Function: H5FD_dsm_cmp * * Purpose: Compares two files belonging to this driver by name. If one * file doesn't have a name then it is less than the other file. * If neither file has a name then the comparison is by file * address. * * Return: Success: A value like strcmp() * * Failure: never fails (arguments were checked by the * caller). * * Programmer: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ static int H5FD_dsm_cmp(const H5FD_t *_f1, const H5FD_t *_f2) { const H5FD_dsm_t *f1 = (const H5FD_dsm_t*)_f1; const H5FD_dsm_t *f2 = (const H5FD_dsm_t*)_f2; if (NULL==f1->name && NULL==f2->name) { if (f1f2) return 1; return 0; } if (NULL==f1->name) return -1; if (NULL==f2->name) return 1; return strcmp(f1->name, f2->name); } /*------------------------------------------------------------------------- * Function: H5FD_dsm_get_eoa * * Purpose: Gets the end-of-address marker for the file. The EOA marker * is the first address past the last byte allocated in the * format address space. * * Return: Success: The end-of-address marker. * * Failure: HADDR_UNDEF * * Programmer: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ static haddr_t #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&(H5_VERS_MINOR>=8)) H5FD_dsm_get_eoa(const H5FD_t *_file, H5FD_mem_t type) #else H5FD_dsm_get_eoa(H5FD_t *_file) #endif { H5FD_dsm_t *file = (H5FD_dsm_t*)_file; #ifdef HDF_IO_DEBUG // printf("H5FD_dsm_get_eoa Called\n"); #endif return file->eoa; } /*------------------------------------------------------------------------- * Function: H5FD_dsm_set_eoa * * Purpose: Set the end-of-address marker for the file. This function is * called shortly after an existing HDF5 file is opened in order * to tell the driver where the end of the HDF5 data is located. * * Return: Success: 0 * * Failure: -1 * * Programmer: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ static herr_t #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&(H5_VERS_MINOR>=8)) H5FD_dsm_set_eoa(H5FD_t *_file, H5FD_mem_t type, haddr_t addr) #else H5FD_dsm_set_eoa(H5FD_t *_file, haddr_t addr) #endif { H5FD_dsm_t *file = (H5FD_dsm_t*)_file; #ifdef HDF_IO_DEBUG // printf("H5FD_dsm_set_eoa Called %ld \n", addr); #endif if (ADDR_OVERFLOW(addr)){ #ifdef HDF_IO_DEBUG // printf("H5FD_dsm_set_eoa Address OverFLow at %ld \n", addr); // printf("H5FD_dsm_set_eoa MAXADDR = %ld \n", MAXADDR); // printf("H5FD_dsm_set_eoa Address (addr) & ~(haddr_t)MAXADDR) = %ld \n", (addr) & ~(haddr_t)MAXADDR); #endif return -1; } file->eof = file->eoa = addr; DsmUpdateEntry( file ); return 0; } /*------------------------------------------------------------------------- * Function: H5FD_dsm_get_eof * * Purpose: Returns the end-of-file marker, which is the greater of * either the size of the underlying memory or the HDF5 * end-of-address markers. * * Return: Success: End of file address, the first address past * the end of the "file", either the memory * or the HDF5 file. * * Failure: HADDR_UNDEF * * Programmer: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ static haddr_t #if (H5_VERS_MAJOR>1)||((H5_VERS_MAJOR==1)&&(H5_VERS_MINOR>=10)) H5FD_dsm_get_eof(const H5FD_t *_file, H5FD_mem_t type) #elif ((H5_VERS_MAJOR==1)&&(H5_VERS_MINOR>=8)) H5FD_dsm_get_eof(const H5FD_t *_file) #else H5FD_dsm_get_eof(H5FD_t *_file) #endif { H5FD_dsm_t *file = (H5FD_dsm_t*)_file; #ifdef HDF_IO_DEBUG // printf("H5FD_dsm_get_eoa Called %ld \n", MAX(file->eof, file->eoa) ); #endif return MAX(file->eof, file->eoa); } /*------------------------------------------------------------------------- * Function: H5FD_dsm_read * * Purpose: Reads SIZE bytes of data from FILE beginning at address ADDR * into buffer BUF according to data transfer properties in * DXPL_ID. * * Return: Success: Zero. Result is stored in caller-supplied * buffer BUF. * * Failure: -1, Contents of buffer BUF are undefined. * * Programmer: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ static herr_t H5FD_dsm_read(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id/*unused*/, haddr_t addr, DSM_HSIZE_T size, void *buf/*out*/) { H5FD_dsm_t *file = (H5FD_dsm_t*)_file; ssize_t nbytes; herr_t status; (void)type; (void)dxpl_id; #ifdef HDF_IO_DEBUG cout << "(" << file->DsmBuffer->GetComm()->GetId() << ") Read Start " << file->start << " End " << file->end << " Addr " << addr << " Size " << size << " Eoa " << file->eoa << " Eof " << file->eof << endl; #endif assert(file && file->pub.cls); assert(buf); /* Check for overflow conditions */ if (HADDR_UNDEF==addr) return -1; if (REGION_OVERFLOW(addr, size)) return -1; if (addr+size>file->eoa) return -1; /* Read the part which is before the EOF marker */ #ifdef HDF_IO_DEBUG /* printf("check addr ( %ld ) < file->eof ( %ld )\n", addr, file->eof); */ #endif if (addreof) { nbytes = MIN(size, file->eof-addr); status = file->DsmBuffer->Get(file->start + addr, nbytes, buf); if( status <= 0 ) return -1; size -= nbytes; addr += nbytes; buf = (char*)buf + nbytes; } /* Read zeros for the part which is after the EOF markers */ if (size>0) { memset(buf, 0, size); } return 0; } /*------------------------------------------------------------------------- * Function: H5FD_dsm_write * * Purpose: Writes SIZE bytes of data to FILE beginning at address ADDR * from buffer BUF according to data transfer properties in * DXPL_ID. * * Return: Success: Zero * * Failure: -1 * * Programmer: Jerry Clarke * * Modifications: * *------------------------------------------------------------------------- */ static herr_t H5FD_dsm_write(H5FD_t *_file, H5FD_mem_t type, hid_t dxpl_id/*unused*/, haddr_t addr, DSM_HSIZE_T size, const void *buf) { H5FD_dsm_t *file = (H5FD_dsm_t*)_file; herr_t status; /* const char *bufp = buf; */ (void)type; (void)dxpl_id; assert(file && file->pub.cls); assert(buf); #ifdef HDF_IO_DEBUG cout << "(" << file->DsmBuffer->GetComm()->GetId() << ") Write Start " << file->start << " End " << file->end << " Addr " << addr << " Size " << size << " Eoa " << file->eoa << " Eof " << file->eof << endl; #endif /* Check for overflow conditions */ if (REGION_OVERFLOW(addr, size)) return -1; if (addr+size>file->eoa) return -1; if (addr+size>file->eof) { size_t new_eof = file->increment * ((addr+size)/file->increment); if ((addr+size) % file->increment) new_eof += file->increment; #ifdef HDF_IO_DEBUG // printf("HDF::Write New eof %ld\n", new_eof); #endif /* Blindly Grab more DSM for now */ file->end = file->start + new_eof; file->eof = new_eof; /* Write it out to DSM */ status = DsmUpdateEntry( file ); if( status != XDMF_SUCCESS ) return -1; } /* Write from BUF to DSM */ status = file->DsmBuffer->Put(file->start + addr, size, (void *)buf); if( status <= 0 ) return -1; return 0; } }