/*--------------------------------------------------------------------------- NeXus - Neutron & X-ray Common Data Format Application Program Interface Routines Copyright (C) 1997-2000 Mark Koennecke, Przemek Klosowski This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information, see ----------------------------------------------------------------------------*/ static const char* rscid = "$Id: napi.c,v 1.9 2005/03/08 11:11:51 zolliker Exp $"; /* Revision interted by CVS */ #include #include #include #include #include "napi.h" /* * We need to include CALLING_STYLE in the function pointer definition * or else we get a type mismatch on Win32 */ typedef struct { NXhandle *pNexusData; NXstatus (CALLING_STYLE *nxclose)(NXhandle* pHandle); NXstatus (CALLING_STYLE *nxflush)(NXhandle* pHandle); NXstatus (CALLING_STYLE *nxmakegroup) (NXhandle handle, CONSTCHAR *name, char* NXclass); NXstatus (CALLING_STYLE *nxopengroup) (NXhandle handle, CONSTCHAR *name, char* NXclass); NXstatus (CALLING_STYLE *nxclosegroup)(NXhandle handle); NXstatus (CALLING_STYLE *nxmakedata) (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]); NXstatus (CALLING_STYLE *nxcompmakedata) (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[], int comp_typ, int bufsize[]); NXstatus (CALLING_STYLE *nxcompress) (NXhandle handle, int compr_type); NXstatus (CALLING_STYLE *nxopendata) (NXhandle handle, CONSTCHAR* label); NXstatus (CALLING_STYLE *nxclosedata)(NXhandle handle); NXstatus (CALLING_STYLE *nxputdata)(NXhandle handle, void* data); NXstatus (CALLING_STYLE *nxputattr)(NXhandle handle, CONSTCHAR* name, void* data, int iDataLen, int iType); NXstatus (CALLING_STYLE *nxputslab)(NXhandle handle, void* data, int start[], int size[]); NXstatus (CALLING_STYLE *nxgetdataID)(NXhandle handle, NXlink* pLink); NXstatus (CALLING_STYLE *nxmakelink)(NXhandle handle, NXlink* pLink); NXstatus (CALLING_STYLE *nxgetdata)(NXhandle handle, void* data); NXstatus (CALLING_STYLE *nxgetinfo)(NXhandle handle, int* rank, int dimension[], int* datatype); NXstatus (CALLING_STYLE *nxgetnextentry)(NXhandle handle, NXname name, NXname nxclass, int* datatype); NXstatus (CALLING_STYLE *nxgetslab)(NXhandle handle, void* data, int start[], int size[]); NXstatus (CALLING_STYLE *nxgetnextattr)(NXhandle handle, NXname pName, int *iLength, int *iType); NXstatus (CALLING_STYLE *nxgetattr)(NXhandle handle, char* name, void* data, int* iDataLen, int* iType); NXstatus (CALLING_STYLE *nxgetattrinfo)(NXhandle handle, int* no_items); NXstatus (CALLING_STYLE *nxgetgroupID)(NXhandle handle, NXlink* pLink); NXstatus (CALLING_STYLE *nxgetgroupinfo)(NXhandle handle, int* no_items, NXname name, NXname nxclass); NXstatus (CALLING_STYLE *nxsameID)(NXhandle handle, NXlink* pFirstID, NXlink* pSecondID); NXstatus (CALLING_STYLE *nxinitgroupdir)(NXhandle handle); NXstatus (CALLING_STYLE *nxinitattrdir)(NXhandle handle); } NexusFunction, *pNexusFunction; static int iFortifyScope; /*------------------------------------------------------------------------ HDF-5 cache size special stuff -------------------------------------------------------------------------*/ long nx_cacheSize = 1024000; /* 1MB, HDF-5 default */ NXstatus CALLING_STYLE NXsetcache(long newVal) { if(newVal > 0) { nx_cacheSize = newVal; return NX_OK; } return NX_ERROR; } /*---------------------------------------------------------------------*/ void NXNXNXReportError(void *pData, char *string) { printf("%s \n",string); } /*---------------------------------------------------------------------*/ void *NXpData = NULL; void (*NXIReportError)(void *pData, char *string) = NXNXNXReportError; /*---------------------------------------------------------------------*/ NX_EXTERNAL 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; NXstatus retstat; /* 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) { /* HDF4 will be used ! */ hdf_type=1; } else if (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((const char*)filename); #endif if (iRet>0) { hdf_type=1; } } } if (hdf_type==1) { /* HDF4 type */ #ifdef HDF4 retstat = NX4open((const char *)filename,am,&hdf4_handle); if(retstat != NX_OK){ free(fHandle); return retstat; } 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->nxsameID=NX4sameID; fHandle->nxinitgroupdir=NX4initgroupdir; fHandle->nxinitattrdir=NX4initattrdir; *gHandle = fHandle; #else NXIReportError (NXpData,"ERROR: Attempt to create HDF4 file when not linked with HDF4"); *gHandle = NULL; retstat = NX_ERROR; #endif /* HDF4 */ return retstat; } else if (hdf_type==2) { /* HDF5 type */ #ifdef HDF5 retstat = NX5open(filename,am,&hdf5_handle); if(retstat != NX_OK){ free(fHandle); return retstat; } 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->nxsameID=NX5sameID; fHandle->nxinitgroupdir=NX5initgroupdir; fHandle->nxinitattrdir=NX5initattrdir; *gHandle = fHandle; #else NXIReportError (NXpData,"ERROR: Attempt to create HDF5 file when not linked with HDF5"); *gHandle = NULL; retstat = NX_ERROR; #endif /* HDF5 */ return retstat; } else { NXIReportError (NXpData, "ERROR: Format not readable by this NeXus library"); *gHandle = NULL; return NX_ERROR; } } /* ------------------------------------------------------------------------- */ 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 NXsameID (NXhandle fileid, NXlink* pFirstID, NXlink* pSecondID) { pNexusFunction pFunc = (pNexusFunction)fileid; return pFunc->nxsameID(pFunc->pNexusData, pFirstID, pSecondID); } /*-------------------------------------------------------------------------*/ 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); } /*------------------------------------------------------------------------ Implementation of NXopenpath. --------------------------------------------------------------------------*/ static int isDataSetOpen(NXhandle hfil) { NXlink id; /* This uses the (sensible) feauture that NXgetdataID returns NX_ERROR when no dataset is open */ if(NXgetdataID(hfil,&id) == NX_ERROR) { return 0; } else { return 1; } } /*----------------------------------------------------------------------*/ static int isRoot(NXhandle hfil) { NXlink id; /* This uses the feauture that NXgetgroupID returns NX_ERROR when we are at root level */ if(NXgetgroupID(hfil,&id) == NX_ERROR) { return 1; } else { return 0; } } /*-------------------------------------------------------------------- copies the next path element into element. returns a pointer into path beyond the extracted path ---------------------------------------------------------------------*/ static char *extractNextPath(char *path, NXname element) { char *pPtr, *pStart; int length; pPtr = path; /* skip over leading / */ if(*pPtr == '/') { pPtr++; } pStart = pPtr; /* find next / */ pPtr = strchr(pStart,'/'); if(pPtr == NULL) { /* this is the last path element */ strcpy(element,pStart); return NULL; } else { length = pPtr - pStart; strncpy(element,pStart,length); element[length] = '\0'; } return pPtr + 1; } /*-------------------------------------------------------------------*/ static NXstatus gotoRoot(NXhandle hfil) { int status; if(isDataSetOpen(hfil)) { status = NXclosedata(hfil); if(status == NX_ERROR) { return status; } } while(!isRoot(hfil)) { status = NXclosegroup(hfil); if(status == NX_ERROR) { return status; } } return NX_OK; } /*--------------------------------------------------------------------*/ static int isRelative(char *path) { if(path[0] == '.' && path[1] == '.') return 1; else return 0; } /*------------------------------------------------------------------*/ static NXstatus moveOneDown(NXhandle hfil) { if(isDataSetOpen(hfil)) { return NXclosedata(hfil); } else { return NXclosegroup(hfil); } } /*------------------------------------------------------------------- returns a pointer to the remaining path string to move up --------------------------------------------------------------------*/ static char *moveDown(NXhandle hfil, char *path, int *code) { int status; NXname pathElem; char *pPtr; *code = NX_OK; if(path[0] == '/') { *code = gotoRoot(hfil); return path; } else { pPtr = path; while(isRelative(pPtr)) { status = moveOneDown(hfil); if(status == NX_ERROR) { *code = status; return pPtr; } pPtr += 3; } return pPtr; } } /*--------------------------------------------------------------------*/ static NXstatus stepOneUp(NXhandle hfil, char *name) { int status, datatype; NXname name2, xclass; char pBueffel[256]; /* catch the case when we are there: i.e. no further stepping necessary. This can happen with paths like ../ */ if(strlen(name) < 1) { return NX_OK; } NXinitgroupdir(hfil); while(NXgetnextentry(hfil,name2,xclass,&datatype) != NX_EOD) { if(strcmp(name2,name) == 0) { if(strcmp(xclass,"SDS") == 0) { return NXopendata(hfil,name); } else { return NXopengroup(hfil,name,xclass); } } } snprintf(pBueffel,255,"ERROR: NXopenpath cannot step into %s",name); NXIReportError (NXpData, pBueffel); return NX_ERROR; } /*---------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXopenpath(NXhandle hfil, CONSTCHAR *path) { int status, run = 1; NXname pathElement; char *pPtr; if(hfil == NULL || path == NULL) { NXIReportError(NXpData, "ERROR: NXopendata needs both a file handle and a path string"); return NX_ERROR; } pPtr = moveDown(hfil,(char *)path,&status); if(status != NX_OK) { NXIReportError (NXpData, "ERROR: NXopendata failed to move down in hierarchy"); return status; } while(run == 1) { pPtr = extractNextPath(pPtr, pathElement); status = stepOneUp(hfil,pathElement); if(status != NX_OK) { return status; } if(pPtr == NULL) { run = 0; } } return NX_OK; } /*---------------------------------------------------------------------- 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); }