diff --git a/exeman.c b/exeman.c index b04fe6bf..7478090c 100644 --- a/exeman.c +++ b/exeman.c @@ -391,6 +391,7 @@ static int appendLine(pExeMan self, SConnection *pCon, static int uploadSave(pExeMan self, SConnection *pCon, int argc, char *argv[]){ int status; + char pPath[256], *pPtr; if(SCGetRights(pCon) > usUser){ SCWrite(pCon,"ERROR: no permission to save buffers",eError); @@ -404,7 +405,19 @@ static int uploadSave(pExeMan self, SConnection *pCon, SCWrite(pCon,"ERROR: no upload buffer to save exists",eError); return 0; } - status = exeBufSave(self->uploadBuffer,argv[2]); + if(argv[2][0] != '/') { + pPtr = self->batchPath; + pPtr = stptok(pPtr,pPath,131,":"); + if(strlen(pPath) + 1 + strlen(argv[2]) <= 256){ + strcat(pPath,"/"); + strcat(pPath,argv[2]); + } else { + strncpy(pPath,argv[2],255); + } + } else { + strncpy(pPath,argv[2],131); + } + status = exeBufSave(self->uploadBuffer,pPath); if(status == 0){ SCWrite(pCon,"ERROR: failed to save exe buffer, destroyed...",eError); } diff --git a/hklscan.c b/hklscan.c index ffa12325..883fc6de 100644 --- a/hklscan.c +++ b/hklscan.c @@ -208,7 +208,7 @@ pVar = (pVarEntry)pPtr; if(pVar) { - sprintf(pItem," %-7.2f",pVar->fData[i]); + sprintf(pItem," %-7.2f",GetScanVarPos(pVar,i)); strcat(pLine,pItem); } } diff --git a/make_gen b/make_gen index ad60dade..f04b3d15 100644 --- a/make_gen +++ b/make_gen @@ -11,9 +11,9 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ sicsexit.o costa.o task.o $(FORTIFYOBJ)\ macro.o ofac.o obpar.o obdes.o drive.o status.o intserv.o \ devexec.o mumo.o mumoconf.o selector.o selvar.o fupa.o lld.o \ - lld_blob.o strrepl.o lin2ang.o fomerge.o\ - script.o o2t.o alias.o napi.o nxdata.o stringdict.o sdynar.o\ - histmem.o histdriv.o histsim.o interface.o callback.o \ + lld_blob.o strrepl.o lin2ang.o fomerge.o napi4.o napi5.o \ + script.o o2t.o alias.o napi.o nxdata.o stringdict.o sdynar.o \ + histmem.o histdriv.o histsim.o interface.o callback.o nxio.o \ event.o emon.o evcontroller.o evdriver.o simev.o perfmon.o \ danu.o nxdict.o varlog.o stptok.o nread.o trigd.o cell.o\ scan.o fitcenter.o telnet.o token.o wwildcard.o hklmot.o\ @@ -23,10 +23,10 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ simchop.o choco.o chadapter.o trim.o scaldate.o tasub.o\ hklscan.o xytable.o exebuf.o exeman.o ubfour.o ubcalc.o\ circular.o maximize.o sicscron.o scanvar.o tasublib.o\ - d_sign.o d_mod.o tcldrivable.o stdscan.o diffscan.o\ + d_sign.o d_mod.o tcldrivable.o stdscan.o diffscan.o nxxml.o\ synchronize.o definealias.o oscillate.o tasdrive.o \ hmcontrol.o userscan.o rs232controller.o lomax.o tasscanub.o \ - fourlib.o motreg.o motreglist.o anticollider.o \ + fourlib.o motreg.o motreglist.o anticollider.o nxdataset.o \ s_rnge.o sig_die.o gpibcontroller.o $(NIOBJ) \ hmdata.o nxscript.o tclintimpl.o sicsdata.o diff --git a/makefile_slinux b/makefile_slinux index 37382d79..e5303ae1 100644 --- a/makefile_slinux +++ b/makefile_slinux @@ -14,7 +14,7 @@ NILIB=$(SINQDIR)/linux/lib/cib.o include sllinux_def CC = gcc -CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 $(NI) \ +CFLAGS = -I$(HDFROOT)/include -DHDF4 -DHDF5 -DNXXML $(NI) \ -Ipsi/hardsup -I. \ -fwritable-strings -DCYGNUS -DNONINTF -g $(DFORTIFY) \ -Wall -Wno-unused -Wno-comment -Wno-switch @@ -26,7 +26,7 @@ SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \ LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB)\ -ltcl8.3 $(HDFROOT)/lib/libhdf5.a \ $(HDFROOT)/lib/libmfhdf.a $(HDFROOT)/lib/libdf.a \ - $(HDFROOT)/lib/libjpeg.a -lsz -ldl -lz -lm -lc + $(HDFROOT)/lib/libjpeg.a -lsz -ldl -lz -lmxml -lm -lc include make_gen diff --git a/napi.c b/napi.c index b7410d6b..98777341 100644 --- a/napi.c +++ b/napi.c @@ -23,48 +23,16 @@ ----------------------------------------------------------------------------*/ -static const char* rscid = "$Id: napi.c,v 1.9 2005/03/08 11:11:51 zolliker Exp $"; /* Revision interted by CVS */ +static const char* rscid = "$Id: napi.c,v 1.10 2005/05/27 11:58:05 koennecke Exp $"; /* Revision interted by CVS */ +#include #include #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; /*------------------------------------------------------------------------ @@ -81,6 +49,23 @@ NXstatus CALLING_STYLE NXsetcache(long newVal) } return NX_ERROR; } +/*-----------------------------------------------------------------------*/ +static NXstatus NXisXML(CONSTCHAR *filename) +{ + FILE *fd = NULL; + char line[132]; + + fd = fopen(filename,"r"); + if(fd) { + fgets(line,131,fd); + fclose(fd); + if(strstr(line,"?xml") != NULL){ + return NX_OK; + } + } + return NX_ERROR; +} +/*-------------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/ @@ -97,7 +82,8 @@ NXstatus CALLING_STYLE NXsetcache(long newVal) /*---------------------------------------------------------------------*/ - NX_EXTERNAL void CALLING_STYLE NXMSetError(void *pData, void (*NewError)(void *pD, char *text)) + NX_EXTERNAL void CALLING_STYLE NXMSetError(void *pData, + void (*NewError)(void *pD, char *text)) { NXpData = pData; NXIReportError = NewError; @@ -109,34 +95,75 @@ NXstatus CALLING_STYLE NXsetcache(long newVal) #ifdef HDF4 #include "napi4.h" #endif - +#ifdef NXXML +#include "nxxml.h" +#endif /* ---------------------------------------------------------------------- Definition of NeXus API ---------------------------------------------------------------------*/ - - +static int determineFileType(CONSTCHAR *filename) +{ + FILE *fd = NULL; + int iRet, fapl; + NXhandle handle; + + /* + this is for reading, check for existence first + */ + fd = fopen(filename,"r"); + if(fd == NULL){ + return -1; + } + fclose(fd); +#ifdef HDF5 + iRet=H5Fis_hdf5((const char*)filename); + if( iRet > 0){ + return 2; + } +#endif +#ifdef HDF4 + iRet=Hishdf((const char*)filename); + if( iRet > 0){ + return 1; + } +#endif +#ifdef NXXML + iRet = NXisXML(filename); + if(iRet == NX_OK){ + return 3; + } +#endif + /* + file type not recognized + */ + return 0; +} +/*-----------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXopen(CONSTCHAR *filename, NXaccess am, NXhandle *gHandle) { int hdf_type=0; int iRet=0; NXhandle hdf5_handle; NXhandle hdf4_handle; + NXhandle xmlHandle; pNexusFunction fHandle; NXstatus retstat; + char error[1024]; /* configure fortify iFortifyScope = Fortify_EnterScope(); Fortify_CheckAllMemory(); */ - + *gHandle = NULL; fHandle = (pNexusFunction)malloc(sizeof(NexusFunction)); if (fHandle == NULL) { NXIReportError (NXpData,"ERROR: no memory to create Function structure"); return NX_ERROR; } + memset(fHandle, 0, sizeof(NexusFunction)); /* so any functions we miss are NULL */ if (am==NXACC_CREATE) { /* HDF4 will be used ! */ hdf_type=1; @@ -146,21 +173,25 @@ NXstatus CALLING_STYLE NXsetcache(long newVal) } else if (am==NXACC_CREATE5) { /* HDF5 will be used ! */ hdf_type=2; + } else if (am==NXACC_CREATEXML) { + /* XML will be used ! */ + hdf_type=3; } 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; - } + /* check file type hdf4/hdf5/XML for reading */ + iRet = determineFileType(filename); + if(iRet < 0) { + snprintf(error,1023,"failed to open %s for reading", + filename); + NXIReportError(NXpData,error); + return NX_ERROR; } + if(iRet == 0){ + snprintf(error,1023,"failed to detrmine filetype for %s ", + filename); + NXIReportError(NXpData,error); + return NX_ERROR; + } + hdf_type = iRet; } if (hdf_type==1) { /* HDF4 type */ @@ -171,36 +202,11 @@ NXstatus CALLING_STYLE NXsetcache(long newVal) 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; + NX4assignFunctions(fHandle); *gHandle = fHandle; #else - NXIReportError (NXpData,"ERROR: Attempt to create HDF4 file when not linked with HDF4"); + NXIReportError (NXpData, + "ERROR: Attempt to create HDF4 file when not linked with HDF4"); *gHandle = NULL; retstat = NX_ERROR; #endif /* HDF4 */ @@ -214,46 +220,41 @@ NXstatus CALLING_STYLE NXsetcache(long newVal) 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; + NX5assignFunctions(fHandle); *gHandle = fHandle; #else - NXIReportError (NXpData,"ERROR: Attempt to create HDF5 file when not linked with HDF5"); + NXIReportError (NXpData, + "ERROR: Attempt to create HDF5 file when not linked with HDF5"); *gHandle = NULL; retstat = NX_ERROR; #endif /* HDF5 */ return retstat; + } else if(hdf_type == 3){ + /* + XML type + */ +#ifdef NXXML + retstat = NXXopen(filename,am,&xmlHandle); + if(retstat != NX_OK){ + free(fHandle); + return retstat; + } + fHandle->pNexusData=xmlHandle; + NXXassignFunctions(fHandle); + *gHandle = fHandle; +#else + NXIReportError (NXpData, + "ERROR: Attempt to create XML file when not linked with XML"); + *gHandle = NULL; + retstat = NX_ERROR; +#endif } else { NXIReportError (NXpData, "ERROR: Format not readable by this NeXus library"); *gHandle = NULL; return NX_ERROR; } + return NX_OK; } /* ------------------------------------------------------------------------- */ @@ -277,7 +278,7 @@ NXstatus CALLING_STYLE NXsetcache(long newVal) /*-----------------------------------------------------------------------*/ - NXstatus CALLING_STYLE NXmakegroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + NXstatus CALLING_STYLE NXmakegroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxmakegroup(pFunc->pNexusData, name, nxclass); @@ -285,7 +286,7 @@ NXstatus CALLING_STYLE NXsetcache(long newVal) /*------------------------------------------------------------------------*/ - NXstatus CALLING_STYLE NXopengroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + NXstatus CALLING_STYLE NXopengroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) { pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxopengroup(pFunc->pNexusData, name, nxclass); @@ -386,8 +387,20 @@ NXstatus CALLING_STYLE NXsetcache(long newVal) pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxmakelink(pFunc->pNexusData, sLink); } + /* --------------------------------------------------------------------*/ + NXstatus CALLING_STYLE NXopensourcegroup(NXhandle fid) + { + char target_path[512]; + int status, type = NX_CHAR, length = 511; - + status = NXgetattr(fid,"target",target_path,&length,&type); + if(status != NX_OK) + { + NXIReportError(NXpData,"ERROR: item not linked"); + return NX_ERROR; + } + return NXopengrouppath(fid,target_path); + } /*----------------------------------------------------------------------*/ NXstatus CALLING_STYLE NXflush(NXhandle *pHandle) @@ -547,6 +560,25 @@ NXstatus CALLING_STYLE NXsetcache(long newVal) pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxinitattrdir(pFunc->pNexusData); } + /*-------------------------------------------------------------------------*/ + + NXstatus CALLING_STYLE NXsetnumberformat (NXhandle fid, + int type, char *format) + { + pNexusFunction pFunc = (pNexusFunction)fid; + if(pFunc->nxsetnumberformat != NULL) + { + return pFunc->nxsetnumberformat(pFunc->pNexusData,type,format); + } + else + { + /* + silently ignore this. Most NeXus file formats do not require + this + */ + return NX_OK; + } + } /*-------------------------------------------------------------------------*/ @@ -556,6 +588,7 @@ NXstatus CALLING_STYLE NXsetcache(long newVal) pNexusFunction pFunc = (pNexusFunction)fid; return pFunc->nxinitgroupdir(pFunc->pNexusData); } + /*------------------------------------------------------------------------ Implementation of NXopenpath. --------------------------------------------------------------------------*/ @@ -742,6 +775,42 @@ static NXstatus stepOneUp(NXhandle hfil, char *name) NXIReportError (NXpData, pBueffel); return NX_ERROR; } +/*--------------------------------------------------------------------*/ +static NXstatus stepOneGroupUp(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 NX_EOD; + } + 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) { @@ -779,6 +848,115 @@ NXstatus CALLING_STYLE NXopenpath(NXhandle hfil, CONSTCHAR *path) } return NX_OK; } +/*---------------------------------------------------------------------*/ +NXstatus CALLING_STYLE NXopengrouppath(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 = stepOneGroupUp(hfil,pathElement); + if(status == NX_ERROR) + { + return status; + } + if(pPtr == NULL || status == NX_EOD) + { + run = 0; + } + } + return NX_OK; +} +/*-------------------------------------------------------------------- + format NeXus time. Code needed in every NeXus file driver + ---------------------------------------------------------------------*/ +char *NXIformatNeXusTime(){ + char *timeData; + time_t timer; + char* time_buffer = NULL; + struct tm *time_info; + const char* time_format; + long gmt_offset; +#ifdef USE_FTIME + struct timeb timeb_struct; +#endif + + time_buffer = (char *)malloc(64*sizeof(char)); + if(!time_buffer){ + NXIReportError(NXpData,"Failed to allocate buffer for time data"); + return NULL; + } + +#ifdef NEED_TZSET + tzset(); +#endif + time(&timer); +#ifdef USE_FTIME + ftime(&timeb_struct); + gmt_offset = -timeb_struct.timezone * 60; + if (timeb_struct.dstflag != 0) + { + gmt_offset += 3600; + } +#else + time_info = gmtime(&timer); + if (time_info != NULL) + { + gmt_offset = (long)difftime(timer, mktime(time_info)); + } + else + { + NXIReportError (NXpData, + "Your gmtime() function does not work ... timezone information will be incorrect\n"); + gmt_offset = 0; + } +#endif + time_info = localtime(&timer); + if (time_info != NULL) + { + if (gmt_offset < 0) + { + time_format = "%04d-%02d-%02d %02d:%02d:%02d-%02d%02d"; + } + else + { + time_format = "%04d-%02d-%02d %02d:%02d:%02d+%02d%02d"; + } + sprintf(time_buffer, time_format, + 1900 + time_info->tm_year, + 1 + time_info->tm_mon, + time_info->tm_mday, + time_info->tm_hour, + time_info->tm_min, + time_info->tm_sec, + abs(gmt_offset / 3600), + abs((gmt_offset % 3600) / 60) + ); + } + else + { + strcpy(time_buffer, "1970-01-01 00:00:00+0000"); + } + return time_buffer; +} /*---------------------------------------------------------------------- F77 - API - Support - Routines ----------------------------------------------------------------------*/ @@ -907,3 +1085,17 @@ NXstatus CALLING_STYLE NXopenpath(NXhandle hfil, CONSTCHAR *path) { return NXputattr(fid, name, data, *pDatalen, *pIType); } + + + /* + * implement snprintf when it is not available + */ + int nxisnprintf(char* buffer, int len, const char* format, ... ) + { + int ret; + va_list valist; + va_start(valist,format); + ret = vsprintf(buffer, format, valist); + va_end(valist); + return ret; + } diff --git a/napi.h b/napi.h index 7e40ac5e..edf04a2d 100644 --- a/napi.h +++ b/napi.h @@ -21,7 +21,7 @@ For further information, see - $Id: napi.h,v 1.7 2004/11/17 10:50:16 cvs Exp $ + $Id: napi.h,v 1.8 2005/05/27 11:58:05 koennecke Exp $ ----------------------------------------------------------------------------*/ @@ -29,7 +29,7 @@ #define NEXUSAPI /* NeXus HDF45 */ -#define NEXUS_VERSION "2.1.0" /* major.minor.patch */ +#define NEXUS_VERSION "3.0.0" /* major.minor.patch */ #define CONSTCHAR const char @@ -43,11 +43,18 @@ # define NX_EXTERNAL #endif +#ifdef _WIN32 +#define snprintf nxisnprintf + +extern int nxisnprintf(char* buffer, int len, const char* format, ... ); + +#endif + typedef void* NXhandle; /* really a pointer to a NexusFile structure */ typedef int NXstatus; typedef char NXname[128]; -typedef enum {NXACC_READ=1, NXACC_RDWR=2, NXACC_CREATE=3, NXACC_CREATE4=4, NXACC_CREATE5=5} NXaccess; +typedef enum {NXACC_READ=1, NXACC_RDWR=2, NXACC_CREATE=3, NXACC_CREATE4=4, NXACC_CREATE5=5, NXACC_CREATEXML=6} NXaccess; typedef struct { char *iname; @@ -90,6 +97,7 @@ typedef struct { #define NX_FLOAT64 6 #define NX_INT8 20 #define NX_UINT8 21 +#define NX_BOOLEAN NX_UINT #define NX_INT16 22 #define NX_UINT16 23 #define NX_INT32 24 @@ -112,17 +120,19 @@ typedef struct { #include #endif -typedef struct { -#ifdef HDF4 - int32 iTag; /* HDF4 variable */ - int32 iRef; /* HDF4 variable */ +#ifndef HDF4 +typedef int int32; #endif +typedef struct { + int32 iTag; /* HDF4 variable */ + int32 iRef; /* HDF4 variable */ #ifdef HDF5 char iTag5[1024]; /* HDF5 variable */ char iRef5[1024]; /* HDF5 variable */ char iRefd[1024]; /* HDF5 variable */ -#endif +#endif + char targetPath[1024]; /* XML path */ } NXlink; @@ -146,6 +156,7 @@ typedef struct { # define NXmakegroup MANGLE(nximakegroup) # define NXopengroup MANGLE(nxiopengroup) # define NXopenpath MANGLE(nxiopenpath) +# define NXopengrouppath MANGLE(nxiopengrouppath) # define NXclosegroup MANGLE(nxiclosegroup) # define NXmakedata MANGLE(nximakedata) # define NXcompmakedata MANGLE(nxicompmakedata) @@ -157,6 +168,7 @@ typedef struct { # define NXputattr MANGLE(nxiputattr) # define NXgetdataID MANGLE(nxigetdataid) # define NXmakelink MANGLE(nximakelink) +# define NXopensourcegroup MANGLE(nxiopensourcegroup) # define NXmalloc MANGLE(nximalloc) # define NXfree MANGLE(nxifree) # define NXflush MANGLE(nxiflush) @@ -174,6 +186,7 @@ typedef struct { # define NXsameID MANGLE(nxisameid) # define NXinitgroupdir MANGLE(nxiinitgroupdir) # define NXinitattrdir MANGLE(nxiinitattrdir) +# define NXsetnumberformat MANGLE(nxisetnumberformat) # define NXsetcache MANGLE(nxisetcache) /* FORTRAN helpers - for NeXus internal use only */ # define NXfopen MANGLE(nxifopen) @@ -217,6 +230,7 @@ typedef struct { # define NXmakegroup MANGLE(NXIMAKEGROUP) # define NXopengroup MANGLE(NXIOPENGROUP) # define NXopenpath MANGLE(NXIOPENPATH) +# define NXopengrouppath MANGLE(NXIOPENGROUPPATH) # define NXclosegroup MANGLE(NXICLOSEGROUP) # define NXmakedata MANGLE(NXIMAKEDATA) # define NXcompress MANGLE(NXICOMPRESS) @@ -237,10 +251,12 @@ typedef struct { # define NXgetnextentry MANGLE(NXIGETNEXTENTRY) # define NXgetattrinfo MANGLE(NXIGETATTRINFO) # define NXinitattrdir MANGLE(NXIINITATTRDIR) +# define NXsetnumberformat MANGLE(NXISETNUMBERFORMAT) # define NXgetnextattr MANGLE(NXIGETNEXTATTR) # define NXgetgroupID MANGLE(NXIGETGROUPID) # define NXgetdataID MANGLE(NXIGETDATAID) # define NXmakelink MANGLE(NXIMAKELINK) +# define NXopensourcegroup MANGLE(NXIOPENSOURCEGROUP) # define NXmalloc MANGLE(NXIMALLOC) # define NXfree MANGLE(NXIFREE) /* FORTRAN helpers - for NeXus internal use only */ @@ -267,9 +283,10 @@ NX_EXTERNAL NXstatus CALLING_STYLE NXopen(CONSTCHAR * filename, NXaccess access NX_EXTERNAL NXstatus CALLING_STYLE NXclose(NXhandle* pHandle); NX_EXTERNAL NXstatus CALLING_STYLE NXflush(NXhandle* pHandle); -NX_EXTERNAL NXstatus CALLING_STYLE NXmakegroup (NXhandle handle, CONSTCHAR *name, char* NXclass); -NX_EXTERNAL NXstatus CALLING_STYLE NXopengroup (NXhandle handle, CONSTCHAR *name, char* NXclass); +NX_EXTERNAL NXstatus CALLING_STYLE NXmakegroup (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass); +NX_EXTERNAL NXstatus CALLING_STYLE NXopengroup (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass); NX_EXTERNAL NXstatus CALLING_STYLE NXopenpath (NXhandle handle, CONSTCHAR *path); +NX_EXTERNAL NXstatus CALLING_STYLE NXopengrouppath (NXhandle handle, CONSTCHAR *path); NX_EXTERNAL NXstatus CALLING_STYLE NXclosegroup(NXhandle handle); @@ -285,6 +302,7 @@ NX_EXTERNAL NXstatus CALLING_STYLE NXputslab(NXhandle handle, void* data, int s NX_EXTERNAL NXstatus CALLING_STYLE NXgetdataID(NXhandle handle, NXlink* pLink); NX_EXTERNAL NXstatus CALLING_STYLE NXmakelink(NXhandle handle, NXlink* pLink); +NX_EXTERNAL NXstatus CALLING_STYLE NXopensourcegroup(NXhandle handle); NX_EXTERNAL NXstatus CALLING_STYLE NXgetdata(NXhandle handle, void* data); NX_EXTERNAL NXstatus CALLING_STYLE NXgetinfo(NXhandle handle, int* rank, int dimension[], int* datatype); @@ -300,22 +318,64 @@ NX_EXTERNAL NXstatus CALLING_STYLE NXsameID(NXhandle handle, NXlink* pFirstID, NX_EXTERNAL NXstatus CALLING_STYLE NXinitgroupdir(NXhandle handle); NX_EXTERNAL NXstatus CALLING_STYLE NXinitattrdir(NXhandle handle); +NX_EXTERNAL NXstatus CALLING_STYLE NXsetnumberformat(NXhandle handle, + int type, char *format); NX_EXTERNAL NXstatus CALLING_STYLE NXmalloc(void** data, int rank, int dimensions[], int datatype); NX_EXTERNAL NXstatus CALLING_STYLE NXfree(void** data); /*----------------------------------------------------------------------- - A non Nexus standard function to set an error handler -*/ + NAPI internals +------------------------------------------------------------------------*/ NX_EXTERNAL void CALLING_STYLE NXMSetError(void *pData, void (*ErrFunc)(void *pD, char *text)); -NX_EXTERNAL void CALLING_STYLE NXNXNXReportError(void *pData,char *text); +extern void (*NXIReportError)(void *pData,char *text); +extern void *NXpData; + /* another special function for setting the default cache size for HDF-5 */ NX_EXTERNAL NXstatus CALLING_STYLE NXsetcache(long newVal); +/* + * 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, CONSTCHAR* NXclass); + NXstatus (CALLING_STYLE *nxopengroup) (NXhandle handle, CONSTCHAR *name, CONSTCHAR* 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); + NXstatus (CALLING_STYLE *nxsetnumberformat)(NXhandle handle, + int type,char *format); + } NexusFunction, *pNexusFunction; + /*---------------------*/ + extern long nx_cacheSize; #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/napi.tex b/napi.tex deleted file mode 100644 index 74d08343..00000000 --- a/napi.tex +++ /dev/null @@ -1,1850 +0,0 @@ -% Copyleft (c) 1997 by Mark Koennecke at PSI, Switzerland. -% -% -% This software 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 General Public License for more details. -% -% You may already have a copy of the GNU General Public License; if -% not, write to the Free Software Foundation, Inc., 675 Mass Ave, -% Cambridge, MA 02139, USA. -% - -\documentclass[12pt]{article} -\usepackage[dvips] - -\setlength{\oddsidemargin}{-.1in} -\setlength{\evensidemargin}{0in} -\setlength{\topmargin}{0in} -\addtolength{\topmargin}{-\headheight} -\addtolength{\topmargin}{-\headsep} -\setlength{\textheight}{8.9in} -\setlength{\textwidth}{6.2in} -\setlength{\marginparwidth}{0.5in} - -\begin{document} -\title{The NeXus Application Programmer's Interface} - -\author{Mark K\"onnecke\\ - Labor f\"ur Neutronenstreuung\\ - Paul Scherrer Institut\\ - CH-5232 Villigen PSI\\ - Switzerland\\ - Mark.Koennecke@psi.ch \\ - Przemek K\l{}osowski\\ - U. of Maryland \& NIST \\ - przemek.klosowski@nist.gov -} - -} - -\maketitle -\tableofcontents - -\vskip.3in -\centerline{\large\bf Abstract} -\vskip.2in -\begin{center} -\parbox{.8\textwidth}{ - There is a proposed portable data exchange format for neutron and - X-ray scattering communities, NeXus (described in a separate - publication). The present document supplements the NeXus proposal, - by defining a simplified, NeXus-compliant programming interface for - reading and writing NeXus files. -} -\end{center} - -\section{Introduction} -\label{chap:intro} - -This file defines an Application Programmer's Interface (API) to HDF -library as used for the NeXus data format. It encapsulates a subset of -HDF and provides some helper routines to simplify creating and reading -NeXus data files. - -The API is designed to be modal; there is a hidden state that -determines which groups and datasets (Vgroups and SDSes) are open at -any given moment, and subsequent operations are implicitly performed -on these entities. This cuts down the number of parameters to pass -around in API calls, at the cost of forcing certain pre-approved {\em -mode d'emploi}. This mode d'emploi will be familiar to most: it is very -similar to navigating a directory hierarchy. In our case HDF--VGroups are -the directories, which can hold other directories and data items which are -restricted to being HDF--scientific data sets (SDS). - -The API comprises the following functional groups: - -\begin{enumerate} -\item General initialization and shutdown: opening and closing the file, - creating or opening an existing group or dataset, and closing them. -\item Reading and writing data and attributes to previously opened datasets. -\item Routines to obtain meta-data and to iterate over component datasets and attributes. -\item Handling of linking and group hierarchy. -\end{enumerate} - - - -\section{Implementation} - -\subsection{Data Structures} -The approach used in this version is to maintain a datastructure for each -open file. This datastructure will hold a stack of Vgroups traversed and -will thus allow stepping back and forth in the NeXus file structure. The -stack is implemented using an array. The datastructure looks like this: -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap1} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ typedef struct __NexusFile {@\\ -\mbox{}\verb@ int iNXID;@\\ -\mbox{}\verb@ int32 iVID;@\\ -\mbox{}\verb@ int32 iSID;@\\ -\mbox{}\verb@ int32 iCurrentVG;@\\ -\mbox{}\verb@ int32 iCurrentSDS;@\\ -\mbox{}\verb@ int32 iStack[NXMAXSTACK];@\\ -\mbox{}\verb@ int iStackPtr; @\\ -\mbox{}\verb@ int iNDir;@\\ -\mbox{}\verb@ int iCurDir;@\\ -\mbox{}\verb@ int *iRefDir;@\\ -\mbox{}\verb@ int *iTagDir;@\\ -\mbox{}\verb@ } NexusFile, *pNexusFile;@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -The fields in more detail: \begin{itemize} -\item iNXID is a test value against memory corruption. -\item iVID is the file ID to use for the Vgroup interface. -\item iSID is the file ID to use for the SDS interface. -\item iCurrentVG is the ID of the current open Vgroup. Is 0, if there is - no Vgroup open. -\item iCurrentSDS is the ID of the current open SDS. Is 0, if there is - no SDS open. -\item iStack is the stack array. -\item iStackPtr is the pointer to the current Vgroup in iStack. -\item iNDir, iCurDir, iRefDir, iTagDir are data fields used during an -directory search with NXgetnextentry. They are: -\begin{itemize} -\item iNDir: number of directory entries. -\item iCurDir current directory entry. -\item iRefDir array of reference numbers. -\item iTagDir array of tag numbers. - -\end{itemize} -\end{itemize} - -The other datastructure used is NXlink. It encapsulates all information -necessary to do a link between Vgroups and SDS's. This is easy: - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap2} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ typedef struct {@\\ -\mbox{}\verb@ int32 iTag;@\\ -\mbox{}\verb@ int32 iRef;@\\ -\mbox{}\verb@ } NXlink;@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -Before diving into code, it may be helpful to highlight a few pecularities -of the HDF interface which help confuse the code. The first is, that there -is no single ID to refer to a given file. The Vgroup interface and the SDS -interface use two different ID's which have to be initialised at file -opening and used apropriatetly. - -The other feature is the plethora of integer ID's associated with each -HDF--object. First there is something called a reference ID which seems to -be an ID which identifies an object within an HDF file. Coming with it there -is a tag, which denotes the type of the object. When things need to be done -to an object, HDF requires to attach or open the object. These calls usually -return another ID which can than be used furtheron. This becomes invalid -once you close the object again. So much bookeeping is needed to keep track -of all these ID's. \label{ididid} - - - -\subsection{General initialization and shutdown} -\label{ss:gen} - - -The routines in this group are for opening and closing the NeXus/HDF file, -creating or opening an existing group or dataset, and closing them. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap3} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@NXhandle NXopen(char * filename, NXaccess access_method);@\\ -\mbox{}\verb@NXstatus NXclose(NXhandle fileid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@NXstatus NXmakegroup (NXhandle fileid, char* Vgroup, char* NXclass);@\\ -\mbox{}\verb@NXstatus NXopengroup (NXhandle fileid, char* Vgroup, char* NXclass);@\\ -\mbox{}\verb@NXstatus NXclosegroup(NXhandle fileid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@NXstatus NXmakedata (NXhandle fileid, char* label, int datatype, int rank, int dim[]);@\\ -\mbox{}\verb@NXstatus NXopendata (NXhandle fileid, char* label);@\\ -\mbox{}\verb@NXstatus NXclosedata(NXhandle fileid);@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXopen} -NXopen opens the HDF--file filename and creates and initialises a NexusFile -structure. The returned handle is actually the pointer to this structure. -This danger of this aproach is, that somebody might try arithemetic on the -handle and thereby corrupt the system. In order to test for this the -NexusFile structure contains the NXID field which can be checked against a -predefined value. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap4} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXhandle NXopen(char *filename, NXaccess am)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pNew = NULL;@\\ -\mbox{}\verb@ char pBuffer[512];@\\ -\mbox{}\verb@ int iRet;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* get memory */@\\ -\mbox{}\verb@ pNew = (pNexusFile)malloc(sizeof(NexusFile));@\\ -\mbox{}\verb@ if(!pNew)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData, "ERROR: no memory to create File datastructure");@\\ -\mbox{}\verb@ return NULL;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ memset(pNew,0,sizeof(NexusFile));@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* start SDS interface */@\\ -\mbox{}\verb@ pNew->iSID = SDstart(filename,am);@\\ -\mbox{}\verb@ if(pNew->iSID <= 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pBuffer,"ERROR: cannot open file: %s",filename);@\\ -\mbox{}\verb@ NXIReportError(NXpData,pBuffer);@\\ -\mbox{}\verb@ free(pNew);@\\ -\mbox{}\verb@ return NULL;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* otherwise we try to create the file two times which makes HDF@\\ -\mbox{}\verb@ Trow up on us.@\\ -\mbox{}\verb@ */@\\ -\mbox{}\verb@ if(am == NXACC_CREATE)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ am = NXACC_RDWR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* start Vgroup API */@\\ -\mbox{}\verb@ pNew->iVID = Hopen(filename,am,100);@\\ -\mbox{}\verb@ if(pNew->iVID <= 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pBuffer,"ERROR: cannot open file: %s",filename);@\\ -\mbox{}\verb@ NXIReportError(NXpData,pBuffer);@\\ -\mbox{}\verb@ free(pNew);@\\ -\mbox{}\verb@ return NULL;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ iRet = Vstart(pNew->iVID);@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF cannot initalise Vgroup interface");@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ pNew->iNXID = NXSIGNATURE;@\\ -\mbox{}\verb@ pNew->iStack[0] = 0; /* root! */@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ return (NXhandle)pNew; @\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXclose} -NXclose closes an Nexus file and deletes all associated datastructures from -memory. The handle fileid will no longer be valid after this. -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap5} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXclose(NXhandle fid)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile = NULL;@\\ -\mbox{}\verb@ int iRet; @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* close links into vGroups or SDS */@\\ -\mbox{}\verb@ if(pFile->iCurrentVG != 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ Vdetach(pFile->iCurrentVG);@\\ -\mbox{}\verb@ } @\\ -\mbox{}\verb@ if(pFile->iCurrentSDS != 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = SDendaccess(pFile->iCurrentSDS);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: ending access to SDS");@\\ -\mbox{}\verb@ } @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* close the SDS and Vgroup API's */@\\ -\mbox{}\verb@ Vend(pFile->iVID);@\\ -\mbox{}\verb@ iRet = SDend(pFile->iSID);@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF cannot close SDS interface");@\\ -\mbox{}\verb@ } @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ iRet = Hclose(pFile->iVID);@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF cannot close HDF file");@\\ -\mbox{}\verb@ } @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* release memory */@\\ -\mbox{}\verb@ NXIKillDir(pFile);@\\ -\mbox{}\verb@ free(pFile);@\\ -\mbox{}\verb@ return NX_OK; @\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXmakegroup} -NXmakegroup creates a new Vgroup at the current level in the Vgroup -hierarchy. The new Vgroup will have the name Vgroup and have the class -descriptor NXclass. This call does not open the new group automatically. -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap6} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXmakegroup(NXhandle fid, char *name, char *class)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ int32 iNew, iRet;@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ pFile = NXIassert(fid); @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* create and configure the group */@\\ -\mbox{}\verb@ iNew = Vattach(pFile->iVID,-1,"w"); @\\ -\mbox{}\verb@ if(iNew < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF could not create Vgroup");@\\ -\mbox{}\verb@ return NX_ERROR; @\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ Vsetname(iNew,name);@\\ -\mbox{}\verb@ Vsetclass(iNew,class);@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* insert it into the hierarchy, when apropriate */@\\ -\mbox{}\verb@ if(pFile->iCurrentVG != 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = Vinsert(pFile->iCurrentVG,iNew);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ Vdetach(iNew);@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF failed to insert Vgroup");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXopengroup} -NXopengroup opens an existing Vgroup for writing and reading data to it. -This routine maintains the Vgroup stack. There are several possible -situations. The first is that we are at root level (iCurrentVG = 0). The -vGroup must be found and attatched to. Than the Stack has to be incremented. -The next situation is, that we are already in a Vgroup. Than we have to find -the new Vgroup, detach the current Vgroup and attach to the new one, thereby -incrementing the stack. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap7} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@/*------------------------------------------------------------------------*/@\\ -\mbox{}\verb@ NXstatus NXopengroup(NXhandle fid, char *name, char *class)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ int32 iNew, iRef;@\\ -\mbox{}\verb@ char pBuffer[256];@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ iRef = NXIFindVgroup(pFile,name,class);@\\ -\mbox{}\verb@ if(iRef < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pBuffer,"ERROR: Vgroup %s, class %s NOT found",name,class);@\\ -\mbox{}\verb@ NXIReportError(NXpData,pBuffer);@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ } @\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* are we at root level ? */@\\ -\mbox{}\verb@ if(pFile->iCurrentVG == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pFile->iCurrentVG = Vattach(pFile->iVID,iRef,"w");@\\ -\mbox{}\verb@ if(pFile->iCurrentVG < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pBuffer,"ERROR: cannot attach to vGroup %s",name);@\\ -\mbox{}\verb@ NXIReportError(NXpData,pBuffer);@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ pFile->iStackPtr++;@\\ -\mbox{}\verb@ pFile->iStack[pFile->iStackPtr] = iRef;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ Vdetach(pFile->iCurrentVG);@\\ -\mbox{}\verb@ pFile->iStackPtr++;@\\ -\mbox{}\verb@ pFile->iStack[pFile->iStackPtr] = iRef;@\\ -\mbox{}\verb@ pFile->iCurrentVG = Vattach(pFile->iVID,@\\ -\mbox{}\verb@ pFile->iStack[pFile->iStackPtr],@\\ -\mbox{}\verb@ "w");@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ NXIKillDir(pFile);@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXclosegroup} -NXclosegroup closes an open Vgroup and travels one back in the Vgroup -hierarchy. The usual hassle with the tons of different indices again. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap8} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXclosegroup(NXhandle fid)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* first catch the trivial case: we are at root and cannot get @\\ -\mbox{}\verb@ deeper into a negative directory hierarchy (anti-directory)@\\ -\mbox{}\verb@ */@\\ -\mbox{}\verb@ if(pFile->iCurrentVG = 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIKillDir(pFile);@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else /* Sighhh. Some work to do */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ /* close the current VG and decrement stack */@\\ -\mbox{}\verb@ Vdetach(pFile->iCurrentVG);@\\ -\mbox{}\verb@ pFile->iStackPtr--;@\\ -\mbox{}\verb@ if(pFile->iStackPtr <= 0) /* we hit root */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pFile->iStackPtr = 0;@\\ -\mbox{}\verb@ pFile->iCurrentVG = 0;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ /* attach to the lower Vgroup */@\\ -\mbox{}\verb@ pFile->iCurrentVG = Vattach(pFile->iVID,@\\ -\mbox{}\verb@ pFile->iStack[pFile->iStackPtr],@\\ -\mbox{}\verb@ "w");@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ NXIKillDir(pFile);@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXmakedata} -NXmakedata creates a new scientific datset. As argument it takes the usual filehandle, -Than there is an integer denoting the datatype. This needs to be one of the -HDF defined type identifiers. Commonly used types are: DFNT\_FLOAT for 32 bit -floats, DFNT\_INT32 for 32-bit integers, DFNT\_UINT8 for unsigned bytes (or -characters). rank is the dimensionality of the data. The parameter dims is -an integer array which has rank values. Each value denotes the length of the -data in the dimensions. Note that this function does not open a dataset. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap9} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXmakedata(NXhandle fid, char *name, int datatype, int rank, @\\ -\mbox{}\verb@ int dimensions[])@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ int32 iNew;@\\ -\mbox{}\verb@ char pBuffer[256];@\\ -\mbox{}\verb@ int i, iRet;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* do some argument checking */@\\ -\mbox{}\verb@ if( (datatype != DFNT_FLOAT32) && (datatype != DFNT_FLOAT64) &&@\\ -\mbox{}\verb@ (datatype != DFNT_INT8) && (datatype != DFNT_UINT8) &&@\\ -\mbox{}\verb@ (datatype != DFNT_INT16) && (datatype != DFNT_UINT16) &&@\\ -\mbox{}\verb@ (datatype != DFNT_INT32) && (datatype != DFNT_UINT32))@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pBuffer,"ERROR: unknown datatype specified for SDS %s",@\\ -\mbox{}\verb@ name);@\\ -\mbox{}\verb@ NXIReportError(NXpData,pBuffer);@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ if(rank <= 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pBuffer,"ERROR: invalid rank specified for SDS %s",@\\ -\mbox{}\verb@ name);@\\ -\mbox{}\verb@ NXIReportError(NXpData,pBuffer);@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ for(i = 0; i < rank; i++)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ if(dimensions[i] <= 0 )@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pBuffer,@\\ -\mbox{}\verb@ "ERROR: invalid dimension %d, value %d given for SDS %s",@\\ -\mbox{}\verb@ i,dimensions[i], name);@\\ -\mbox{}\verb@ NXIReportError(NXpData,pBuffer);@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* behave nicely, if there is still an SDS open */@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS != 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ SDendaccess(pFile->iCurrentSDS);@\\ -\mbox{}\verb@ pFile->iCurrentSDS = 0;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* dataset creation */@\\ -\mbox{}\verb@ iNew = SDcreate(pFile->iSID,name,datatype,rank,dimensions);@\\ -\mbox{}\verb@ if(iNew < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pBuffer,"ERROR: cannot create SDS %s, check argumenst",@\\ -\mbox{}\verb@ name);@\\ -\mbox{}\verb@ NXIReportError(NXpData,pBuffer);@\\ -\mbox{}\verb@ return NX_ERROR; @\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ /* link into Vgroup, if in one */@\\ -\mbox{}\verb@ if(pFile->iCurrentVG != 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = Vaddtagref(pFile->iCurrentVG,DFTAG_SDG,SDidtoref(iNew));@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ iRet = SDendaccess(iNew);@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF cannot end access to SDS");@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXopendata} -NXopendata opens a scientific data set for further manipulation, i.e. reading -and writing of data or getting information about it. The scientific dataset -must exist. -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap10} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXopendata(NXhandle fid, char *name)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ int32 iNew; @\\ -\mbox{}\verb@ char pBuffer[256];@\\ -\mbox{}\verb@ int iRet;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* first find the reference number of the SDS */@\\ -\mbox{}\verb@ iNew = NXIFindSDS(fid,name);@\\ -\mbox{}\verb@ if(iNew < 0) @\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pBuffer,"ERROR: SDS %s not found at this level",name);@\\ -\mbox{}\verb@ NXIReportError(NXpData,pBuffer);@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* be nice: properly close the old open SDS silently if there is@\\ -\mbox{}\verb@ still an SDS open.@\\ -\mbox{}\verb@ */@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = SDendaccess(pFile->iCurrentSDS);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = 1;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF cannot end access to SDS");@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* clear pending attribute directories first */@\\ -\mbox{}\verb@ NXIKillDir(pFile);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* open the SDS */@\\ -\mbox{}\verb@ iNew = SDreftoindex(pFile->iSID, iNew);@\\ -\mbox{}\verb@ pFile->iCurrentSDS = SDselect(pFile->iSID,iNew);@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF error opening SDS");@\\ -\mbox{}\verb@ pFile->iCurrentSDS = 0;@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXclosedata} -NXclosedata ends the access to the currently active scientific dataset. -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap11} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXclosedata(NXhandle fid)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ int iRet;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS != 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = SDendaccess(pFile->iCurrentSDS);@\\ -\mbox{}\verb@ pFile->iCurrentSDS = 0;@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF cannot end access to SDS");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: no SDS open --> nothing to do");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ NXIKillDir(pFile); /* for attribute data */@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsection{Reading and writing} -\label{ss:rw} - -Routines to read and write data and attributes to previously opened datasets: - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap12} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@NXstatus NXgetdata(NXhandle fileid, void* data);@\\ -\mbox{}\verb@NXstatus NXgetslab(NXhandle fileid, void* data, int start[], int size[]);@\\ -\mbox{}\verb@NXstatus NXgetattr(NXhandle fileid, char* name, char* data, int datalen);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@NXstatus NXputdata(NXhandle fileid, void* data);@\\ -\mbox{}\verb@NXstatus NXputslab(NXhandle fileid, void* data, int start[], int size[]);@\\ -\mbox{}\verb@NXstatus NXputattr(NXhandle fileid, char* name, char* data, int datalen);@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -Please note, that all data reading and writing routines require that the -scientific dataset has been opened beforehand with NXopenadata. - -\subsubsection{NXgetdata} -NXgetdata reads data from the currently open scientific data set into -data. Please note, that memory overwrite occurs if the caller has not -allocated enough memory to hold all the data available. There are functions -in the section \ref{ss:meta} which allow to inquire the data size first. - -Note as well that the scientific dataset must have been opened with -NXopendata before this function can succeed. Before it can do its job, -NXgetdata has to get dimension information first. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap13} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXgetdata(NXhandle fid, void *data)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ int32 iStart[MAX_VAR_DIMS], iEnd[MAX_VAR_DIMS];@\\ -\mbox{}\verb@ NXname pBuffer;@\\ -\mbox{}\verb@ int32 iRank, iAtt, iType;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* check if there is an SDS open */@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: no SDS open");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* first read dimension information */@\\ -\mbox{}\verb@ memset(iStart,0,MAX_VAR_DIMS*sizeof(int32));@\\ -\mbox{}\verb@ SDgetinfo(pFile->iCurrentSDS,pBuffer,&iRank,iEnd,&iType,&iAtt);@\\ -\mbox{}\verb@ /* actually read */@\\ -\mbox{}\verb@ SDreaddata(pFile->iCurrentSDS,iStart,NULL,iEnd,data);@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXgetslab} -NXgetslab reads a subset of the data in the current scientific data set. -The start dimensions to read from are specified in iStart, the end in iEnd. -The caller is responsable for allocation enough memory for data. -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap14} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXgetslab(NXhandle fid, void *data, int iStart[], int iEnd[])@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* check if there is an SDS open */@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: no SDS open");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* actually read */@\\ -\mbox{}\verb@ SDreaddata(pFile->iCurrentSDS,iStart,NULL,iEnd,data);@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXgetattr} -HDF has the concept of attributes. This is additional data which goes with -usually an SDS. Such attributes are used to denotes axis, units etc. The -other class of attributes are global attributes. This function reads such -attributes. If an SDS is open, it reads the attributes associated with the SDS, else -the it tries to find a global attribute. The data read is transfered to -data, but maximum datalen bytes. The caller is responsible for allocating at -least datalen bytes for data. In order to enable this scheme, NXgetattr -has to read the first into an internal temporary buffer before it copies the -data to the datat buffer provided. And discards with the temporary buffer. -Note that searching for attributes is handled differently if attributes at -global level are searched compared to searching attributes in an SDS. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap15} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXgetattr(NXhandle fid, char *name, char *data, int datalen)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ int32 iNew;@\\ -\mbox{}\verb@ void *pData = NULL;@\\ -\mbox{}\verb@ int32 iLen, iType, iRet;@\\ -\mbox{}\verb@ char pBuffer[256];@\\ -\mbox{}\verb@ NXname pNam; @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* find attribute */@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS != 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ /* SDS attribute */@\\ -\mbox{}\verb@ iNew = SDfindattr(pFile->iCurrentSDS,name);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ /* global attribute */@\\ -\mbox{}\verb@ iNew = SDfindattr(pFile->iSID,name);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ if(iNew < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pBuffer,"ERROR: attribute %s not found",name);@\\ -\mbox{}\verb@ NXIReportError(NXpData,pBuffer);@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ } @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* get more info, allocate temporary data space */@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS != 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = SDattrinfo(pFile->iCurrentSDS,iNew,pNam,&iType,&iLen);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = SDattrinfo(pFile->iSID,iNew,pNam,&iType,&iLen);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pBuffer,"ERROR: HDF could not read attribute info");@\\ -\mbox{}\verb@ NXIReportError(NXpData,pBuffer);@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ iLen = iLen*DFKNTsize(iType); @\\ -\mbox{}\verb@ pData = (void *)malloc(iLen);@\\ -\mbox{}\verb@ if(!pData)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: allocating memory in NXgetattr");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ memset(pData,0,iLen);@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* finally read the data */@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS != 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = SDreadattr(pFile->iCurrentSDS,iNew,pData);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = SDreadattr(pFile->iSID,iNew,pData);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pBuffer,"ERROR: HDF could not read attribute data");@\\ -\mbox{}\verb@ NXIReportError(NXpData,pBuffer);@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* copy data to caller */@\\ -\mbox{}\verb@ memset(data,0,datalen);@\\ -\mbox{}\verb@ if(datalen < iLen)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iLen = datalen - 1;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ memcpy(data,pData,iLen);@\\ -\mbox{}\verb@ free(pData);@\\ -\mbox{}\verb@ return NX_OK; @\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXputdata} -NXputdata copies data into the currently open scientific data set in the -HDF file. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap16} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXputdata(NXhandle fid, void *data)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ int32 iStart[MAX_VAR_DIMS], iEnd[MAX_VAR_DIMS], iStride[MAX_VAR_DIMS];@\\ -\mbox{}\verb@ NXname pBuffer;@\\ -\mbox{}\verb@ int32 iRank, iAtt, iType, iRet, i;@\\ -\mbox{}\verb@ char pError[512];@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* check if there is an SDS open */@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: no SDS open");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* first read dimension information */@\\ -\mbox{}\verb@ memset(iStart,0,MAX_VAR_DIMS*sizeof(int32));@\\ -\mbox{}\verb@ SDgetinfo(pFile->iCurrentSDS,pBuffer,&iRank,iEnd,&iType,&iAtt);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* initialise stride to 1 */@\\ -\mbox{}\verb@ for(i = 0; i < iRank; i++)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iStride[i] = 1;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* actually write */@\\ -\mbox{}\verb@ iRet = SDwritedata(pFile->iCurrentSDS,iStart,iStride,iEnd,data);@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sprintf(pError,"ERROR: failure to write data to %s",pBuffer);@\\ -\mbox{}\verb@ NXIReportError(NXpData,pError);@\\ -\mbox{}\verb@ return NX_ERROR; @\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXputslab} -NXputslab writes an subset of data as specified by iStart to iEnd into the -currently open SDS. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap17} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXputslab(NXhandle fid, void *data, int iStart[], int iEnd[])@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ int iRet;@\\ -\mbox{}\verb@ int iStride[MAX_VAR_DIMS], i;@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* check if there is an SDS open */@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: no SDS open");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* initialise stride to 1 */@\\ -\mbox{}\verb@ for(i = 0; i < MAX_VAR_DIMS; i++)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iStride[i] = 1;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* actually write */@\\ -\mbox{}\verb@ iRet = SDwritedata(pFile->iCurrentSDS,iStart,iStride,iEnd,data);@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: writing slab failed");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXputattr} -Nxputattr puts an attribute into an Nexus file.If an SDS is open, the SDS -will get the attribute. If not, a global attribute will be generated. -Attributes are name = value pairs. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap18} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXputattr(NXhandle fid, char *name, char *data, int datalen)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ int iRet;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS != 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ /* SDS attribute */@\\ -\mbox{}\verb@ iRet = SDsetattr(pFile->iCurrentSDS,name,DFNT_UINT8,@\\ -\mbox{}\verb@ datalen,data);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ /* global attribute */@\\ -\mbox{}\verb@ iRet = SDsetattr(pFile->iSID,name,DFNT_UINT8,@\\ -\mbox{}\verb@ datalen, data);@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDf failed to store attribute ");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsection{Meta-data} -\label{ss:meta} - -Routines to obtain meta-data and to iterate over component datasets and attributes. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap19} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@NXstatus NXgetinfo (NXhandle fileid, int* rank, int dimension[], int* datatype);@\\ -\mbox{}\verb@NXstatus NXgetnextentry (NXhandle fileid, NXname name, NXname class, int* datatype);@\\ -\mbox{}\verb@NXstatus NXgetnextattr(NXhandle fileid, NXname pName, int *iLength, int *iType);@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXgetinfo} -NXgetinfo gets information about an SDS. rank is the dimesionality of the -data, dimension will contain the size of the data in each dimension and -datatype results to one of the HDF--datatypes. The SDS has to be open in -order for this routine to work. -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap20} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXgetinfo(NXhandle fid, int *rank,int dimension[], int *iType)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ NXname pBuffer;@\\ -\mbox{}\verb@ int32 iAtt;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* check if there is an SDS open */@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: no SDS open");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* read information */@\\ -\mbox{}\verb@ SDgetinfo(pFile->iCurrentSDS,pBuffer,rank,dimension,iType,&iAtt);@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXgetnextentry} -NXgetnextentry implements a directory search facility on the current Vgroup -level. The first call will initialize Vgroup searching facilities and return -information on the first data item in the list. Subsequent calls will yield -information about the next item in the Vgroup. If the end of the list is -reached, NXgetentry will return NX\_EOD. Before, the usual NX\_ERROR or NX\_OK -are returned. Information returned is different for each type of data. For -Vgroups the name and class of the Vgroup will be returned, iType will be 0. -For scientific data sets, the name field will be the name, class will be SDS -and iType will denote the number type of the scientific data set. For types -not known to Nexus (but to HDF) both name and class will be set to -"UNKNOWN". - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap21} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ int NXgetnextentry(NXhandle fid, NXname name, NXname class, int *datatype)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ int iRet; @\\ -\mbox{}\verb@ int32 iTemp, iD1, iD2, iA;@\\ -\mbox{}\verb@ int32 iDim[MAX_VAR_DIMS];@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* first case to check for: no directory entry */@\\ -\mbox{}\verb@ if(pFile->iRefDir == NULL)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = NXIInitDir(pFile);@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData, @\\ -\mbox{}\verb@ "ERROR: no memory to store directory info");@\\ -\mbox{}\verb@ return -1;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* next case: end of directory */@\\ -\mbox{}\verb@ if(pFile->iCurDir >= pFile->iNDir)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIKillDir(pFile);@\\ -\mbox{}\verb@ return NX_EOD;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* next case: we have data! suppy it and increment counter */@\\ -\mbox{}\verb@ if(pFile->iCurrentVG == 0) /* root level */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iTemp = Vattach(pFile->iVID,pFile->iRefDir[pFile->iCurDir],@\\ -\mbox{}\verb@ "r");@\\ -\mbox{}\verb@ if(iTemp < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF cannot attach to Vgroup");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ Vgetname(iTemp,name);@\\ -\mbox{}\verb@ Vgetclass(iTemp,class);@\\ -\mbox{}\verb@ *datatype = DFTAG_VG;@\\ -\mbox{}\verb@ pFile->iCurDir++;@\\ -\mbox{}\verb@ Vdetach(iTemp);@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else /* in Vgroup */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ if(pFile->iTagDir[pFile->iCurDir] == DFTAG_VG) /* Vgroup */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iTemp = Vattach(pFile->iVID,pFile->iRefDir[pFile->iCurDir],@\\ -\mbox{}\verb@ "r");@\\ -\mbox{}\verb@ if(iTemp < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF cannot attach to Vgroup");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ Vgetname(iTemp,name);@\\ -\mbox{}\verb@ Vgetclass(iTemp,class);@\\ -\mbox{}\verb@ *datatype = DFTAG_VG;@\\ -\mbox{}\verb@ pFile->iCurDir++;@\\ -\mbox{}\verb@ Vdetach(iTemp);@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else if( (pFile->iTagDir[pFile->iCurDir] == DFTAG_SDG) ||@\\ -\mbox{}\verb@ (pFile->iTagDir[pFile->iCurDir] == DFTAG_NDG) )@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iTemp = SDreftoindex(pFile->iSID, @\\ -\mbox{}\verb@ pFile->iRefDir[pFile->iCurDir]);@\\ -\mbox{}\verb@ iTemp = SDselect(pFile->iSID,iTemp);@\\ -\mbox{}\verb@ SDgetinfo(iTemp,name,&iA,iDim,&iD1, &iD2);@\\ -\mbox{}\verb@ strcpy(class,"SDS");@\\ -\mbox{}\verb@ *datatype = iD1;@\\ -\mbox{}\verb@ SDendaccess(iTemp);@\\ -\mbox{}\verb@ pFile->iCurDir++;@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else /* unidentified */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ strcpy(name,"UNKNOWN");@\\ -\mbox{}\verb@ strcpy(class,"UNKNOWN");@\\ -\mbox{}\verb@ pFile->iCurDir++;@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ } @\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ return NX_ERROR; /* not reached */@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXgetnextattr} -NXgetnextattr works very much like NXgetnextentry except, that it works on -SDS attributes and not on Vgroup entries. This function allows to scan the -names of attributes available. iLength will be filled with the length of the -attributes data in byte. iType will be filled with the HDF type of the -attribute. Be warned: this routine returns global attributes when no SDS is -currently open. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap22} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\ -\mbox{}\verb@ NXstatus NXgetnextattr(NXhandle fileid, NXname pName, @\\ -\mbox{}\verb@ int *iLength, int *iType)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ int iRet;@\\ -\mbox{}\verb@ int32 iPType, iCount;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fileid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* first check if we have to start a new attribute search */@\\ -\mbox{}\verb@ if(pFile->iNDir == 0) @\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = NXIInitAttDir(pFile);@\\ -\mbox{}\verb@ if(iRet == NX_ERROR)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* are we done ? */@\\ -\mbox{}\verb@ if(pFile->iCurDir >= pFile->iNDir)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIKillDir(pFile);@\\ -\mbox{}\verb@ return NX_EOD;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* well, there must be data to copy */@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS == 0) /* global attribute */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = SDattrinfo(pFile->iSID,pFile->iCurDir, pName, &iPType,&iCount); @\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = SDattrinfo(pFile->iCurrentSDS,pFile->iCurDir,@\\ -\mbox{}\verb@ pName, &iPType,&iCount);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF cannot read attribute info");@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ *iLength = iCount*DFKNTsize(iPType);@\\ -\mbox{}\verb@ *iType = iPType;@\\ -\mbox{}\verb@ pFile->iCurDir++;@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsection{ Handling of linking and group hierarchy} -\label{ss:link} - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap23} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@NXlink NXgetgroupID(NXhandle fileid);@\\ -\mbox{}\verb@NXlink NXgetdataID(NXhandle fileid);@\\ -\mbox{}\verb@NXstatus NXmakelink(NXhandle fileid, NXlink link);@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{ NXgetgroupID} -NXgetgroupID retrieves the ID and tag of the currently open -Vgroup in an NXlink strcuture. In case of an error the iTag field of this -structure will contain NX\_ERROR. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap24} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXlink NXgetgroupID(NXhandle fileid)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ NXlink sRes;@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ pFile = NXIassert(fileid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ if(pFile->iCurrentVG == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sRes.iTag = NX_ERROR;@\\ -\mbox{}\verb@ return sRes;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sRes.iTag = DFTAG_VG;@\\ -\mbox{}\verb@ sRes.iRef = pFile->iCurrentVG;@\\ -\mbox{}\verb@ return sRes;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ /* not reached */@\\ -\mbox{}\verb@ sRes.iTag = NX_ERROR;@\\ -\mbox{}\verb@ return sRes;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{NXgetdataID} -NXgetdataID retrieves the tag and reference number of the current data -object. Returns NX\_ERROR if none is open. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap25} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXlink NXgetdataID(NXhandle fid)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@ NXlink sRes;@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ if(pFile->iCurrentSDS == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sRes.iTag = NX_ERROR;@\\ -\mbox{}\verb@ return sRes;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ sRes.iTag = DFTAG_SDS;@\\ -\mbox{}\verb@ sRes.iRef = SDidtoref(pFile->iCurrentSDS);@\\ -\mbox{}\verb@ return sRes;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ sRes.iTag = NX_ERROR;@\\ -\mbox{}\verb@ return sRes; /* not reached */@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{ NXlink} -NXlink links a Vgroup or SDS into a Vgroup. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap26} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ NXstatus NXmakelink(NXhandle fid, NXlink sLink)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pFile;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ if(pFile->iCurrentVG == 0) /* root level, can not link here */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ if(sLink.iTag == DFTAG_VG)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ Vinsert(pFile->iCurrentVG,sLink.iRef);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else @\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ Vaddtagref(pFile->iCurrentVG, sLink.iTag,sLink.iRef);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsection{Internal routines} -There are a couple of internal Nexus API routines which are declared -static and are not visible outside of the module. First a few -defines. - - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap27} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@#include @\\ -\mbox{}\verb@#include @\\ -\mbox{}\verb@#include @\\ -\mbox{}\verb@#include "fortify.h"@\\ -\mbox{}\verb@#include "napi.h"@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@#define NXMAXSTACK 50@\\ -\mbox{}\verb@#define NXSIGNATURE 959697@\\ -\mbox{}\verb@@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -MAXSTACK denotes the maximum depth of Vgroup stacking permissible. If there -are problems, feel free to increase this value and recompile. 50 is probably -fairly generous. - -NXSIGNATURE is just the signature which the Nexus API will check for on -handles in order to prevent against tampering with the handles. - -NXMAXNAME is the number of characters permitted for names and Vgroup names. - -The internal function NXIassert will convert a filehandle to a pointer -to a NexusFile datastructure. Furthermore, it will check the signature and -throw an assertion, when the signature does not match. - - -\subsubsection{NX error handling} - -As each piece of non trivial software the Nexus API needs a error handling -policy. The policy implemented is as follows: The NX routines terminate when -an invalid NXhandle has been specified. This is a serious programmer error. -In any other case the NX routines are meant to complain, recover and present -an NX-ERROR return to the higher level code. That code is than responsible -to deal with the problem. The problem left is error reporting. This is done -througout the code by a call to NXIReportError. This function takes as first -parameter a pointer to void and as next parameter the string with the -complaint. The default implementation of NXIReportError will print to -stdout. However, there are environments where this strategy is not feasible -because stdout is supported only in a very strange way. Think about -operating system like MS-Windows, MAC-OS (going to die anyway) or other -windowing systems. In order to cater for this there is an inofficial support -function which allows to set both a pointer to a datastructure and a new -function for error reporting. This is called NXMSetError. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap28} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@/*---------------------------------------------------------------------*/@\\ -\mbox{}\verb@ static void NXNXNXReportError(void *pData, char *string)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ printf("%s \n",string);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@/*---------------------------------------------------------------------*/@\\ -\mbox{}\verb@ static void *NXpData = NULL;@\\ -\mbox{}\verb@ static void (*NXIReportError)(void *pData, char *string) =@\\ -\mbox{}\verb@ NXNXNXReportError;@\\ -\mbox{}\verb@/*---------------------------------------------------------------------*/@\\ -\mbox{}\verb@ void NXMSetError(void *pData, void (*NewError)(void *pD, char *text))@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXpData = pData;@\\ -\mbox{}\verb@ NXIReportError = NewError;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap29} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@/*--------------------------------------------------------------------*/@\\ -\mbox{}\verb@ static pNexusFile NXIassert(NXhandle fid)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile pRes;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ assert(fid);@\\ -\mbox{}\verb@ pRes = (pNexusFile)fid;@\\ -\mbox{}\verb@ assert(pRes->iNXID == NXSIGNATURE);@\\ -\mbox{}\verb@ return pRes;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{ Object finding dunctions} - -Routines for finding objects in an HDF file have to cope with two quirks in -the HDF interface. The first is that the root level is no Vgroup. This -implies that the root level is searched for objects using different routines -than searching for objects in a Vgroup. The last one uses, of course, Vgroup -interface routines. - -Finding routines have to cope with the plethora of different integer -ID's for any given HDF object. See \ref{ididid} for more details. - - -NXIFindVgroup searches the current Vgroup level in the file for the -occurence of a Vgroup with a specified name and of a specified class. If no -suitable Vgroup can be found NIXFinfVgroup returns -1, else the ID of the -Vgroup. -NXIFindVgroup has to cope with the plethora of different integer -ID's for any give Vgroup. There is the Vgroup ID, than there is the -reference number which can be obtained by Vgettagref and which can refer to -any object in the HDF file. Additionally there is a Tag which denotes the -type of the object. - - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap30} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@/*----------------------------------------------------------------------*/@\\ -\mbox{}\verb@ static int32 NXIFindVgroup(pNexusFile pFile, char *name, char *class)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ int32 iNew, iRef, iTag;@\\ -\mbox{}\verb@ int iN, i;@\\ -\mbox{}\verb@ int32 *pArray = NULL;@\\ -\mbox{}\verb@ NXname pText;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ assert(pFile);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ if(pFile->iCurrentVG == 0) /* root level */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ /* get the number and ID's of all lone Vgroups in the file */@\\ -\mbox{}\verb@ iN = Vlone(pFile->iVID,NULL,0);@\\ -\mbox{}\verb@ pArray = (int32 *)malloc(iN*sizeof(int32));@\\ -\mbox{}\verb@ if(!pArray)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: out of memory in NXIFindVgroup");@\\ -\mbox{}\verb@ return -1;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ Vlone(pFile->iVID,pArray,iN);@\\ -\mbox{}\verb@ @\\ -\mbox{}\verb@ /* loop and check */@\\ -\mbox{}\verb@ for(i = 0; i < iN; i++)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iNew = Vattach(pFile->iVID,pArray[i],"r");@\\ -\mbox{}\verb@ Vgetname(iNew, pText);@\\ -\mbox{}\verb@ if(strcmp(pText,name) == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ Vgetclass(iNew,pText);@\\ -\mbox{}\verb@ if(strcmp(pText,class) == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ /* found !*/@\\ -\mbox{}\verb@ Vdetach(iNew);@\\ -\mbox{}\verb@ iNew = pArray[i];@\\ -\mbox{}\verb@ free(pArray);@\\ -\mbox{}\verb@ return iNew;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ Vdetach(iNew);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ /* nothing found */@\\ -\mbox{}\verb@ free(pArray); @\\ -\mbox{}\verb@ return -1; @\\ -\mbox{}\verb@ } @\\ -\mbox{}\verb@ else /* case in Vgroup */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iN = Vntagrefs(pFile->iCurrentVG);@\\ -\mbox{}\verb@ for(i = 0; i < iN; i++)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ Vgettagref(pFile->iCurrentVG,i,&iTag, &iRef);@\\ -\mbox{}\verb@ if(iTag == DFTAG_VG)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iNew = Vattach(pFile->iVID,iRef,"r");@\\ -\mbox{}\verb@ Vgetname(iNew, pText);@\\ -\mbox{}\verb@ if(strcmp(pText,name) == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ Vgetclass(iNew,pText);@\\ -\mbox{}\verb@ if(strcmp(pText,class) == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ /* found !*/@\\ -\mbox{}\verb@ Vdetach(iNew);@\\ -\mbox{}\verb@ return iRef;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ Vdetach(iNew);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ } /* end for */ @\\ -\mbox{}\verb@ } /* end else */ @\\ -\mbox{}\verb@ /* not found */@\\ -\mbox{}\verb@ return -1;@\\ -\mbox{}\verb@ } @\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -NXIFindSDS searches the current Vgroup level for an SDS name. It returns -the reference ID of the SDS when found and -1 when no SDS of this name can -be found on this level. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap31} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ static int32 NXIFindSDS(NXhandle fid, char *name)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ pNexusFile self;@\\ -\mbox{}\verb@ int32 iNew, iRet, iTag, iRef;@\\ -\mbox{}\verb@ int32 i, iN, iA, iD1, iD2;@\\ -\mbox{}\verb@ NXname pNam;@\\ -\mbox{}\verb@ int32 iDim[MAX_VAR_DIMS];@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ self = NXIassert(fid);@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ /* root level search */@\\ -\mbox{}\verb@ if(self->iCurrentVG == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ i = SDfileinfo(self->iSID,&iN,&iA);@\\ -\mbox{}\verb@ if(i < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData, "ERROR: failure to read file information");@\\ -\mbox{}\verb@ return -1;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ for(i = 0; i < iN; i++)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iNew = SDselect(self->iSID,i);@\\ -\mbox{}\verb@ SDgetinfo(iNew,pNam,&iA,iDim,&iD2, &iD2);@\\ -\mbox{}\verb@ if(strcmp(pNam,name) == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = SDidtoref(iNew);@\\ -\mbox{}\verb@ SDendaccess(iNew);@\\ -\mbox{}\verb@ return iRet;@\\ -\mbox{}\verb@ } @\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ SDendaccess(iNew);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ /* not found */@\\ -\mbox{}\verb@ return -1;@\\ -\mbox{}\verb@ }/* end root level */@\\ -\mbox{}\verb@ else /* search in a Vgroup */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iN = Vntagrefs(self->iCurrentVG);@\\ -\mbox{}\verb@ for(i = 0; i < iN; i++)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ Vgettagref(self->iCurrentVG,i,&iTag, &iRef);@\\ -\mbox{}\verb@ if( (iTag == DFTAG_SDG) || (iTag == DFTAG_NDG) || @\\ -\mbox{}\verb@ (iTag == DFTAG_SDS) )@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iNew = SDreftoindex(self->iSID, iRef);@\\ -\mbox{}\verb@ iNew = SDselect(self->iSID,iNew);@\\ -\mbox{}\verb@ SDgetinfo(iNew,pNam,&iA,iDim,&iD2, &iD2);@\\ -\mbox{}\verb@ if(strcmp(pNam,name) == 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ SDendaccess(iNew);@\\ -\mbox{}\verb@ return iRef;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ SDendaccess(iNew);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ } /* end for */ @\\ -\mbox{}\verb@ } /* end Vgroup */@\\ -\mbox{}\verb@ /* we get here, only if nothing found */@\\ -\mbox{}\verb@ return -1; @\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\subsubsection{Helper routines for directory search} -NXIInitDir initialises the directory data fields in the Nexus File structure -for a subsequent directory request. Please note, that at root level only -Vgroups will be searched. When searching SDS's at root level, all SDS's in -the whole -file seem to be returned. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap32} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ static int NXIInitDir(pNexusFile self)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ int i;@\\ -\mbox{}\verb@ int32 iTag, iRef;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ if(self->iCurrentVG == 0) /* root level */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ /* get the number and ID's of all lone Vgroups in the file */@\\ -\mbox{}\verb@ self->iNDir = Vlone(self->iVID,NULL,0);@\\ -\mbox{}\verb@ self->iRefDir = (int32 *)malloc(self->iNDir*sizeof(int32));@\\ -\mbox{}\verb@ if(!self->iRefDir)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: out of memory in NXIInitDir");@\\ -\mbox{}\verb@ return -1;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ Vlone(self->iVID,self->iRefDir,self->iNDir);@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ /* Vgroup level */@\\ -\mbox{}\verb@ self->iNDir = Vntagrefs(self->iCurrentVG);@\\ -\mbox{}\verb@ self->iRefDir = (int32 *)malloc(self->iNDir*sizeof(int32));@\\ -\mbox{}\verb@ self->iTagDir = (int32 *)malloc(self->iNDir*sizeof(int32));@\\ -\mbox{}\verb@ if( (!self->iRefDir) || (!self->iTagDir))@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: out of memory in NXIInitDir");@\\ -\mbox{}\verb@ return -1;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ for(i = 0; i < self->iNDir; i++)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ Vgettagref(self->iCurrentVG,i,&iTag, &iRef);@\\ -\mbox{}\verb@ self->iRefDir[i] = iRef;@\\ -\mbox{}\verb@ self->iTagDir[i] = iTag;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ } @\\ -\mbox{}\verb@ self->iCurDir = 0;@\\ -\mbox{}\verb@ return 1;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -NXIKillDir removes all data associated with a directory search from - memory. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap33} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@ static void NXIKillDir(pNexusFile self)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ if(self->iRefDir)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ free(self->iRefDir);@\\ -\mbox{}\verb@ self->iRefDir = NULL;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ if(self->iTagDir)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ free(self->iTagDir);@\\ -\mbox{}\verb@ self->iTagDir = NULL;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ self->iCurDir = 0;@\\ -\mbox{}\verb@ self->iNDir = 0;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -NXIInitAttDir will initialise the counters for reading either SDS or global -attribute data. - -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap34} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@/*-------------------------------------------------------------------------*/@\\ -\mbox{}\verb@ static int NXIInitAttDir(pNexusFile pFile)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ int iRet;@\\ -\mbox{}\verb@ int32 iData, iAtt, iRank, iType;@\\ -\mbox{}\verb@ int32 iDim[MAX_VAR_DIMS];@\\ -\mbox{}\verb@ NXname pNam;@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ pFile->iCurDir = 0;@\\ -\mbox{}\verb@ if(pFile->iCurrentSDS != 0) /* SDS level */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = SDgetinfo(pFile->iCurrentSDS,pNam, &iRank, iDim,&iType, @\\ -\mbox{}\verb@ &iAtt); @\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ else /* global level */@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ iRet = SDfileinfo(pFile->iSID,&iData,&iAtt); @\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ if(iRet < 0)@\\ -\mbox{}\verb@ {@\\ -\mbox{}\verb@ NXIReportError(NXpData,"ERROR: HDF cannot read attribute numbers");@\\ -\mbox{}\verb@ pFile->iNDir = 0;@\\ -\mbox{}\verb@ return NX_ERROR;@\\ -\mbox{}\verb@ }@\\ -\mbox{}\verb@ pFile->iNDir = iAtt;@\\ -\mbox{}\verb@ return NX_OK;@\\ -\mbox{}\verb@ }@\\ -\end{list} -\vspace{-1ex} -\footnotesize\addtolength{\baselineskip}{-1ex} -\end{minipage}\\[4ex] -\end{flushleft} -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap35} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@/*---------------------------------------------------------------------------@\\ -\mbox{}\verb@ Nexus API header file@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ copyleft: Mark Koennecke, March 1997 at LNS,PSI, Switzerland@\\ -\mbox{}\verb@ Przemek Klosowski, U. of Maryland & NIST, USA @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ No warranties of any kind taken.@\\ -\mbox{}\verb@----------------------------------------------------------------------------*/@\\ -\mbox{}\verb@#ifndef NEXUSAPI@\\ -\mbox{}\verb@#define NEXUSAPI@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@#include @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@typedef enum {NXACC_READ = DFACC_READ, @\\ -\mbox{}\verb@ NXACC_RDWR = DFACC_RDWR, @\\ -\mbox{}\verb@ NXACC_CREATE = DFACC_CREATE } NXaccess;@\\ -\mbox{}\verb@typedef void * NXhandle;@\\ -\mbox{}\verb@typedef int NXstatus;@\\ -\mbox{}\verb@typedef char NXname[VGNAMELENMAX];@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@#define NX_OK 1@\\ -\mbox{}\verb@#define NX_ERROR 0@\\ -\mbox{}\verb@#define NX_EOD -1@\\ -\mbox{}\verb@/*-------------------------------------------------------------------------@\\ -\mbox{}\verb@ HDF Datatype values for datatype parameters @\\ -\mbox{}\verb@ in the Nexus API@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ DFNT_FLOAT32 32 bit float@\\ -\mbox{}\verb@ DFNT_FLOAT64 64 nit float == double@\\ -\mbox{}\verb@ DFNT_INT8 8 bit integer ==char, byte@\\ -\mbox{}\verb@ DFNT_UINT8 8 bit unsigned integer@\\ -\mbox{}\verb@ DFNT_INT16 16 bit integer@\\ -\mbox{}\verb@ DFNT_UINT16 16 bit unsigned integer@\\ -\mbox{}\verb@ DFNT_INT32 32 bit integer@\\ -\mbox{}\verb@ DFNT_UINT32 32 bit unsigned integer@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ This list is a edited version of the one found in the HDF header file@\\ -\mbox{}\verb@ htndefs.h. That source will always be the real reference, this is@\\ -\mbox{}\verb@ documented here for your convenience.@\\ -\mbox{}\verb@--------------------------------------------------------------------------*/ @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@/*-----------------------------------------------------------------------@\\ -\mbox{}\verb@ A non Nexus standars function to set an error handler @\\ -\mbox{}\verb@*/@\\ -\mbox{}\verb@ void NXMSetError(void *pData, void (*ErrFunc)(void *pD, char *text));@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@#endif@\\ -\mbox{}\verb@@\\ -\end{list} -\vspace{-2ex} -\end{minipage}\\[4ex] -\end{flushleft} -\begin{flushleft} \small -\begin{minipage}{\linewidth} \label{scrap36} -\vspace{-1ex} -\begin{list}{}{} \item -\mbox{}\verb@@\\ -\mbox{}\verb@/*---------------------------------------------------------------------------@\\ -\mbox{}\verb@ Nexus API implementation file.@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ For documentation see the Napi.tex file which comes with this @\\ -\mbox{}\verb@ distribution.@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ copyleft: Mark Koennecke@\\ -\mbox{}\verb@ Labor fuer Neutronenstreuung@\\ -\mbox{}\verb@ Paul Scherrer Institut@\\ -\mbox{}\verb@ CH-5232 Villigen-PSI@\\ -\mbox{}\verb@ Switzerland@\\ -\mbox{}\verb@ Mark.Koenencke@{\tt @}\verb@psi.ch@\\ -\mbox{}\verb@ Przemek Klosowski@\\ -\mbox{}\verb@ U. of Maryland & NIST @\\ -\mbox{}\verb@ przemek.klosowski@{\tt @}\verb@nist.gov @\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ no warranties of any kind, whether explicit or implied, taken.@\\ -\mbox{}\verb@ Distributed under the GNU copyleft license as documented elsewhere.@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ March 1997@\\ -\mbox{}\verb@@\\ -\mbox{}\verb@ Version: 1.0@\\ -\mbox{}\verb@----------------------------------------------------------------------------*/@\\ -\end{list} -\vspace{-2ex} -\end{minipage}\\[4ex] -\end{flushleft} -\end{document} diff --git a/napi4.c b/napi4.c index 4da84b52..45974ee1 100644 --- a/napi4.c +++ b/napi4.c @@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA For further information, see + + $Id: napi4.c,v 1.4 2005/05/27 11:58:06 koennecke Exp $ ----------------------------------------------------------------------------*/ #include @@ -27,6 +29,11 @@ #include #include +#include "napi.h" +#include "napi4.h" + +extern void *NXpData; + typedef struct __NexusFile { struct iStack { int32 *iRefDir; @@ -45,8 +52,7 @@ int iStackPtr; char iAccess[2]; } NexusFile, *pNexusFile; - - + /*--------------------------------------------------------------------*/ static pNexusFile NXIassert(NXhandle fid) @@ -61,7 +67,7 @@ /* --------------------------------------------------------------------- */ - static int32 NXIFindVgroup (pNexusFile pFile, char *name, char *nxclass) + static int32 NXIFindVgroup (pNexusFile pFile, CONSTCHAR *name, CONSTCHAR *nxclass) { int32 iNew, iRef, iTag; int iN, i; @@ -285,8 +291,28 @@ self->iAtt.iCurDir = 0; self->iAtt.iNDir = 0; } +/*------------------------------------------------------------------*/ + static void NXIbuildPath(pNexusFile pFile, char *buffer, int bufLen) + { + int i; + int32 groupID, iA, iD1, iD2, iDim[MAX_VAR_DIMS]; + NXname pText; - + buffer[0] = '\0'; + for(i = 0; i < pFile->iStackPtr; i++){ + strncat(buffer,"/",bufLen-strlen(buffer)); + groupID = Vattach(pFile->iVID,pFile->iStack[pFile->iStackPtr].iVref, + "r"); + Vgetname(groupID, pText); + strncat(buffer,pText,bufLen-strlen(buffer)); + Vdetach(groupID); + } + if(pFile->iCurrentSDS != 0){ + strncat(buffer,"/",bufLen-strlen(buffer)); + SDgetinfo(pFile->iCurrentSDS,pText,&iA,iDim,&iD1,&iD2); + strncat(buffer,pText,bufLen-strlen(buffer)); + } + } /* ---------------------------------------------------------------------- Definition of NeXus API @@ -294,7 +320,8 @@ ---------------------------------------------------------------------*/ - NXstatus CALLING_STYLE NX4open(CONSTCHAR *filename, NXaccess am, NXhandle* pHandle) + NXstatus CALLING_STYLE NX4open(CONSTCHAR *filename, NXaccess am, + NXhandle* pHandle) { pNexusFile pNew = NULL; char pBuffer[512], time_buffer[64]; @@ -331,9 +358,11 @@ /* * get time in ISO 8601 format */ + +/* #ifdef NEED_TZSET tzset(); -#endif /* NEED_TZSET */ +#endif time(&timer); #ifdef USE_FTIME ftime(&timeb_struct); @@ -349,8 +378,10 @@ NXIReportError(NXpData, "Your gmtime() function does not work ... timezone information will be incorrect\n"); gmt_offset = 0; } -#endif /* USE_FTIME */ +#endif time_info = localtime(&timer); +*/ + time_info = NULL; if (time_info != NULL) { if (gmt_offset < 0) { time_format = "%04d-%02d-%02d %02d:%02d:%02d-%02d%02d"; @@ -505,7 +536,7 @@ /*-----------------------------------------------------------------------*/ - NXstatus CALLING_STYLE NX4makegroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + NXstatus CALLING_STYLE NX4makegroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) { pNexusFile pFile; int32 iNew, iRet; @@ -549,7 +580,7 @@ /*------------------------------------------------------------------------*/ - NXstatus CALLING_STYLE NX4opengroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + NXstatus CALLING_STYLE NX4opengroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) { pNexusFile pFile; int32 iRef; @@ -1130,7 +1161,7 @@ } iType = type; if (iRet < 0) { - NXIReportError (NXpData, "ERROR: HDf failed to store attribute "); + NXIReportError (NXpData, "ERROR: HDF failed to store attribute "); return NX_ERROR; } return NX_OK; @@ -1208,6 +1239,7 @@ } else { sRes->iTag = DFTAG_NDG; sRes->iRef = SDidtoref (pFile->iCurrentSDS); + NXIbuildPath(pFile,sRes->targetPath,1024); return NX_OK; } sRes->iTag = NX_ERROR; @@ -1221,14 +1253,24 @@ NXstatus CALLING_STYLE NX4makelink (NXhandle fid, NXlink* sLink) { pNexusFile pFile; - int32 iVG, iRet; + int32 iVG, iRet, dataID, type = DFNT_CHAR8, length; + char name[] = "target"; pFile = NXIassert (fid); if (pFile->iCurrentVG == 0) { /* root level, can not link here */ return NX_ERROR; } - Vaddtagref (pFile->iCurrentVG, sLink->iTag, sLink->iRef); + Vaddtagref(pFile->iCurrentVG, sLink->iTag, sLink->iRef); + if(sLink->iTag == DFTAG_SDG || sLink->iTag == DFTAG_NDG || + sLink->iTag == DFTAG_SDS) + { + dataID = SDreftoindex(pFile->iSID,sLink->iRef); + dataID = SDselect(pFile->iSID,dataID); + length = strlen(sLink->targetPath); + SDsetattr(dataID,name,type,length,sLink->targetPath); + SDendaccess(dataID); + } return NX_OK; } @@ -1687,6 +1729,7 @@ } else { sRes->iTag = DFTAG_VG; sRes->iRef = VQueryref(pFile->iCurrentVG); + NXIbuildPath(pFile,sRes->targetPath,1024); return NX_OK; } /* not reached */ @@ -1765,3 +1808,34 @@ return NX_OK; } +/*--------------------------------------------------------------------*/ +void NX4assignFunctions(pNexusFunction fHandle) +{ + 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; +} diff --git a/napi4.h b/napi4.h index 733544d4..927d58a8 100644 --- a/napi4.h +++ b/napi4.h @@ -1,6 +1,7 @@ #define NXSIGNATURE 959697 -#include "napi4.c" +#include "napi.h" +/* #include "napi4.c" */ /* * HDF4 interface @@ -10,8 +11,8 @@ NX_EXTERNAL NXstatus CALLING_STYLE NX4open(CONSTCHAR *filename, NXaccess access NX_EXTERNAL NXstatus CALLING_STYLE NX4close(NXhandle* pHandle); NX_EXTERNAL NXstatus CALLING_STYLE NX4flush(NXhandle* pHandle); -NX_EXTERNAL NXstatus CALLING_STYLE NX4makegroup (NXhandle handle, CONSTCHAR* Vgroup, char* NXclass); -NX_EXTERNAL NXstatus CALLING_STYLE NX4opengroup (NXhandle handle, CONSTCHAR* Vgroup, char* NXclass); +NX_EXTERNAL NXstatus CALLING_STYLE NX4makegroup (NXhandle handle, CONSTCHAR* Vgroup, CONSTCHAR* NXclass); +NX_EXTERNAL NXstatus CALLING_STYLE NX4opengroup (NXhandle handle, CONSTCHAR* Vgroup, CONSTCHAR* NXclass); NX_EXTERNAL NXstatus CALLING_STYLE NX4closegroup(NXhandle handle); NX_EXTERNAL NXstatus CALLING_STYLE NX4makedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]); @@ -40,4 +41,6 @@ NX_EXTERNAL NXstatus CALLING_STYLE NX4getnextattr(NXhandle handle, NXname pName NX_EXTERNAL NXstatus CALLING_STYLE NX4getgroupID(NXhandle handle, NXlink* pLink); NX_EXTERNAL NXstatus CALLING_STYLE NX4getdataID(NXhandle handle, NXlink* pLink); NX_EXTERNAL NXstatus CALLING_STYLE NX4makelink(NXhandle handle, NXlink* pLink); +void NX4assignFunctions(pNexusFunction fHandle); + diff --git a/napi45.c b/napi45.c deleted file mode 100644 index a80e9322..00000000 --- a/napi45.c +++ /dev/null @@ -1,630 +0,0 @@ -#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); - } diff --git a/napi5.c b/napi5.c index 6d8c0330..29dd38d5 100644 --- a/napi5.c +++ b/napi5.c @@ -27,10 +27,8 @@ #include #include -/* #include "napi.h" #include "napi5.h" -*/ extern void *NXpData; @@ -114,7 +112,8 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); ---------------------------------------------------------------------*/ - NXstatus CALLING_STYLE NX5open(CONSTCHAR *filename, NXaccess am, NXhandle* pHandle) + NXstatus CALLING_STYLE NX5open(CONSTCHAR *filename, NXaccess am, + NXhandle* pHandle) { hid_t attr1,aid1, aid2; pNexusFile5 pNew = NULL; @@ -128,11 +127,7 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); unsigned int vers_major, vers_minor, vers_release, am1 ; hid_t fapl; int mdc_nelmts; -#ifdef H5_WANT_H5_V1_4_COMPAT - unsigned int rdcc_nelmts; -#else - size_t rdcc_nelmts; -#endif + unsigned long rdcc_nelmts; size_t rdcc_nbytes; double rdcc_w0; @@ -395,7 +390,7 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); /*-----------------------------------------------------------------------*/ - NXstatus CALLING_STYLE NX5makegroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + NXstatus CALLING_STYLE NX5makegroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) { pNexusFile5 pFile; hid_t iRet; @@ -451,7 +446,7 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); return strstr(member_name, attr_name) ? 1 : 0; } - NXstatus CALLING_STYLE NX5opengroup (NXhandle fid, CONSTCHAR *name, char *nxclass) + NXstatus CALLING_STYLE NX5opengroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) { pNexusFile5 pFile; @@ -870,6 +865,8 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); /* ------------------------------------------------------------------- */ + + NXstatus CALLING_STYLE NX5putdata (NXhandle fid, void *data) { pNexusFile5 pFile; @@ -1090,7 +1087,8 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); if(pFile->iCurrentD <= 0){ return NX_ERROR; } - strcpy(sRes->iRef5,pFile->name_ref); + strcpy(sRes->iRef5,"/"); + strcat(sRes->iRef5,pFile->name_ref); strcpy(sRes->iRefd,pFile->iCurrentLD); return NX_OK; } @@ -1101,10 +1099,11 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); { pNexusFile5 pFile; /* int iRet; */ - herr_t status; + herr_t status, dataID, aid1, aid2, attID; int size_type; char buffer[1024]; - + char name[] = "target"; + pFile = NXI5assert (fid); if (pFile->iCurrentG == 0) { /* root level, can not link here */ return NX_ERROR; @@ -1132,6 +1131,36 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); strcat(sLink->iTag5,sLink->iRefd); } status = H5Glink(pFile->iFID, H5G_LINK_HARD, sLink->iRef5, sLink->iTag5); + if(size_type > 0) + { + dataID = H5Dopen(pFile->iFID,sLink->iRef5); + /* + remove old attribute if existing + */ + status = H5Aopen_name(dataID,name); + if(status > 0) + { + H5Aclose(status); + status = H5Adelete(dataID,name); + if(status < 0) + { + return NX_OK; + } + } + aid2 = H5Screate(H5S_SCALAR); + aid1 = H5Tcopy(H5T_C_S1); + H5Tset_size(aid1,strlen(sLink->iRef5)); + attID = H5Acreate(dataID,name,aid1,aid2,H5P_DEFAULT); + if(attID < 0) + { + return NX_OK; + } + H5Awrite(attID,aid1,sLink->iRef5); + H5Tclose(aid1); + H5Sclose(aid2); + H5Aclose(attID); + H5Dclose(dataID); + } return NX_OK; } @@ -2070,3 +2099,35 @@ NXstatus CALLING_STYLE NX5closegroup (NXhandle fid); NXI5KillDir (fid); return NX_OK; } +/*------------------------------------------------------------------------*/ +void NX5assignFunctions(pNexusFunction fHandle) +{ + 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; + +} diff --git a/napi5.h b/napi5.h index 69a39ea7..5c4b6664 100644 --- a/napi5.h +++ b/napi5.h @@ -1,7 +1,6 @@ #define NX5SIGNATURE 959695 #include -#include "napi5.c" /* HDF5 interface */ @@ -9,8 +8,8 @@ NX_EXTERNAL NXstatus CALLING_STYLE NX5open(CONSTCHAR *filename, NXaccess access NX_EXTERNAL NXstatus CALLING_STYLE NX5close(NXhandle* pHandle); NX_EXTERNAL NXstatus CALLING_STYLE NX5flush(NXhandle* pHandle); -NX_EXTERNAL NXstatus CALLING_STYLE NX5makegroup (NXhandle handle, CONSTCHAR *name, char* NXclass); -NX_EXTERNAL NXstatus CALLING_STYLE NX5opengroup (NXhandle handle, CONSTCHAR *name, char* NXclass); +NX_EXTERNAL NXstatus CALLING_STYLE NX5makegroup (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass); +NX_EXTERNAL NXstatus CALLING_STYLE NX5opengroup (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass); NX_EXTERNAL NXstatus CALLING_STYLE NX5closegroup(NXhandle handle); NX_EXTERNAL NXstatus CALLING_STYLE NX5makedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]); @@ -40,6 +39,7 @@ NX_EXTERNAL NXstatus CALLING_STYLE NX5getgroupinfo(NXhandle handle, int* no_ite NX_EXTERNAL NXstatus CALLING_STYLE NX5initgroupdir(NXhandle handle); NX_EXTERNAL NXstatus CALLING_STYLE NX5initattrdir(NXhandle handle); +void NX5assignFunctions(pNexusFunction fHandle); herr_t nxgroup_info(hid_t loc_id, const char *name, void *op_data); herr_t attr_info(hid_t loc_id, const char *name, void *opdata); diff --git a/napif.f b/napif.f deleted file mode 100644 index 9b9c127c..00000000 --- a/napif.f +++ /dev/null @@ -1,274 +0,0 @@ -C---------------------------------------------------------------------------- -C NeXus - Neutron & X-ray Common Data Format -C -C API Fortran Interface -C -C $Id: napif.f,v 1.1 2000/02/07 10:38:58 cvs Exp $ -C -C Copyright (C) 1997, Freddie Akeroyd -C ISIS Facility, Rutherford Appleton Laboratory, UK -C -C See NAPI.C for further details -C -C 22/2/98 - Correct an NXfclose problem (free() of FORTRAN memory) -C 97/7/30 - Initial Release -C 97/7/31 - Correct NXPUTATTR/NXGETATTR and make 'implicit none' clean -C 97/8/7 - Update interface -C---------------------------------------------------------------------------- - -C *** Return length of a string, ignoring trailing blanks - INTEGER FUNCTION TRUELEN(STRING) - CHARACTER*(*) STRING - DO TRUELEN=LEN(STRING),1,-1 - IF (STRING(TRUELEN:TRUELEN) .NE. ' ') RETURN - ENDDO - TRUELEN = 0 - END - -C *** Convert FORTRAN string STRING into NULL terminated C string ISTRING - SUBROUTINE EXTRACT_STRING(ISTRING, LENMAX, STRING) - CHARACTER*(*) STRING - INTEGER I,ILEN,TRUELEN,LENMAX - BYTE ISTRING(LENMAX) - EXTERNAL TRUELEN - ILEN = TRUELEN(STRING) -C WRITE(6,*)'TRUELEN: ', ILEN - IF (ILEN .GE. LENMAX) THEN - WRITE(6,9000) LENMAX, ILEN+1 - RETURN - ENDIF - DO I=1,ILEN - ISTRING(I) = ICHAR(STRING(I:I)) - ENDDO - ISTRING(ILEN+1) = 0 - RETURN - 9000 FORMAT('NAPIF: String too long - buffer needs increasing from ', - + i4,' to at least ',i4) - END - -C *** Convert NULL terminated C string ISTRING to FORTRAN string STRING - SUBROUTINE REPLACE_STRING(STRING, ISTRING) - BYTE ISTRING(*) - CHARACTER*(*) STRING - INTEGER I - STRING = ' ' - DO I=1,LEN(STRING) - IF (ISTRING(I) .EQ. 0) RETURN - STRING(I:I) = CHAR(ISTRING(I)) - ENDDO - WRITE(6,9010) LEN(STRING) - RETURN - 9010 FORMAT('NAPIF: String truncated - buffer needs to be > ', I4) - END - -C *** Wrapper routines for NXAPI interface - INTEGER FUNCTION NXOPEN(FILENAME, ACCESS_METHOD, FILEID) - CHARACTER*(*) FILENAME - BYTE IFILENAME(256) - INTEGER ACCESS_METHOD - INTEGER FILEID(*),NXIFOPEN - EXTERNAL NXIFOPEN - CALL EXTRACT_STRING(IFILENAME, 256, FILENAME) - NXOPEN = NXIFOPEN(IFILENAME, ACCESS_METHOD, FILEID) - END - - INTEGER FUNCTION NXCLOSE(FILEID) - INTEGER FILEID(*),NXIFCLOSE - EXTERNAL NXIFCLOSE - NXCLOSE = NXIFCLOSE(FILEID) - END - - INTEGER FUNCTION NXMAKEGROUP(FILEID, VGROUP, NXCLASS) - INTEGER FILEID(*),NXIMAKEGROUP - CHARACTER*(*) VGROUP, NXCLASS - BYTE IVGROUP(256), INXCLASS(256) - EXTERNAL NXIMAKEGROUP - CALL EXTRACT_STRING(IVGROUP, 256, VGROUP) - CALL EXTRACT_STRING(INXCLASS, 256, NXCLASS) - NXMAKEGROUP = NXIMAKEGROUP(FILEID, IVGROUP, INXCLASS) - END - - INTEGER FUNCTION NXOPENGROUP(FILEID, VGROUP, NXCLASS) - INTEGER FILEID(*),NXIOPENGROUP - CHARACTER*(*) VGROUP, NXCLASS - BYTE IVGROUP(256), INXCLASS(256) - EXTERNAL NXIOPENGROUP - CALL EXTRACT_STRING(IVGROUP, 256, VGROUP) - CALL EXTRACT_STRING(INXCLASS, 256, NXCLASS) - NXOPENGROUP = NXIOPENGROUP(FILEID, IVGROUP, INXCLASS) - END - - INTEGER FUNCTION NXCLOSEGROUP(FILEID) - INTEGER FILEID(*),NXICLOSEGROUP - EXTERNAL NXICLOSEGROUP - NXCLOSEGROUP = NXICLOSEGROUP(FILEID) - END - - INTEGER FUNCTION NXMAKEDATA(FILEID, LABEL, DATATYPE, RANK, DIM) - INTEGER FILEID(*), DATATYPE, RANK, DIM(*), NXIFMAKEDATA - CHARACTER*(*) LABEL - BYTE ILABEL(256) - EXTERNAL NXIFMAKEDATA - CALL EXTRACT_STRING(ILABEL, 256, LABEL) - NXMAKEDATA = NXIFMAKEDATA(FILEID, ILABEL, DATATYPE, RANK, DIM) - END - - INTEGER FUNCTION NXOPENDATA(FILEID, LABEL) - INTEGER FILEID(*),NXIOPENDATA - CHARACTER*(*) LABEL - BYTE ILABEL(256) - EXTERNAL NXIOPENDATA - CALL EXTRACT_STRING(ILABEL, 256, LABEL) - NXOPENDATA = NXIOPENDATA(FILEID, ILABEL) - END - - INTEGER FUNCTION NXCLOSEDATA(FILEID) - INTEGER FILEID(*),NXICLOSEDATA - EXTERNAL NXICLOSEDATA - NXCLOSEDATA = NXICLOSEDATA(FILEID) - END - - INTEGER FUNCTION NXGETDATA(FILEID, DATA) - INTEGER FILEID(*), DATA(*),NXIGETDATA - EXTERNAL NXIGETDATA - NXGETDATA = NXIGETDATA(FILEID, DATA) - END - - INTEGER FUNCTION NXGETSLAB(FILEID, DATA, START, SIZE) - INTEGER FILEID(*), DATA(*), START(*), SIZE(*) - INTEGER NXIGETSLAB - EXTERNAL NXIGETSLAB - NXGETSLAB = NXIGETSLAB(FILEID, DATA, START, SIZE) - END - - INTEGER FUNCTION NXIFGETCHARATTR(FILEID, INAME, DATA, - + DATALEN, TYPE) - INTEGER MAX_DATALEN,NX_ERROR - INTEGER FILEID(*), DATALEN, TYPE - PARAMETER(MAX_DATALEN=1024,NX_ERROR=0) - CHARACTER*(*) DATA - BYTE IDATA(MAX_DATALEN) - BYTE INAME(*) - INTEGER NXIGETATTR - EXTERNAL NXIGETATTR - IF (DATALEN .GE. MAX_DATALEN) THEN - WRITE(6,9020) DATALEN, MAX_DATALEN - NXIFGETCHARATTR=NX_ERROR - RETURN - ENDIF - NXIFGETCHARATTR = NXIGETATTR(FILEID, INAME, IDATA, DATALEN, TYPE) - IF (NXIFGETCHARATTR .NE. NX_ERROR) THEN - CALL REPLACE_STRING(DATA, IDATA) - ENDIF - RETURN - 9020 FORMAT('NXgetattr: asked for attribute size ', I4, - + ' with buffer size only ', I4) - END - - INTEGER FUNCTION NXGETATTR(FILEID, NAME, DATA, DATALEN, TYPE) - INTEGER FILEID(*),DATALEN,TYPE,NX_CHAR - PARAMETER(NX_CHAR=4) - CHARACTER*(*) NAME, DATA - BYTE INAME(256) - INTEGER NXIGETATTR, NXIFGETCHARATTR - EXTERNAL NXIGETATTR, NXIFGETCHARATTR - CALL EXTRACT_STRING(INAME, 256, NAME) - IF ((TYPE .EQ. NX_CHAR) .OR. (TYPE .EQ. NX_UINT8)) THEN - NXGETATTR = NXIFGETCHARATTR(FILEID, INAME, DATA, - + DATALEN, TYPE) - ELSE - NXGETATTR = NXIGETATTR(FILEID, INAME, DATA, DATALEN, TYPE) - ENDIF - END - - INTEGER FUNCTION NXPUTDATA(FILEID, DATA) - INTEGER FILEID(*), DATA(*), NXIPUTDATA - EXTERNAL NXIPUTDATA - NXPUTDATA = NXIPUTDATA(FILEID, DATA) - END - - INTEGER FUNCTION NXPUTSLAB(FILEID, DATA, START, SIZE) - INTEGER FILEID(*), DATA(*), START(*), SIZE(*) - INTEGER NXIPUTSLAB - EXTERNAL NXIPUTSLAB - NXPUTSLAB = NXIPUTSLAB(FILEID, DATA, START, SIZE) - END - - INTEGER FUNCTION NXIFPUTCHARATTR(FILEID, INAME, DATA, - + DATALEN, TYPE) - INTEGER FILEID(*), DATALEN, TYPE - BYTE INAME(*) - CHARACTER*(*) DATA - BYTE IDATA(1024) - INTEGER NXIFPUTATTR - EXTERNAL NXIFPUTATTR - CALL EXTRACT_STRING(IDATA, 1024, DATA) - NXIFPUTCHARATTR = NXIFPUTATTR(FILEID, INAME, IDATA, DATALEN, TYPE) - END - - INTEGER FUNCTION NXPUTATTR(FILEID, NAME, DATA, DATALEN, TYPE) - INTEGER FILEID(*), DATALEN, TYPE, NX_CHAR - PARAMETER(NX_CHAR=4) - CHARACTER*(*) NAME, DATA - BYTE INAME(256) - INTEGER NXIFPUTATTR, NXIFPUTCHARATTR - EXTERNAL NXIFPUTATTR, NXIFPUTCHARATTR - CALL EXTRACT_STRING(INAME, 256, NAME) - IF ((TYPE .EQ. NX_CHAR) .OR. (TYPE .EQ. NX_UINT8)) THEN - NXPUTATTR = NXIFPUTCHARATTR(FILEID, INAME, DATA, - + DATALEN, TYPE) - ELSE - NXPUTATTR = NXIFPUTATTR(FILEID, INAME, DATA, DATALEN, TYPE) - ENDIF - END - - INTEGER FUNCTION NXGETINFO(FILEID, RANK, DIM, DATATYPE) - INTEGER FILEID(*), RANK, DIM(*), DATATYPE - INTEGER I, J, NXIGETINFO - EXTERNAL NXIGETINFO - NXGETINFO = NXIGETINFO(FILEID, RANK, DIM, DATATYPE) -C *** Reverse dimension array as C is ROW major, FORTRAN column major - DO I = 1, RANK/2 - J = DIM(I) - DIM(I) = DIM(RANK-I+1) - DIM(RANK-I+1) = J - ENDDO - END - - INTEGER FUNCTION NXGETNEXTENTRY(FILEID, NAME, CLASS, DATATYPE) - INTEGER FILEID(*), DATATYPE - CHARACTER*(*) NAME, CLASS - BYTE INAME(256), ICLASS(256) - INTEGER NXIGETNEXTENTRY - EXTERNAL NXIGETNEXTENTRY - NXGETNEXTENTRY = NXIGETNEXTENTRY(FILEID, INAME, ICLASS, DATATYPE) - CALL REPLACE_STRING(NAME, INAME) - CALL REPLACE_STRING(CLASS, ICLASS) - END - - INTEGER FUNCTION NXGETNEXTATTR(FILEID, PNAME, ILENGTH, ITYPE) - INTEGER FILEID(*), ILENGTH, ITYPE, NXIGETNEXTATTR - CHARACTER*(*) PNAME - BYTE IPNAME(1024) - EXTERNAL NXIGETNEXTATTR - NXGETNEXTATTR = NXIGETNEXTATTR(FILEID, IPNAME, ILENGTH, ITYPE) - CALL REPLACE_STRING(PNAME, IPNAME) - END - - INTEGER FUNCTION NXGETGROUPID(FILEID, LINK) - INTEGER FILEID(*), LINK(*), NXIGETGROUPID - EXTERNAL NXIGETGROUPID - NXGETGROUPID = NXIGETGROUPID(FILEID, LINK) - END - - INTEGER FUNCTION NXGETDATAID(FILEID, LINK) - INTEGER FILEID(*), LINK(*), NXIGETDATAID - EXTERNAL NXIGETDATAID - NXGETDATAID = NXIGETDATAID(FILEID, LINK) - END - - INTEGER FUNCTION NXMAKELINK(FILEID, LINK) - INTEGER FILEID(*), LINK(*), NXIMAKELINK - EXTERNAL NXIMAKELINK - NXMAKELINK = NXIMAKELINK(FILEID, LINK) - END diff --git a/napif.inc b/napif.inc deleted file mode 100644 index 07e27deb..00000000 --- a/napif.inc +++ /dev/null @@ -1,47 +0,0 @@ -C---------------------------------------------------------------------------- -C NeXus - Neutron & X-ray Common Data Format -C -C API Fortran Interface Definitions -C -C $Id: napif.inc,v 1.1 2000/02/07 10:38:58 cvs Exp $ -C -C Copyright (C) 1997, Freddie Akeroyd -C ISIS Facility, Rutherford Appleton Laboratory -C -C See NAPI.C for details -C -C 97/7/30 - Initial Release -C 97/7/31 - Correct NXPUTATTR/NXGETATTR and make 'implicit none' clean -C 97/8/7 - Update interface -C---------------------------------------------------------------------------- - -C *** NXaccess enum - access modes for NXopen - INTEGER NXACC_READ,NXACC_RDWR,NXACC_CREATE - PARAMETER(NXACC_READ=1,NXACC_RDWR=3,NXACC_CREATE=7) -C *** NXHANDLESIZE should be the size of an INTEGER*4 array that is (at least) -C *** large enough to hold an NXhandle structure - INTEGER NXHANDLESIZE - PARAMETER(NXHANDLESIZE=600) -C *** NXLINKSIZE is (at least) the size of an INTEGER*4 array that can hold -C *** an NXlink structure: we'll assume 64bit alignment of structure members for safety - INTEGER NXLINKSIZE - PARAMETER(NXLINKSIZE=4) -C *** Possible NXstatus values - these are returned by all NX routines - INTEGER NX_OK,NX_ERROR,NX_EOD - PARAMETER(NX_OK=1,NX_ERROR=0,NX_EOD=-1) -C *** HDF datatypes used by Nexus - see hntdefs.h in HDF distribution - INTEGER DFNT_FLOAT32,DFNT_FLOAT64,DFNT_INT8,DFNT_UINT8,DFNT_INT16, - + DFNT_UINT16,DFNT_INT32,DFNT_UINT32 - PARAMETER(DFNT_FLOAT32=5,DFNT_FLOAT64=6,DFNT_INT8=20, - + DFNT_UINT8=21,DFNT_INT16=22,DFNT_UINT16=23, - + DFNT_INT32=24,DFNT_UINT32=25) - INTEGER NXOPEN, NXCLOSE, NXMAKEGROUP, NXOPENGROUP, NXCLOSEGROUP, - + NXMAKEDATA, NXOPENDATA, NXCLOSEDATA, NXGETDATA, NXGETSLAB, - + NXGETATTR, NXGETDIM, NXPUTDATA, NXPUTSLAB, NXPUTATTR, - + NXPUTDIM, NXGETINFO, NXGETNEXTENTRY, NXGETNEXTATTR, - + NXGETGROUPID, NXMAKELINK - EXTERNAL NXOPEN, NXCLOSE, NXMAKEGROUP, NXOPENGROUP, NXCLOSEGROUP, - + NXMAKEDATA, NXOPENDATA, NXCLOSEDATA, NXGETDATA, NXGETSLAB, - + NXGETATTR, NXGETDIM, NXPUTDATA, NXPUTSLAB, NXPUTATTR, - + NXPUTDIM, NXGETINFO, NXGETNEXTENTRY, NXGETNEXTATTR, - + NXGETGROUPID, NXMAKELINK diff --git a/nxdataset.c b/nxdataset.c new file mode 100644 index 00000000..c64c1321 --- /dev/null +++ b/nxdataset.c @@ -0,0 +1,299 @@ +/* + This is a module which implements the notion of a dataset. Its is + designed for the use with scripting languages. + + copyright: GPL + + Mark Koennecke, October 2002 +*/ +#include +#include +#include "nxdataset.h" + +/*-----------------------------------------------------------------------*/ +static int getTypeSize(int typecode){ + switch(typecode){ + case NX_FLOAT32: + case NX_INT32: + case NX_UINT32: + return 4; + break; + case NX_FLOAT64: + return 8; + break; + case NX_INT16: + case NX_UINT16: + return 2; + break; + default: + return 1; + break; + } +} +/*-----------------------------------------------------------------------*/ +pNXDS createNXDataset(int rank, int typecode, int dim[]){ + pNXDS pNew = NULL; + int i, length; + + pNew = (pNXDS)malloc(sizeof(NXDS)); + if(pNew == NULL){ + return NULL; + } + + pNew->dim = (int *)malloc(rank*sizeof(int)); + for(i = 0, length = 1; i < rank; i++){ + length *= dim[i]; + } + pNew->u.ptr = malloc(length*getTypeSize(typecode)); + + if(pNew->dim == NULL || pNew->u.ptr == NULL){ + free(pNew); + return NULL; + } + pNew->rank = rank; + pNew->type = typecode; + pNew->format = NULL; + for(i = 0; i < rank; i++){ + pNew->dim[i] = dim[i]; + } + pNew->magic = MAGIC; + memset(pNew->u.ptr,0,length*getTypeSize(typecode)); + return pNew; +} +/*---------------------------------------------------------------------*/ +pNXDS createTextNXDataset(char *name){ + pNXDS pNew = NULL; + + pNew = (pNXDS)malloc(sizeof(NXDS)); + if(pNew == NULL){ + return NULL; + } + pNew->dim = (int *)malloc(sizeof(int)); + pNew->u.cPtr = strdup(name); + if(pNew->dim == NULL || pNew->u.ptr == NULL){ + free(pNew); + return NULL; + } + pNew->rank = 1; + pNew->type = NX_CHAR; + pNew->magic = MAGIC; + pNew->dim[0] = strlen(name); + return pNew; +} +/*-----------------------------------------------------------------------*/ +void dropNXDataset(pNXDS dataset){ + if(dataset == NULL){ + return; + } + if(dataset->magic != MAGIC){ + return; + } + if(dataset->dim != NULL){ + free(dataset->dim); + } + if(dataset->u.ptr != NULL){ + free(dataset->u.ptr); + } + if(dataset->format != NULL){ + free(dataset->format); + } + free(dataset); +} +/*-----------------------------------------------------------------------*/ +int getNXDatasetRank(pNXDS dataset){ + if(dataset == NULL){ + return 0; + } + if(dataset->magic != MAGIC){ + return 0; + } + return dataset->rank; +} +/*-----------------------------------------------------------------------*/ +int getNXDatasetDim(pNXDS dataset, int which){ + if(dataset == NULL){ + return 0; + } + if(dataset->magic != MAGIC){ + return 0; + } + if(which < 0 || which >= dataset->rank){ + return 0; + } + return dataset->dim[which]; +} +/*------------------------------------------------------------------------*/ +int getNXDatasetType(pNXDS dataset){ + if(dataset == NULL){ + return 0; + } + if(dataset->magic != MAGIC){ + return 0; + } + return dataset->type; +} +/*--------------------------------------------------------------------*/ +int getNXDatasetLength(pNXDS dataset){ + int length, i; + + if(dataset == NULL){ + return 0; + } + if(dataset->magic != MAGIC){ + return 0; + } + length = dataset->dim[0]; + for(i = 1; i < dataset->rank; i++){ + length *= dataset->dim[i]; + } + return length; +} +/*---------------------------------------------------------------------*/ +int getNXDatasetByteLength(pNXDS dataset){ + return getNXDatasetLength(dataset)*getTypeSize(dataset->type); +} +/*---------------------------------------------------------------------- + This calculates an arbitray address in C storage order + -----------------------------------------------------------------------*/ +static int calculateAddress(pNXDS dataset, int pos[]){ + int result, mult; + int i, j; + + result = pos[dataset->rank - 1]; + for(i = 0; i < dataset->rank -1; i++){ + mult = 1; + for(j = dataset->rank -1; j > i; j--){ + mult *= dataset->dim[j]; + } + if(pos[i] < dataset->dim[i] && pos[i] > 0){ + result += mult*pos[i]; + } + } + return result; +} +/*-----------------------------------------------------------------------*/ +double getNXDatasetValue(pNXDS dataset, int pos[]){ + int address; + double value; + + if(dataset == NULL){ + return 0; + } + if(dataset->magic != MAGIC){ + return 0; + } + + address = calculateAddress(dataset,pos); + return getNXDatasetValueAt(dataset, address); +} +/*----------------------------------------------------------------------*/ +double getNXDatasetValueAt(pNXDS dataset, int address){ + double value; + + if(dataset == NULL){ + return 0; + } + if(dataset->magic != MAGIC){ + return 0; + } + + switch(dataset->type){ + case NX_FLOAT64: + value = dataset->u.dPtr[address]; + break; + case NX_FLOAT32: + value = (double)dataset->u.fPtr[address]; + break; + case NX_INT32: + case NX_UINT32: + value = (double)dataset->u.iPtr[address]; + break; + case NX_INT16: + case NX_UINT16: + value = (double)dataset->u.sPtr[address]; + break; + default: + value = (double)dataset->u.cPtr[address]; + break; + } + return value; +} +/*-----------------------------------------------------------------------*/ +char *getNXDatasetText(pNXDS dataset){ + char *resultBuffer = NULL; + int length, status = 1; + + if(dataset == NULL){ + status = 0; + } + if(dataset->magic != MAGIC){ + status = 0; + } + if(dataset->rank > 1){ + status = 0; + } + if(dataset->type == NX_FLOAT32 || + dataset->type == NX_FLOAT64 || + dataset->type == NX_INT32 || + dataset->type == NX_UINT32 || + dataset->type == NX_INT16 || + dataset->type == NX_UINT16 ) { + status = 0; + } + + if(status == 0){ + return strdup("NO type problem"); + }else{ + resultBuffer = (char *)malloc((dataset->dim[0]+10)*sizeof(char)); + if(resultBuffer == NULL){ + return strdup("NO Memory"); + } + memset(resultBuffer,0,(dataset->dim[0]+10)*sizeof(char)); + strncpy(resultBuffer,dataset->u.cPtr,dataset->dim[0]); + } + return resultBuffer; +} +/*----------------------------------------------------------------------*/ +int putNXDatasetValue(pNXDS dataset, int pos[], double value){ + int address; + + if(dataset == NULL){ + return 0; + } + if(dataset->magic != MAGIC){ + return 0; + } + + address = calculateAddress(dataset,pos); + return putNXDatasetValueAt(dataset,address,value); +} + /*---------------------------------------------------------------------*/ +int putNXDatasetValueAt(pNXDS dataset, int address, double value){ + /* + this code is dangerous, it casts without checking the data range. + This may cause trouble in some cases + */ + switch(dataset->type){ + case NX_FLOAT64: + dataset->u.dPtr[address] = value; + break; + case NX_FLOAT32: + dataset->u.fPtr[address] = (float)value; + break; + case NX_INT32: + case NX_UINT32: + dataset->u.iPtr[address] = (int)value; + break; + case NX_INT16: + case NX_UINT16: + dataset->u.sPtr[address] = (short int)value; + break; + default: + dataset->u.cPtr[address] = (char)value; + break; + } + return 1; +} + + + diff --git a/nxdataset.h b/nxdataset.h new file mode 100644 index 00000000..c8613aa1 --- /dev/null +++ b/nxdataset.h @@ -0,0 +1,69 @@ +/* + This is a module which implements the notion of a dataset. Its is + designed for the use with scripting languages. + + copyright: GPL + + Mark Koennecke, October 2002 +*/ +#ifndef NXDATASET +#define NXDATASET + + +#define MAGIC 7776622 + +typedef struct { + int magic; + int rank; + int type; + int *dim; + char *format; + union { + void *ptr; + float *fPtr; + double *dPtr; + int *iPtr; + short int *sPtr; + char *cPtr; + } u; +}*pNXDS, NXDS; + +/* + include NeXus type codes if not already defined +*/ +#ifndef NX_FLOAT32 + +#define NX_FLOAT32 5 +#define NX_FLOAT64 6 +#define NX_INT8 20 +#define NX_UINT8 21 +#define NX_INT16 22 +#define NX_UINT16 23 +#define NX_INT32 24 +#define NX_UINT32 25 +#define NX_CHAR 4 + +#define NX_MAXRANK 32 + +#endif + + +pNXDS createNXDataset(int rank, int typecode, int dim[]); +pNXDS createTextNXDataset(char *name); + +void dropNXDataset(pNXDS dataset); + +int getNXDatasetRank(pNXDS dataset); +int getNXDatasetDim(pNXDS dataset, int which); +int getNXDatasetType(pNXDS dataset); +int getNXDatasetLength(pNXDS dataset); +int getNXDatasetByteLength(pNXDS dataset); + +double getNXDatasetValue(pNXDS dataset, int pos[]); +double getNXDatasetValueAt(pNXDS dataset, int address); +char *getNXDatasetText(pNXDS dataset); + +int putNXDatasetValue(pNXDS dataset, int pos[], double value); +int putNXDatasetValueAt(pNXDS dataset, int address, double value); + +#endif diff --git a/nxdict.c b/nxdict.c index b053cc2e..7453988d 100644 --- a/nxdict.c +++ b/nxdict.c @@ -733,6 +733,67 @@ /* not reached */ return; } +/*-----------------------------------------------------------------------*/ + static void NXDIAttValue(ParDat *sStat) + { + int i; + + + sStat->pToken[0] = '\0'; + + /* skip whitespace */ + while( (*(sStat->pPtr) == ' ') || (*(sStat->pPtr) == '\t') ) + { + sStat->pPtr++; + } + + if(*(sStat->pPtr) == ',') + { + sStat->iToken = DKOMMA; + sStat->pToken[0] = *(sStat->pPtr); + sStat->pPtr++; + return; + } + else if(*(sStat->pPtr) == '\0') + { + sStat->iToken = DEND; + sStat->pToken[0] = *(sStat->pPtr); + sStat->pPtr++; + return; + } + else if(*(sStat->pPtr) == '{') + { + sStat->iToken = DOPEN; + sStat->pToken[0] = *(sStat->pPtr); + sStat->pPtr++; + return; + } + else if(*(sStat->pPtr) == '}') + { + sStat->iToken = DCLOSE; + sStat->pToken[0] = *(sStat->pPtr); + sStat->pPtr++; + return; + } + else + { + sStat->iToken = DWORD; + /* copy word to pToken */ + i = 0; + while( (*(sStat->pPtr) != ' ') && (*(sStat->pPtr) != '\t') && + (*(sStat->pPtr) != '\0') && + (*(sStat->pPtr) != ',') && (*(sStat->pPtr) != '}') ) + { + sStat->pToken[i] = *(sStat->pPtr); + sStat->pPtr++; + i++; + } + sStat->pToken[i] = '\0'; + return; + } + /* not reached */ + return; + } /*------------------------------------------------------------------------*/ @@ -864,7 +925,7 @@ } /* a word is expected */ - NXDIDefToken(pParse); + NXDIAttValue(pParse); if(pParse->iToken != DWORD) { sprintf(pError,"ERROR: expected attribute value, got %s",pParse->pToken); diff --git a/nxio.c b/nxio.c new file mode 100644 index 00000000..4f156422 --- /dev/null +++ b/nxio.c @@ -0,0 +1,550 @@ +/** + * This file contains functions necessary to perform XML-I/O for + * NeXus with the mxml-library. + * + * Most notably it contains the callback function for reading and + * writing data + * + * Copyright (C) 2004 Mark Koennecke + * + * 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 + */ +#include +#include +#include "nxio.h" +#include "nxdataset.h" + +/* #define TESTMAIN 1 */ +/*=================== type code handling ================================= */ +typedef struct { + char name[30]; + char format[30]; + int nx_type; +}type_code; + +static type_code typecode[9]; +/*-----------------------------------------------------------------------*/ +void initializeNumberFormats(){ + type_code myCode; + + strcpy(myCode.name,"NX_FLOAT32"); + strcpy(myCode.format,"%12.4f"); + myCode.nx_type = NX_FLOAT32; + typecode[0] = myCode; + + strcpy(myCode.name,"NX_FLOAT64"); + strcpy(myCode.format,"%16.5f"); + myCode.nx_type = NX_FLOAT64; + typecode[1] = myCode; + + strcpy(myCode.name,"NX_INT8"); + strcpy(myCode.format,"%5d"); + myCode.nx_type = NX_INT8; + typecode[2] = myCode; + + strcpy(myCode.name,"NX_UINT8"); + strcpy(myCode.format,"%5d"); + myCode.nx_type = NX_UINT8; + typecode[3] = myCode; + + strcpy(myCode.name,"NX_INT16"); + strcpy(myCode.format,"%8d"); + myCode.nx_type = NX_INT16; + typecode[4] = myCode; + + strcpy(myCode.name,"NX_UINT16"); + strcpy(myCode.format,"%8d"); + myCode.nx_type = NX_UINT16; + typecode[5] = myCode; + + strcpy(myCode.name,"NX_INT32"); + strcpy(myCode.format,"%12d"); + myCode.nx_type = NX_INT32; + typecode[6] = myCode; + + strcpy(myCode.name,"NX_UNIT32"); + strcpy(myCode.format,"%12d"); + myCode.nx_type = NX_UINT32; + typecode[7] = myCode; + + strcpy(myCode.name,"NX_CHAR"); + strcpy(myCode.format,"%c"); + myCode.nx_type = NX_CHAR; + typecode[8] = myCode; +} +/*----------------------------------------------------------------------*/ +void setNumberFormat(int nx_type, char *format){ + int i; + + for(i = 0; i < 9; i++){ + if(typecode[i].nx_type == nx_type){ + strncpy(typecode[i].format,format,29); + } + } +} +/*------------------------------------------------------------------*/ +static void getNumberFormat(int nx_type, char format[30]){ + int i; + + for(i = 0; i < 9; i++){ + if(typecode[i].nx_type == nx_type){ + strncpy(format,typecode[i].format,29); + } + } +} +/*----------------------------------------------------------------*/ +void getNumberText(int nx_type, char *typestring, int typeLen){ + int i; + + for(i = 0; i < 9; i++){ + if(typecode[i].nx_type == nx_type){ + strncpy(typestring,typecode[i].name,typeLen); + } + } +} +/* + * 'mxml_add_char()' - Add a character to a buffer, expanding as needed. + * copied here from mxml-file.c to achieve compatibility with mxml-2.1 + * standard + */ + +static int /* O - 0 on success, -1 on error */ +myxml_add_char(int ch, /* I - Character to add */ + char **bufptr, /* IO - Current position in buffer */ + char **buffer, /* IO - Current buffer */ + int *bufsize) /* IO - Current buffer size */ +{ + char *newbuffer; /* New buffer value */ + + + if (*bufptr >= (*buffer + *bufsize - 4)) + { + /* + * Increase the size of the buffer... + */ + + if (*bufsize < 1024) + (*bufsize) *= 2; + else + (*bufsize) += 1024; + + newbuffer = (char *)malloc(*bufsize*sizeof(char)); + if(!newbuffer){ + free(*buffer); + + mxml_error("Unable to expand string buffer to %d bytes!", *bufsize); + + return (-1); + } + memset(newbuffer,0,*bufsize*sizeof(char)); + memcpy(newbuffer,*buffer,*bufptr - *buffer); + free(*buffer); + + *bufptr = newbuffer + (*bufptr - *buffer); + *buffer = newbuffer; + } + + if (ch < 128) + { + /* + * Single byte ASCII... + */ + + *(*bufptr)++ = ch; + } + else if (ch < 2048) + { + /* + * Two-byte UTF-8... + */ + + *(*bufptr)++ = 0xc0 | (ch >> 6); + *(*bufptr)++ = 0x80 | (ch & 0x3f); + } + else if (ch < 65536) + { + /* + * Three-byte UTF-8... + */ + + *(*bufptr)++ = 0xe0 | (ch >> 12); + *(*bufptr)++ = 0x80 | ((ch >> 6) & 0x3f); + *(*bufptr)++ = 0x80 | (ch & 0x3f); + } + else + { + /* + * Four-byte UTF-8... + */ + + *(*bufptr)++ = 0xf0 | (ch >> 18); + *(*bufptr)++ = 0x80 | ((ch >> 12) & 0x3f); + *(*bufptr)++ = 0x80 | ((ch >> 6) & 0x3f); + *(*bufptr)++ = 0x80 | (ch & 0x3f); + } + + return (0); +} +/*------------------------------------------------------------------*/ +extern char *stptok(char *s, char *tok, size_t toklen, char *brk); +/*===================================================================== + actual stuff for implementing the callback functions + =====================================================================*/ +static void analyzeDim(const char *typeString, int *rank, + int *iDim, int *type){ + char dimString[132]; + char dim[20]; + char *dimStart, *dimEnd; + int myRank; + + if(strchr(typeString,(int)'[') == NULL){ + switch(*type){ + case NX_INT8: + case NX_UINT8: + case NX_INT16: + case NX_UINT16: + case NX_INT32: + case NX_UINT32: + case NX_FLOAT32: + case NX_FLOAT64: + iDim[0] = 1; + break; + case NX_CHAR: + iDim[0] = -1; + break; + } + } else { + /* + we have to determine rank and the dims. + Start by extracting the dimension string. + */ + dimStart = strchr(typeString,(int)'[') + 1; + dimEnd = strchr(typeString,(int)']'); + if(!dimStart || !dimEnd) { + mxml_error("ERROR: malformed dimension string in %s",typeString); + return; + } + if((dimEnd - dimStart) > 131){ + mxml_error("ERROR: run away dimension definition in %s",typeString); + return; + } + memset(dimString,0,132); + memcpy(dimString,dimStart,(dimEnd-dimStart)*sizeof(char)); + dimStart = stptok(dimString,dim,19,","); + myRank = 0; + while(dimStart != NULL){ + iDim[myRank] = atoi(dim); + dimStart = stptok(dimStart,dim,19,","); + myRank++; + } + *rank = myRank; + } +} +/*--------------------------------------------------------------------*/ +int translateTypeCode(char *code){ + int i, result = -1; + + for(i = 0; i < 9; i++){ + if(strstr(code,typecode[i].name) != NULL){ + result = typecode[i].nx_type; + break; + } + } + return result; +} +/*---------------------------------------------------------------------*/ +static void analyzeDataType(mxml_node_t *parent, int *rank, int *type, + int *iDim){ + const char *typeString; + mxml_type_t myType; + int i, nx_type = -1; + + *rank = 1; + *type = NX_CHAR; + iDim[0] = -1; + + /* + get the type attribute. No attribute means: plain text + */ + typeString = mxmlElementGetAttr(parent,TYPENAME); + if(typeString == NULL){ + return; + } + + nx_type = translateTypeCode((char *)typeString); + + /* + assign type + */ + if(nx_type == -1){ + mxml_error( + "ERROR: %s is an invalid NeXus type, I try to continue but may fail", + typeString); + *type =NX_CHAR; + return; + } + + *type = nx_type; + + analyzeDim(typeString, rank, iDim, type); +} +/*-------------------------------------------------------------------*/ +void destroyDataset(void *data){ + if(data != NULL){ + dropNXDataset((pNXDS)data); + } +} +/*-------------------------------------------------------------------*/ +static char *getNextNumber(char *pStart, char pNumber[80]){ + int charCount = 0; + pNumber[0] = '\0'; + + /* advance to first digit */ + while(isspace(*pStart) && *pStart != '\0'){ + pStart++; + } + if(*pStart == '\0'){ + return NULL; + } + + /* copy */ + while(!isspace(*pStart) && *pStart != '\0' && charCount < 78){ + pNumber[charCount] = *pStart; + pStart++; + charCount++; + } + pNumber[charCount] = '\0'; + return pStart; +} +/*--------------------------------------------------------------------*/ +mxml_type_t nexusTypeCallback(mxml_node_t *parent){ + const char *typeString; + + if(strstr(parent->value.element.name,"?xml") != NULL || + strstr(parent->value.element.name,"NX") != NULL){ + return MXML_ELEMENT; + } else { + typeString = mxmlElementGetAttr(parent,TYPENAME); + if(typeString == NULL){ + /* + MXML_TEXT seems more appropriate here. But mxml hacks text into + single words which is not what NeXus want. + */ + return MXML_OPAQUE; + } else{ + return MXML_CUSTOM; + } + } +} +/*----------------------------------------------------------------------*/ +int nexusLoadCallback(mxml_node_t *node, const char *buffer){ + mxml_node_t *parent = NULL; + int rank, type, iDim[NX_MAXRANK]; + char pNumber[80], *pStart; + long address, maxAddress; + pNXDS dataset = NULL; + int i; + + parent = node->parent; + analyzeDataType(parent,&rank,&type,iDim); + if(iDim[0] == -1){ + iDim[0] = strlen(buffer); + node->value.custom.data = strdup(buffer); + node->value.custom.destroy = free; + return 0; + } else { + node->value.custom.data = createNXDataset(rank,type,iDim); + dataset = (pNXDS)node->value.custom.data; + if(dataset == NULL){ + mxml_error("Failed to allocate custom dataset"); + return 1; + } + node->value.custom.destroy = destroyDataset; + } + + /* + load data + */ + pStart = (char *)buffer; + maxAddress = getNXDatasetLength(dataset); + address = 0; + while( (pStart = getNextNumber(pStart,pNumber)) != NULL && + address < maxAddress){ + putNXDatasetValueAt(dataset,address,atof(pNumber)); + address++; + } + + return 0; +} +/*---------------------------------------------------------------------*/ +static void stringIntoBuffer(char **buffer, char **bufPtr, int *bufSize, + char *string){ + int i; + + for(i = 0; i < strlen(string); i++){ + myxml_add_char(string[i],bufPtr,buffer,bufSize); + } +} +/*--------------------------------------------------------------------*/ +static void formatNumber(double value, char *txt, int txtLen, + char *format, int type){ + switch(type){ + case NX_INT8: + case NX_UINT8: + case NX_INT16: + case NX_UINT16: + case NX_INT32: + case NX_UINT32: + snprintf(txt,txtLen,format,(int)value); + break; + case NX_FLOAT32: + case NX_FLOAT64: + snprintf(txt,txtLen,format,value); + break; + default: + assert(0); /* something is very wrong here */ + break; + } +} +/*--------------------------------------------------------------------*/ +static int countDepth(mxml_node_t *node){ + int count = 0; + mxml_node_t *cur; + + cur = node; + while(cur != NULL){ + count++; + cur = cur->parent; + } + count--; + return count; +} +/*---------------------------------------------------------------------*/ +char *nexusWriteCallback(mxml_node_t *node){ + int type, col; + char pNumber[80], indent[80], format[30]; + char *buffer, *bufPtr; + pNXDS dataset; + int bufsize, i, length, currentLen; + + /* + allocate output buffer + */ + buffer = (char *)malloc(1024*sizeof(char)); + if(buffer == NULL){ + mxml_error("Unable to allocate buffer"); + return NULL; + } + memset(buffer,0,1024); + bufPtr = buffer; + bufsize = 1024; + + dataset = (pNXDS)node->value.custom.data; + + /* + prepare indentation level + */ + col = countDepth(node)*2; + memset(indent,0,80); + for(i = 0; i < col; i++){ + indent[i] = ' '; + } + + /* + get dataset info + */ + type = getNXDatasetType(dataset); + length = getNXDatasetLength(dataset); + if(dataset->format != NULL){ + strcpy(format,dataset->format); + } else { + getNumberFormat(type,format); + } + + /* + actually get the data out + */ + currentLen = col; + myxml_add_char('\n',&bufPtr,&buffer,&bufsize); + stringIntoBuffer(&buffer,&bufPtr,&bufsize,indent); + for(i = 0; i < length; i++){ + formatNumber(getNXDatasetValueAt(dataset,i),pNumber,79,format,type); + if(currentLen + strlen(pNumber) > MXML_WRAP){ + /* + wrap line + */ + myxml_add_char('\n',&bufPtr,&buffer,&bufsize); + stringIntoBuffer(&buffer,&bufPtr,&bufsize,indent); + currentLen = col; + } + stringIntoBuffer(&buffer,&bufPtr,&bufsize,pNumber); + myxml_add_char(' ',&bufPtr,&buffer,&bufsize); + currentLen += strlen(pNumber) + 1; + } + myxml_add_char('\0',&bufPtr,&buffer,&bufsize); + return (char *)buffer; +} +/*---------------------------------------------------------------------*/ +const char *NXwhitespaceCallback(mxml_node_t *node, int where){ + char *indent; + int len; + + if(strstr(node->value.element.name,"?xml") != NULL){ + return NULL; + } + + if(where == MXML_WS_BEFORE_OPEN || where == MXML_WS_BEFORE_CLOSE){ + len = countDepth(node)*2 + 2; + indent = (char *)malloc(len*sizeof(char)); + if(indent != NULL){ + memset(indent,' ',len); + indent[0]= '\n'; + indent[len-1] = '\0'; + return (const char*)indent; + } + } + return NULL; +} +/*-----------------------------------------------------------------------*/ +#ifdef TESTMAIN +#include + +int main(int argc, char *argv[]){ + mxml_node_t *root = NULL; + FILE *f; + + mxmlSetCustomHandlers(nexusLoadCallback, nexusWriteCallback); + initializeNumberFormats(); + + /* + read test + */ + f = fopen("dmc.xml","r"); + root = mxmlLoadFile(NULL,f,nexusTypeCallback); + fclose(f); + + /* + write test + */ + setNumberFormat(NX_INT32,"%8d"); + setNumberFormat(NX_FLOAT32,"%8.2f"); + f = fopen("dmc2.xml","w"); + mxmlSaveFile(root,f,NXwhitespaceCallback); + fclose(f); + +} +#endif diff --git a/nxio.h b/nxio.h new file mode 100644 index 00000000..f0f5bc64 --- /dev/null +++ b/nxio.h @@ -0,0 +1,45 @@ +/** + * This file contains functions necessary to perform XML-I/O for + * NeXus with the mxml-library. + * + * Most notably it contains the callback function for reading data + * + * Copyright (C) 2004 Mark Koennecke + * + * 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 + */ + +#ifndef __NXIO +#define __NXIO +#include + +#define TYPENAME "NAPItype" + +mxml_type_t nexusTypeCallback(mxml_node_t *parent); +const char *NXwhitespaceCallback(mxml_node_t *node, int where); +int nexusLoadCallback(mxml_node_t *node, const char *buffer); +char *nexusWriteCallback(mxml_node_t *node); + +void setNumberFormat(int dataType, char *formatString); +void initializeNumberFormats(); +void getNumberText(int nx_type, char *typestring, int typeLen); +void destroyDataset(void *data); +int translateTypeCode(char *code); + + + +#endif diff --git a/nxscript.c b/nxscript.c index d555d90a..04d9c0e0 100644 --- a/nxscript.c +++ b/nxscript.c @@ -159,6 +159,8 @@ static int handleFileOperations(SConnection *pCon, pNXScript self, } else if(strcmp(argv[1],"create5") == 0){ access = NXACC_CREATE5; unlink(argv[2]); /* kill file for overwrite */ + } else if(strcmp(argv[1],"createxml") == 0){ + access = NXACC_CREATEXML; } else { return 0; } @@ -727,6 +729,91 @@ static void putArray(SConnection *pCon, SicsInterp *pSics, SCSendOK(pCon); } /*----------------------------------------------------------------------*/ +static void putIntArray(SConnection *pCon, SicsInterp *pSics, + pNXScript self, + int argc, char *argv[]){ + int *data = NULL; + int length, i, status; + char num[20]; + char buffer[256], defString[512], *varData; + Tcl_Interp *tcl = NULL; + int iVal; + + if(argc < 5){ + SCWrite(pCon,"ERROR: insufficient number of arguments to array", + eError); + return; + } + tcl = InterpGetTcl(pSics); + assert(tcl != NULL); + + /* + get array length + */ + status = Tcl_GetInt(tcl,argv[4],&length); + if(status != TCL_OK){ + sprintf(buffer,"ERROR: failed to convert %s to integer",argv[4]); + SCWrite(pCon,buffer,eError); + return; + } + + /* + allocate + */ + if(length > 0){ + data = (int *)malloc(length*sizeof(int)); + } + if(data == NULL){ + SCWrite(pCon,"ERROR: out of memory or invalid length",eError); + return; + } + memset(data,0,length*sizeof(int)); + + /* + try getting data + */ + for(i = 0; i < length; i++){ + sprintf(num,"%d",i); + varData = (char *)Tcl_GetVar2(tcl,argv[3],num,0); + if(varData != NULL){ + status = Tcl_GetInt(tcl,varData,&iVal); + if(status != TCL_OK){ + sprintf(buffer,"ERROR: failed to convert %s to int", + varData); + SCWrite(pCon,buffer,eError); + } + data[i] = iVal; + } else { + snprintf(buffer,254,"WARNING: failed to find array element %d", i); + SCWrite(pCon,buffer,eError); + } + } + + /* + build definition string + */ + status = NXDdefget(self->dictHandle,argv[2],buffer,254); + if(!status){ + sprintf(buffer,"ERROR: alias %s for array not found", + argv[2]); + SCWrite(pCon,buffer,eError); + free(data); + return; + } + snprintf(defString,511,"%s -dim {%d} ",buffer,length); + + /* + write it! + */ + status = NXDputdef(self->fileHandle,self->dictHandle,defString,data); + if(status != NX_OK){ + sprintf(buffer,"ERROR: failed to write array"); + SCWrite(pCon,buffer,eError); + } + free(data); + SCSendOK(pCon); +} +/*----------------------------------------------------------------------*/ static void putGlobal(SConnection *pCon, SicsInterp *pSics, pNXScript self, int argc, char *argv[]){ @@ -851,6 +938,9 @@ static int handlePut(SConnection *pCon, SicsInterp *pSics, pNXScript self, }else if(strcmp(argv[1],"putarray") == 0){ /*================*/ putArray(pCon,pSics,self,argc,argv); + }else if(strcmp(argv[1],"putintarray") == 0){ + /*================*/ + putIntArray(pCon,pSics,self,argc,argv); }else if(strcmp(argv[1],"putglobal") == 0){ /*===============*/ putGlobal(pCon,pSics,self,argc,argv); diff --git a/scan.c b/scan.c index be6c1561..4dec8030 100644 --- a/scan.c +++ b/scan.c @@ -94,6 +94,7 @@ static void ConfigureScanDict(pStringDict dict) StringDictAddPair(dict,"collect","stdscan collect"); StringDictAddPair(dict,"writepoint","stdscan writepoint"); StringDictAddPair(dict,"userdata","unknown"); + StringDictAddPair(dict,"finish","stdscan finish"); } /*--------------------------------------------------------------------------*/ pScanData CreateScanObject(char *pRecover, char *pHeader,pCounter pCount, @@ -670,6 +671,7 @@ CountEntry CollectCounterData(pScanData self) self->iActive = 1; iRet = ScanLoop(self); + ScriptScanFinish(self); InvokeCallBack(self->pCall,SCANEND,self); SendQuieck(QUIECK,self->pFile); self->iActive = 0; @@ -834,6 +836,7 @@ CountEntry CollectCounterData(pScanData self) self->iActive = 1; iRet = ScanLoop(self); + ScriptScanFinish(self); InvokeCallBack(self->pCall,SCANEND,self); SendQuieck(QUIECK,self->pFile); self->iActive = 0; diff --git a/scan.tex b/scan.tex index 20677a38..1d99cb0e 100644 --- a/scan.tex +++ b/scan.tex @@ -516,6 +516,10 @@ $\langle$stdscan {\footnotesize ?}$\rangle\equiv$ \mbox{}\verb@ */@\\ \mbox{}\verb@ int ScriptScanCollect(pScanData self, int iPoint); @\\ \mbox{}\verb@ /**@\\ +\mbox{}\verb@ * ScriptScanFinish invokes a script after the scan has finished@\\ +\mbox{}\verb@ */@\\ +\mbox{}\verb@ int ScriptScanFinish(pScanData self); @\\ +\mbox{}\verb@ /**@\\ \mbox{}\verb@ * ConfigureScript assigns the script invocation functions for@\\ \mbox{}\verb@ * scan@\\ \mbox{}\verb@ */@\\ diff --git a/scan.w b/scan.w index 083c22e7..53135d5f 100644 --- a/scan.w +++ b/scan.w @@ -461,6 +461,10 @@ documentation. * Script collecting scan data for each scan point */ int ScriptScanCollect(pScanData self, int iPoint); + /** + * ScriptScanFinish invokes a script after the scan has finished + */ + int ScriptScanFinish(pScanData self); /** * ConfigureScript assigns the script invocation functions for * scan diff --git a/stdscan.c b/stdscan.c index ed0824ce..71601976 100644 --- a/stdscan.c +++ b/stdscan.c @@ -860,6 +860,10 @@ int ScriptScanCollect(pScanData self, int iPoint){ int ScriptWriteScanPoints(pScanData self, int iPoint){ return StandardScriptInvokeWithPoint(self,"writepoint",iPoint); } +/*--------------------------------------------------------------------*/ +int ScriptScanFinish(pScanData self){ + return StandardScriptInvoke(self,"finish"); +} /*---------------------------------------------------------------------*/ void ConfigureScript(pScanData self){ assert(self); @@ -890,7 +894,9 @@ int StandardScanWrapper(SConnection *pCon, SicsInterp *pSics, void *pData, return WriteHeader(self); } else if(strcmp(argv[1],"prepare") == 0){ return PrepareScan(self); - } + } else if(strcmp(argv[1],"finish") == 0) { + return 1; + } /* from here on we need a scan point diff --git a/stdscan.h b/stdscan.h index 2a95fa6d..bb7404da 100644 --- a/stdscan.h +++ b/stdscan.h @@ -11,10 +11,6 @@ #ifndef SICSSTDSCAN #define SICSSTDSCAN - /** - * make a scan file name - */ - char *ScanMakeFileName(SicsInterp *pSics, SConnection *pCon); /** * write the header of the scan file */ @@ -33,10 +29,6 @@ /** * second version of PrepareScan which does not check scan limits */ - int SilentPrepare(pScanData self); - /** - * third version of PrepareScan which does not create data files but checks - */ int NonCheckPrepare(pScanData self); /** * ScanDrive handles driving to the scan point iPoint. @@ -84,6 +76,10 @@ * Script collecting scan data for each scan point */ int ScriptScanCollect(pScanData self, int iPoint); + /** + * ScriptScanFinish invokes a script after the scan has finished + */ + int ScriptScanFinish(pScanData self); /** * ConfigureScript assigns the script invocation functions for * scan diff --git a/tasdrive.c b/tasdrive.c index fc702a44..b0b1e7a9 100644 --- a/tasdrive.c +++ b/tasdrive.c @@ -633,7 +633,8 @@ int TasMot(SConnection *pCon,SicsInterp *pSics, void *pData, SCWrite(pCon,pBueffel,eValue); return 1; } else { - SCWrite(pCon,"ERROR: tasmot does not understand this subcommand",eError); + snprintf(pBueffel,131,"ERROR: tasmot does not understand %s", argv[1]); + SCWrite(pCon,pBueffel,eError); return 0; } } diff --git a/tasscanub.c b/tasscanub.c index d704f23e..73263930 100644 --- a/tasscanub.c +++ b/tasscanub.c @@ -23,6 +23,7 @@ #include #include #include "tasscanub.h" +#include "nxscript.h" /*------------------------------------------------------------------------ a little local utility for making a line of characters -------------------------------------------------------------------------*/ @@ -968,6 +969,100 @@ int TASUBPrepare(pScanData self) return status; } +/*---------------------------------------------------------------------*/ +static void TASUBDump(pTASdata self, SicsInterp *pSics, SConnection *pCon, + int argc, char *argv[]){ + float v[3], ub[3][3], cell[6]; + int status, i, j; + pNXScript nxscript = NULL; + char pBueffel[256]; + tasReflection r; + + if(argc < 4){ + SCWrite(pCon,"ERROR: not enough argument to dump tasub",eError); + return; + } + + nxscript = (pNXScript)FindCommandData(pSics,argv[2],"NXScript"); + if(nxscript == NULL){ + snprintf(pBueffel,255,"ERROR: %s is no NXScript object", + argv[2]); + SCWrite(pCon,pBueffel,eError); + return; + } + if(nxscript->fileHandle == NULL){ + SCWrite(pCon,"ERROR: files is closed, cannot write",eError); + return; + } + + /* + write cell + */ + snprintf(pBueffel,255,"%s_cell",argv[3]); + cell[0] = self->ub->cell.a; + cell[1] = self->ub->cell.b; + cell[2] = self->ub->cell.c; + cell[3] = self->ub->cell.alpha; + cell[4] = self->ub->cell.beta; + cell[5] = self->ub->cell.gamma; + status = NXDputalias(nxscript->fileHandle,nxscript->dictHandle,pBueffel,cell); + if(status != NX_OK){ + snprintf(pBueffel,255,"ERROR: failed to write cell to %s_cell",argv[3]); + SCWrite(pCon,pBueffel,eWarning); + } + + /* + write planenormal + */ + for(i = 0; i < 3; i++){ + v[i] = self->ub->machine.planeNormal[i][0]; + } + snprintf(pBueffel,255,"%s_norm",argv[3]); + status = NXDputalias(nxscript->fileHandle,nxscript->dictHandle,pBueffel,v); + if(status != NX_OK){ + snprintf(pBueffel,255,"ERROR: failed to write plane_normal to %s_norm",argv[3]); + SCWrite(pCon,pBueffel,eWarning); + } + + /* + write orienting reflections + */ + snprintf(pBueffel,255,"%s_vec1",argv[3]); + findReflection(self->ub->reflectionList, self->ub->r1,&r); + v[0] = r.qe.qh; + v[1] = r.qe.qk; + v[2] = r.qe.ql; + status = NXDputalias(nxscript->fileHandle,nxscript->dictHandle,pBueffel,v); + if(status != NX_OK){ + snprintf(pBueffel,255,"ERROR: failed to write plane vector 1 to %s_vec1",argv[3]); + SCWrite(pCon,pBueffel,eWarning); + } + snprintf(pBueffel,255,"%s_vec2",argv[3]); + findReflection(self->ub->reflectionList, self->ub->r2,&r); + v[0] = r.qe.qh; + v[1] = r.qe.qk; + v[2] = r.qe.ql; + status = NXDputalias(nxscript->fileHandle,nxscript->dictHandle,pBueffel,v); + if(status != NX_OK){ + snprintf(pBueffel,255,"ERROR: failed to write plane vector 2 to %s_vec2",argv[3]); + SCWrite(pCon,pBueffel,eWarning); + } + + /* + write UB + */ + for(i = 0; i < 3; i++){ + for(j = 0; j < 3; j++){ + ub[i][j] = self->ub->machine.UB[i][j]; + } + } + snprintf(pBueffel,255,"%s_ub",argv[3]); + status = NXDputalias(nxscript->fileHandle,nxscript->dictHandle,pBueffel,ub); + if(status != NX_OK){ + snprintf(pBueffel,255,"ERROR: failed to write UB to %s_ub",argv[3]); + SCWrite(pCon,pBueffel,eWarning); + } +} /*----------------------------------------------------------------------*/ int TASUBScan(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]){ @@ -1014,6 +1109,9 @@ int TASUBScan(SConnection *pCon, SicsInterp *pSics, void *pData, } } else if(strcmp(argv[1],"prepare") == 0){ return TASUBPrepare(self->pScan); + } else if(strcmp(argv[1],"nxdump") == 0){ + TASUBDump(self,pSics,pCon,argc,argv); + return 1; } else if(strcmp(argv[1],"drive") == 0){ if(argc < 5) { SCWrite(pCon,"ERROR: insufficient number of arguments to tasscan drive",