#include #include #include #include #include "fortify.h" #include "napi.h" typedef struct { NXhandle *pNexusData; NXstatus (*nxclose)(NXhandle* pHandle); NXstatus (*nxflush)(NXhandle* pHandle); NXstatus (*nxmakegroup) (NXhandle handle, CONSTCHAR *name, char* NXclass); NXstatus (*nxopengroup) (NXhandle handle, CONSTCHAR *name, char* NXclass); NXstatus (*nxclosegroup)(NXhandle handle); NXstatus (*nxmakedata) (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]); NXstatus (*nxcompmakedata) (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[], int comp_typ, int bufsize[]); NXstatus (*nxcompress) (NXhandle handle, int compr_type); NXstatus (*nxopendata) (NXhandle handle, CONSTCHAR* label); NXstatus (*nxclosedata)(NXhandle handle); NXstatus (*nxputdata)(NXhandle handle, void* data); NXstatus (*nxputattr)(NXhandle handle, CONSTCHAR* name, void* data, int iDataLen, int iType); NXstatus (*nxputslab)(NXhandle handle, void* data, int start[], int size[]); NXstatus (*nxgetdataID)(NXhandle handle, NXlink* pLink); NXstatus (*nxmakelink)(NXhandle handle, NXlink* pLink); NXstatus (*nxgetdata)(NXhandle handle, void* data); NXstatus (*nxgetinfo)(NXhandle handle, int* rank, int dimension[], int* datatype); NXstatus (*nxgetnextentry)(NXhandle handle, NXname name, NXname nxclass, int* datatype); NXstatus (*nxgetslab)(NXhandle handle, void* data, int start[], int size[]); NXstatus (*nxgetnextattr)(NXhandle handle, NXname pName, int *iLength, int *iType); NXstatus (*nxgetattr)(NXhandle handle, char* name, void* data, int* iDataLen, int* iType); NXstatus (*nxgetattrinfo)(NXhandle handle, int* no_items); NXstatus (*nxgetgroupID)(NXhandle handle, NXlink* pLink); NXstatus (*nxgetgroupinfo)(NXhandle handle, int* no_items, NXname name, NXname nxclass); NXstatus (*nxinitgroupdir)(NXhandle handle); NXstatus (*nxinitattrdir)(NXhandle handle); } NexusFunction, *pNexusFunction; static int iFortifyScope; /*------------------------------------------------------------------------ HDF-5 cache size special stuff -------------------------------------------------------------------------*/ static long cacheSize = 1024000; /* 1MB, HDF-5 default */ NXstatus CALLING_STYLE NXsetcache(long newVal) { if(newVal > 0) { cacheSize = newVal; return NX_OK; } return NX_ERROR; } /*---------------------------------------------------------------------*/ static void NXNXNXReportError(void *pData, char *string) { printf("%s \n",string); } /*---------------------------------------------------------------------*/ void *NXpData = NULL; void (*NXIReportError)(void *pData, char *string) = NXNXNXReportError; /*---------------------------------------------------------------------*/ void CALLING_STYLE NXMSetError(void *pData, void (*NewError)(void *pD, char *text)) { NXpData = pData; NXIReportError = NewError; } #ifdef HDF5 #include "napi5.h" #endif #ifdef HDF4 #include "napi4.h" #endif /* ---------------------------------------------------------------------- Definition of NeXus API ---------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXopen(CONSTCHAR *filename, NXaccess am, NXhandle *gHandle) { int hdf_type=0; int iRet=0; NXhandle hdf5_handle; NXhandle hdf4_handle; pNexusFunction fHandle; /* configure fortify iFortifyScope = Fortify_EnterScope(); Fortify_CheckAllMemory(); */ fHandle = (pNexusFunction)malloc(sizeof(NexusFunction)); if (fHandle == NULL) { NXIReportError (NXpData,"ERROR: no memory to create Function structure"); return NX_ERROR; } if (am==NXACC_CREATE || am == NXACC_CREATE4) { /* HDF4 will be used ! */ hdf_type=1; } else if (am==NXACC_CREATE5) { /* HDF5 will be used ! */ hdf_type=2; } else { /* check file type hdf4/hdf5 for reading */ #ifdef HDF5 iRet=H5Fis_hdf5((const char*)filename); #endif if (iRet>0) { hdf_type=2; } else { #ifdef HDF4 iRet=Hishdf(filename); #endif if (iRet>0) { hdf_type=1; } } } if (hdf_type==1) { /* HDF4 type */ #ifdef HDF4 iRet = NX4open(filename,am,&hdf4_handle); fHandle->pNexusData=hdf4_handle; fHandle->nxclose=NX4close; fHandle->nxflush=NX4flush; fHandle->nxmakegroup=NX4makegroup; fHandle->nxopengroup=NX4opengroup; fHandle->nxclosegroup=NX4closegroup; fHandle->nxmakedata=NX4makedata; fHandle->nxcompmakedata=NX4compmakedata; fHandle->nxcompress=NX4compress; fHandle->nxopendata=NX4opendata; fHandle->nxclosedata=NX4closedata; fHandle->nxputdata=NX4putdata; fHandle->nxputattr=NX4putattr; fHandle->nxputslab=NX4putslab; fHandle->nxgetdataID=NX4getdataID; fHandle->nxmakelink=NX4makelink; fHandle->nxgetdata=NX4getdata; fHandle->nxgetinfo=NX4getinfo; fHandle->nxgetnextentry=NX4getnextentry; fHandle->nxgetslab=NX4getslab; fHandle->nxgetnextattr=NX4getnextattr; fHandle->nxgetattr=NX4getattr; fHandle->nxgetattrinfo=NX4getattrinfo; fHandle->nxgetgroupID=NX4getgroupID; fHandle->nxgetgroupinfo=NX4getgroupinfo; fHandle->nxinitgroupdir=NX4initgroupdir; fHandle->nxinitattrdir=NX4initattrdir; #endif } else if (hdf_type==2) { /* HDF5 type */ #ifdef HDF5 iRet = NX5open(filename,am,&hdf5_handle); fHandle->pNexusData=hdf5_handle; fHandle->nxclose=NX5close; fHandle->nxflush=NX5flush; fHandle->nxmakegroup=NX5makegroup; fHandle->nxopengroup=NX5opengroup; fHandle->nxclosegroup=NX5closegroup; fHandle->nxmakedata=NX5makedata; fHandle->nxcompmakedata=NX5compmakedata; fHandle->nxcompress=NX5compress; fHandle->nxopendata=NX5opendata; fHandle->nxclosedata=NX5closedata; fHandle->nxputdata=NX5putdata; fHandle->nxputattr=NX5putattr; fHandle->nxputslab=NX5putslab; fHandle->nxgetdataID=NX5getdataID; fHandle->nxmakelink=NX5makelink; fHandle->nxgetdata=NX5getdata; fHandle->nxgetinfo=NX5getinfo; fHandle->nxgetnextentry=NX5getnextentry; fHandle->nxgetslab=NX5getslab; fHandle->nxgetnextattr=NX5getnextattr; fHandle->nxgetattr=NX5getattr; fHandle->nxgetattrinfo=NX5getattrinfo; fHandle->nxgetgroupID=NX5getgroupID; fHandle->nxgetgroupinfo=NX5getgroupinfo; fHandle->nxinitgroupdir=NX5initgroupdir; fHandle->nxinitattrdir=NX5initattrdir; #endif } else { NXIReportError (NXpData,"ERROR: Format couldn't be handled!"); *gHandle = NULL; return NX_ERROR; } if(iRet == NX_OK) { *gHandle = fHandle; return NX_OK; } else { free(fHandle); return iRet; } } /* ------------------------------------------------------------------------- */ NXstatus CALLING_STYLE NXclose (NXhandle *fid) { NXhandle hfil; int status; pNexusFunction pFunc=NULL; pFunc = (pNexusFunction)*fid; hfil = pFunc->pNexusData; status = pFunc->nxclose(&hfil); pFunc->pNexusData = hfil; free(pFunc); /* Fortify_CheckAllMemory(); */ return status; } /*-----------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXmakegroup (NXhandle fid, CONSTCHAR *name, char *nxclass) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxmakegroup(pFunc->pNexusData, name, nxclass); } /*------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXopengroup (NXhandle fid, CONSTCHAR *name, char *nxclass) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxopengroup(pFunc->pNexusData, name, nxclass); } /* ------------------------------------------------------------------- */ NXstatus CALLING_STYLE NXclosegroup (NXhandle fid) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxclosegroup(pFunc->pNexusData); } /* --------------------------------------------------------------------- */ NXstatus CALLING_STYLE NXmakedata (NXhandle fid, CONSTCHAR *name, int datatype, int rank, int dimensions[]) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxmakedata(pFunc->pNexusData, name, datatype, rank, dimensions); } /* --------------------------------------------------------------------- */ NXstatus CALLING_STYLE NXcompmakedata (NXhandle fid, CONSTCHAR *name, int datatype, int rank, int dimensions[],int compress_type, int chunk_size[]) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxcompmakedata (pFunc->pNexusData, name, datatype, rank, dimensions, compress_type, chunk_size); } /* --------------------------------------------------------------------- */ NXstatus CALLING_STYLE NXcompress (NXhandle fid, int compress_type) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxcompress (pFunc->pNexusData, compress_type); } /* --------------------------------------------------------------------- */ NXstatus CALLING_STYLE NXopendata (NXhandle fid, CONSTCHAR *name) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxopendata(pFunc->pNexusData, name); } /* ----------------------------------------------------------------- */ NXstatus CALLING_STYLE NXclosedata (NXhandle fid) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxclosedata(pFunc->pNexusData); } /* ------------------------------------------------------------------- */ NXstatus CALLING_STYLE NXputdata (NXhandle fid, void *data) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxputdata(pFunc->pNexusData, data); } /* ------------------------------------------------------------------- */ NXstatus CALLING_STYLE NXputattr (NXhandle fid, CONSTCHAR *name, void *data, int datalen, int iType) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxputattr(pFunc->pNexusData, name, data, datalen, iType); } /* ------------------------------------------------------------------- */ NXstatus CALLING_STYLE NXputslab (NXhandle fid, void *data, int iStart[], int iSize[]) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxputslab(pFunc->pNexusData, data, iStart, iSize); } /* ------------------------------------------------------------------- */ NXstatus CALLING_STYLE NXgetdataID (NXhandle fid, NXlink* sRes) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxgetdataID(pFunc->pNexusData, sRes); } /* ------------------------------------------------------------------- */ NXstatus CALLING_STYLE NXmakelink (NXhandle fid, NXlink* sLink) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxmakelink(pFunc->pNexusData, sLink); } /*----------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXflush(NXhandle *pHandle) { NXhandle hfil; int status; pNexusFunction pFunc=NULL; pFunc = (pNexusFunction)*pHandle; hfil = pFunc->pNexusData; status = pFunc->nxflush(&hfil); pFunc->pNexusData = hfil; return status; } /*-------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXmalloc (void** data, int rank, int dimensions[], int datatype) { int i; size_t size = 1; *data = NULL; for(i=0; inxgetnextentry(pFunc->pNexusData, name, nxclass, datatype); } /*-------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXgetdata (NXhandle fid, void *data) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxgetdata(pFunc->pNexusData, data); } /*-------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXgetinfo (NXhandle fid, int *rank, int dimension[], int *iType) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxgetinfo(pFunc->pNexusData, rank, dimension, iType); } /*-------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXgetslab (NXhandle fid, void *data, int iStart[], int iSize[]) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxgetslab(pFunc->pNexusData, data, iStart, iSize); } /*-------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXgetnextattr (NXhandle fileid, NXname pName, int *iLength, int *iType) { pNexusFunction pFunc = (pNexusFunction)fileid; return pFunc->nxgetnextattr(pFunc->pNexusData, pName, iLength, iType); } /*-------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXgetattr (NXhandle fid, char *name, void *data, int* datalen, int* iType) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxgetattr(pFunc->pNexusData, name, data, datalen, iType); } /*-------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXgetattrinfo (NXhandle fid, int *iN) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxgetattrinfo(pFunc->pNexusData, iN); } /*-------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXgetgroupID (NXhandle fileid, NXlink* sRes) { pNexusFunction pFunc = (pNexusFunction)fileid; return pFunc->nxgetgroupID(pFunc->pNexusData, sRes); } /*-------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXgetgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxgetgroupinfo(pFunc->pNexusData, iN, pName, pClass); } /*-------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXinitattrdir (NXhandle fid) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxinitattrdir(pFunc->pNexusData); } /*-------------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXinitgroupdir (NXhandle fid) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxinitgroupdir(pFunc->pNexusData); } /*---------------------------------------------------------------------- F77 - API - Support - Routines ----------------------------------------------------------------------*/ /* * We store the whole of the NeXus file in the array - that way * we can just pass the array name to C as it will be a valid * NXhandle. We could store the NXhandle value in the FORTRAN array * instead, but that would mean writing far more wrappers */ NXstatus CALLING_STYLE NXfopen(char * filename, NXaccess* am, NexusFunction* pHandle) { NXstatus ret; NXhandle fileid = NULL; ret = NXopen(filename, *am, &fileid); if (ret == NX_OK) { memcpy(pHandle, fileid, sizeof(NexusFunction)); } else { memset(pHandle, 0, sizeof(NexusFunction)); } if (fileid != NULL) { free(fileid); } return ret; } /* * The pHandle from FORTRAN is a pointer to a static FORTRAN * array holding the NexusFunction structure. We need to malloc() * a temporary copy as NXclose will try to free() this */ NXstatus CALLING_STYLE NXfclose (NexusFunction* pHandle) { NXhandle h; NXstatus ret; h = (NXhandle)malloc(sizeof(NexusFunction)); memcpy(h, pHandle, sizeof(NexusFunction)); ret = NXclose(&h); /* does free(h) */ memset(pHandle, 0, sizeof(NexusFunction)); return ret; } /*---------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXfflush(NexusFunction* pHandle) { NXhandle h; NXstatus ret; h = (NXhandle)malloc(sizeof(NexusFunction)); memcpy(h, pHandle, sizeof(NexusFunction)); ret = NXflush(&h); /* modifies and reallocates h */ memcpy(pHandle, h, sizeof(NexusFunction)); return ret; } /*----------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXfmakedata(NXhandle fid, char *name, int *pDatatype, int *pRank, int dimensions[]) { NXstatus ret; static char buffer[256]; int i, *reversed_dimensions; reversed_dimensions = (int*)malloc(*pRank * sizeof(int)); if (reversed_dimensions == NULL) { sprintf (buffer, "ERROR: Cannot allocate space for array rank of %d in NXfmakedata", *pRank); NXIReportError (NXpData, buffer); return NX_ERROR; } /* * Reverse dimensions array as FORTRAN is column major, C row major */ for(i=0; i < *pRank; i++) { reversed_dimensions[i] = dimensions[*pRank - i - 1]; } ret = NXmakedata(fid, name, *pDatatype, *pRank, reversed_dimensions); free(reversed_dimensions); return ret; } NXstatus CALLING_STYLE NXfcompmakedata(NXhandle fid, char *name, int *pDatatype, int *pRank, int dimensions[], int *compression_type, int chunk[]) { NXstatus ret; static char buffer[256]; int i, *reversed_dimensions, *reversed_chunk; reversed_dimensions = (int*)malloc(*pRank * sizeof(int)); reversed_chunk = (int*)malloc(*pRank * sizeof(int)); if (reversed_dimensions == NULL || reversed_chunk == NULL) { sprintf (buffer, "ERROR: Cannot allocate space for array rank of %d in NXfcompmakedata", *pRank); NXIReportError (NXpData, buffer); return NX_ERROR; } /* * Reverse dimensions array as FORTRAN is column major, C row major */ for(i=0; i < *pRank; i++) { reversed_dimensions[i] = dimensions[*pRank - i - 1]; reversed_chunk[i] = chunk[*pRank - i - 1]; } ret = NXcompmakedata(fid, name, *pDatatype, *pRank, reversed_dimensions,*compression_type, reversed_chunk); free(reversed_dimensions); free(reversed_chunk); return ret; } /*-----------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXfcompress(NXhandle fid, int *compr_type) { return NXcompress(fid,*compr_type); } /*-----------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXfputattr(NXhandle fid, char *name, void *data, int *pDatalen, int *pIType) { return NXputattr(fid, name, data, *pDatalen, *pIType); }