diff --git a/make_gen b/make_gen index dd40bf20..66180e68 100644 --- a/make_gen +++ b/make_gen @@ -34,7 +34,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ moregress.o hdbcommand.o multicounter.o regresscter.o histregress.o \ sicshdbadapter.o polldriv.o sicspoll.o statemon.o hmslave.o \ nwatch.o asyncqueue.o asyncprotocol.o sicsobj.o hdbqueue.o\ - nxcopy.o nxinterhelper.o nxinter_wrap.o genericcontroller.o + nxcopy.o nxinterhelper.o nxinter_wrap.o genericcontroller.o nxstack.o MOTOROBJ = motor.o simdriv.o COUNTEROBJ = countdriv.o simcter.o counter.o diff --git a/makefile_slinux b/makefile_slinux index a9c11577..06a7df27 100644 --- a/makefile_slinux +++ b/makefile_slinux @@ -9,7 +9,7 @@ SINQDIR=/afs/psi.ch/project/sinq NI= -DHAVENI NIOBJ= nigpib.o -NILIB=$(SINQDIR)/sl-linux/lib/cib.o +NILIB=$(SINQDIR)/sl5/lib/cib.o include sllinux_def diff --git a/napi.c b/napi.c index 75fed79f..a821750b 100644 --- a/napi.c +++ b/napi.c @@ -3,7 +3,7 @@ Application Program Interface Routines - Copyright (C) 1997-2000 Mark Koennecke, Przemek Klosowski + Copyright (C) 1997-2006 Mark Koennecke, Przemek Klosowski This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -23,7 +23,7 @@ ----------------------------------------------------------------------------*/ -static const char* rscid = "$Id: napi.c,v 1.13 2006/03/03 15:30:55 koennecke Exp $"; /* Revision interted by CVS */ +static const char* rscid = "$Id: napi.c,v 1.14 2008/01/03 09:56:56 koennecke Exp $"; /* Revision inserted by CVS */ #include #include @@ -33,8 +33,81 @@ static const char* rscid = "$Id: napi.c,v 1.13 2006/03/03 15:30:55 koennecke Exp #include #include #include "napi.h" +#include "nxstack.h" +/*--------------------------------------------------------------------- + Recognized and handled napimount URLS + -----------------------------------------------------------------------*/ +#define NXBADURL 0 +#define NXFILE 1 + +/*--------------------------------------------------------------------*/ static int iFortifyScope; +/*---------------------------------------------------------------------- + This is a section with code for searching the NX_LOAD_PATH + -----------------------------------------------------------------------*/ +#ifdef _WIN32 +#define LIBSEP ";" +#define PATHSEP "\\" +#else +#define LIBSEP ":" +#define PATHSEP "/" +#endif +extern char *stptok(char *s, char *tok, size_t toklen, char *brk); +/*--------------------------------------------------------------------- + wrapper for getenv. This is a future proofing thing for porting to OS + which have different ways of accessing environment variables + --------------------------------------------------------------------*/ +static char *nxgetenv(const char *name){ + return getenv(name); +} +/*----------------------------------------------------------------------*/ +static int canOpen(char *filename){ + FILE *fd = NULL; + + fd = fopen(filename,"r"); + if(fd != NULL){ + fclose(fd); + return 1; + } else { + return 0; + } +} +/*--------------------------------------------------------------------*/ +static char *locateNexusFileInPath(char *startName){ + char *loadPath = NULL, *testPath = NULL, *pPtr = NULL; + char pathPrefix[256]; + int length; + + if(canOpen(startName)){ + return strdup(startName); + } + + loadPath = nxgetenv("NX_LOAD_PATH"); + if(loadPath == NULL){ + /* file not found will be issued by upper level code */ + return strdup(startName); + } + + pPtr = stptok(loadPath,pathPrefix,255,LIBSEP); + while(pPtr != NULL){ + length = strlen(pathPrefix) + strlen(startName) + strlen(PATHSEP) + 2; + testPath = malloc(length*sizeof(char)); + if(testPath == NULL){ + return strdup(startName); + } + memset(testPath,0,length*sizeof(char)); + strcpy(testPath, pathPrefix); + strcat(testPath,PATHSEP); + strcat(testPath,startName); + if(canOpen(testPath)){ + return(testPath); + } + free(testPath); + pPtr = stptok(pPtr,pathPrefix,255,LIBSEP); + } + return strdup(startName); +} /*------------------------------------------------------------------------ HDF-5 cache size special stuff -------------------------------------------------------------------------*/ @@ -49,7 +122,6 @@ NXstatus NXsetcache(long newVal) } return NX_ERROR; } - /*-----------------------------------------------------------------------*/ static NXstatus NXisXML(CONSTCHAR *filename) @@ -69,22 +141,14 @@ static NXstatus NXisXML(CONSTCHAR *filename) } /*-------------------------------------------------------------------------*/ - - - /*---------------------------------------------------------------------*/ - - void NXNXNXReportError(void *pData, char *string) + static void NXNXNXReportError(void *pData, char *string) { printf("%s \n",string); } - /*---------------------------------------------------------------------*/ - void *NXpData = NULL; void (*NXIReportError)(void *pData, char *string) = NXNXNXReportError; - /*---------------------------------------------------------------------*/ - extern void NXMSetError(void *pData, void (*NewError)(void *pD, char *text)) { @@ -95,7 +159,27 @@ static NXstatus NXisXML(CONSTCHAR *filename) extern ErrFunc NXMGetError(){ return NXIReportError; } - + +/*----------------------------------------------------------------------*/ +void NXNXNoReport(void *pData, char *string){ + /* do nothing */ +} +/*----------------------------------------------------------------------*/ + +static ErrFunc last_errfunc = NXNXNXReportError; + +extern void NXMDisableErrorReporting() +{ + last_errfunc = NXMGetError(); + NXMSetError(NXpData, NXNXNoReport); +} + +extern void NXMEnableErrorReporting() +{ + NXMSetError(NXpData, last_errfunc); +} + +/*----------------------------------------------------------------------*/ #ifdef HDF5 #include "napi5.h" #endif @@ -105,7 +189,6 @@ extern ErrFunc NXMGetError(){ #ifdef NXXML #include "nxxml.h" #endif - /* ---------------------------------------------------------------------- Definition of NeXus API @@ -148,17 +231,49 @@ static int determineFileType(CONSTCHAR *filename) */ return 0; } +/*---------------------------------------------------------------------*/ +static pNexusFunction handleToNexusFunc(NXhandle fid){ + pFileStack fileStack = NULL; + fileStack = (pFileStack)fid; + if(fileStack != NULL){ + return peekFileOnStack(fileStack); + } else { + return NULL; + } +} +/*--------------------------------------------------------------------*/ +static NXstatus NXinternalopen(CONSTCHAR *userfilename, NXaccess am, + pFileStack fileStack); +/*----------------------------------------------------------------------*/ +NXstatus NXopen(CONSTCHAR *userfilename, NXaccess am, NXhandle *gHandle){ + int status; + pFileStack fileStack = NULL; + NXhandle hfile; + + fileStack = makeFileStack(); + if(fileStack == NULL){ + NXIReportError (NXpData,"ERROR: no memory to create filestack"); + return NX_ERROR; + } + status = NXinternalopen(userfilename,am,fileStack); + if(status == NX_OK){ + *gHandle = fileStack; + } + + return status; +} /*-----------------------------------------------------------------------*/ - NXstatus NXopen(CONSTCHAR *filename, NXaccess am, NXhandle *gHandle) +static NXstatus NXinternalopen(CONSTCHAR *userfilename, NXaccess am, pFileStack fileStack) { int hdf_type=0; int iRet=0; - NXhandle hdf5_handle; - NXhandle hdf4_handle; - NXhandle xmlHandle; - pNexusFunction fHandle; - NXstatus retstat; + NXhandle hdf5_handle = NULL; + NXhandle hdf4_handle = NULL; + NXhandle xmlHandle = NULL; + pNexusFunction fHandle = NULL; + NXstatus retstat = NX_ERROR; char error[1024]; + char *filename = NULL; /* configure fortify iFortifyScope = Fortify_EnterScope(); @@ -168,13 +283,12 @@ static int determineFileType(CONSTCHAR *filename) /* allocate data */ - *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 */ + memset(fHandle, 0, sizeof(NexusFunction)); /* so any functions we miss are NULL */ /* test the strip flag. Elimnate it for the rest of the tests to work @@ -188,49 +302,68 @@ static int determineFileType(CONSTCHAR *filename) if (am==NXACC_CREATE) { /* HDF4 will be used ! */ hdf_type=1; + filename = strdup(userfilename); } else if (am==NXACC_CREATE4) { /* HDF4 will be used ! */ hdf_type=1; + filename = strdup(userfilename); } else if (am==NXACC_CREATE5) { /* HDF5 will be used ! */ hdf_type=2; + filename = strdup(userfilename); } else if (am==NXACC_CREATEXML) { /* XML will be used ! */ hdf_type=3; + filename = strdup(userfilename); } else { + filename = locateNexusFileInPath((char *)userfilename); + if(filename == NULL){ + NXIReportError(NXpData,"Out of memory in NeXus-API"); + free(fHandle); + return NX_ERROR; + } /* 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); + free(filename); return NX_ERROR; } if(iRet == 0){ - snprintf(error,1023,"failed to detrmine filetype for %s ", + snprintf(error,1023,"failed to determine filetype for %s ", filename); NXIReportError(NXpData,error); + free(filename); + free(fHandle); return NX_ERROR; } hdf_type = iRet; } + if(filename == NULL){ + NXIReportError(NXpData,"Out of memory in NeXus-API"); + return NX_ERROR; + } + if (hdf_type==1) { /* HDF4 type */ #ifdef HDF4 retstat = NX4open((const char *)filename,am,&hdf4_handle); if(retstat != NX_OK){ free(fHandle); + free(filename); return retstat; } fHandle->pNexusData=hdf4_handle; NX4assignFunctions(fHandle); - *gHandle = fHandle; + pushFileStack(fileStack,fHandle,filename); #else NXIReportError (NXpData, "ERROR: Attempt to create HDF4 file when not linked with HDF4"); - *gHandle = NULL; retstat = NX_ERROR; #endif /* HDF4 */ + free(filename); return retstat; } else if (hdf_type==2) { /* HDF5 type */ @@ -238,17 +371,18 @@ static int determineFileType(CONSTCHAR *filename) retstat = NX5open(filename,am,&hdf5_handle); if(retstat != NX_OK){ free(fHandle); + free(filename); return retstat; } fHandle->pNexusData=hdf5_handle; NX5assignFunctions(fHandle); - *gHandle = fHandle; + pushFileStack(fileStack,fHandle, filename); #else NXIReportError (NXpData, "ERROR: Attempt to create HDF5 file when not linked with HDF5"); - *gHandle = NULL; retstat = NX_ERROR; #endif /* HDF5 */ + free(filename); return retstat; } else if(hdf_type == 3){ /* @@ -258,24 +392,26 @@ static int determineFileType(CONSTCHAR *filename) retstat = NXXopen(filename,am,&xmlHandle); if(retstat != NX_OK){ free(fHandle); + free(filename); return retstat; } fHandle->pNexusData=xmlHandle; NXXassignFunctions(fHandle); - *gHandle = fHandle; + pushFileStack(fileStack,fHandle, filename); #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; + retstat = NX_ERROR; } - return NX_OK; + if (filename != NULL) { + free(filename); + } + return retstat; } /* ------------------------------------------------------------------------- */ @@ -284,13 +420,19 @@ static int determineFileType(CONSTCHAR *filename) { NXhandle hfil; int status; + pFileStack fileStack = NULL; pNexusFunction pFunc=NULL; - pFunc = (pNexusFunction)*fid; + fileStack = (pFileStack)*fid; + pFunc = peekFileOnStack(fileStack); hfil = pFunc->pNexusData; status = pFunc->nxclose(&hfil); pFunc->pNexusData = hfil; free(pFunc); + popFileStack(fileStack); + if(fileStackDepth(fileStack) < 0){ + killFileStack(fileStack); + } /* Fortify_CheckAllMemory(); */ @@ -301,24 +443,113 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXmakegroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxmakegroup(pFunc->pNexusData, name, nxclass); } + /*------------------------------------------------------------------------*/ +static int analyzeNapimount(char *napiMount, char *extFile, int extFileLen, + char *extPath, int extPathLen){ + char *pPtr = NULL, *path = NULL; + int length; + memset(extFile,0,extFileLen); + memset(extPath,0,extPathLen); + pPtr = strstr(napiMount,"nxfile://"); + if(pPtr == NULL){ + return NXBADURL; + } + path = strrchr(napiMount,'#'); + if(path == NULL){ + length = strlen(napiMount) - 9; + if(length > extFileLen){ + NXIReportError(NXpData,"ERROR: internal errro with external linking"); + return NXBADURL; + } + memcpy(extFile,pPtr+9,length); + strcpy(extPath,"/"); + return NXFILE; + } else { + pPtr += 9; + length = path - pPtr; + if(length > extFileLen){ + NXIReportError(NXpData,"ERROR: internal errro with external linking"); + return NXBADURL; + } + memcpy(extFile,pPtr,length); + length = strlen(path-1); + if(length > extPathLen){ + NXIReportError(NXpData,"ERROR: internal error with external linking"); + return NXBADURL; + } + strcpy(extPath,path+1); + return NXFILE; + } + return NXBADURL; +} /*------------------------------------------------------------------------*/ NXstatus NXopengroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) { - pNexusFunction pFunc = (pNexusFunction)fid; - return pFunc->nxopengroup(pFunc->pNexusData, name, nxclass); + int status, attStatus, type = NX_CHAR, length = 1023; + NXaccess access = NXACC_RDWR; + NXlink breakID; + pFileStack fileStack; + char nxurl[1024], exfile[512], expath[512]; + ErrFunc oldError; + pNexusFunction pFunc = NULL; + + fileStack = (pFileStack)fid; + pFunc = handleToNexusFunc(fid); + + status = pFunc->nxopengroup(pFunc->pNexusData, name, nxclass); + oldError = NXMGetError(); + NXIReportError = NXNXNoReport; + attStatus = NXgetattr(fid,"napimount",nxurl,&length, &type); + NXIReportError = oldError; + if(attStatus == NX_OK){ + /* + this is an external linking group + */ + status = analyzeNapimount(nxurl,exfile,511,expath,511); + if(status == NXBADURL){ + return NX_ERROR; + } + status = NXinternalopen(exfile,access, fileStack); + if(status == NX_ERROR){ + return status; + } + status = NXopenpath(fid,expath); + NXgetgroupID(fid,&breakID); + setCloseID(fileStack,breakID); + } + + return status; } /* ------------------------------------------------------------------- */ NXstatus NXclosegroup (NXhandle fid) { - pNexusFunction pFunc = (pNexusFunction)fid; - return pFunc->nxclosegroup(pFunc->pNexusData); + int status; + pFileStack fileStack = NULL; + NXlink closeID, currentID; + + pNexusFunction pFunc = handleToNexusFunc(fid); + fileStack = (pFileStack)fid; + if(fileStackDepth(fileStack) == 0){ + return pFunc->nxclosegroup(pFunc->pNexusData); + } else { + /* we have to check for leaving an external file */ + NXgetgroupID(fid,¤tID); + peekIDOnStack(fileStack,&closeID); + if(NXsameID(fid,&closeID,¤tID) == NX_OK){ + NXclose(&fid); + status = NXclosegroup(fid); + } else { + status = pFunc->nxclosegroup(pFunc->pNexusData); + } + return status; + } } /* --------------------------------------------------------------------- */ @@ -326,17 +557,8 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXmakedata (NXhandle fid, CONSTCHAR *name, int datatype, int rank, int dimensions[]) { - pNexusFunction pFunc = (pNexusFunction)fid; - if ( (datatype == NX_CHAR) && (rank > 1) ) - { - NXIReportError (NXpData, - "ERROR: multi-dimensional NX_CHAR arrays are not supported by the NeXus library"); - return NX_ERROR; - } - else - { - return pFunc->nxmakedata(pFunc->pNexusData, name, datatype, rank, dimensions); - } + pNexusFunction pFunc = handleToNexusFunc(fid); + return pFunc->nxmakedata(pFunc->pNexusData, name, datatype, rank, dimensions); } @@ -345,17 +567,8 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXcompmakedata (NXhandle fid, CONSTCHAR *name, int datatype, int rank, int dimensions[],int compress_type, int chunk_size[]) { - pNexusFunction pFunc = (pNexusFunction)fid; - if ( (datatype == NX_CHAR) && (rank > 1) ) - { - NXIReportError (NXpData, - "ERROR: multi-dimensional NX_CHAR arrays are not supported by the NeXus library"); - return NX_ERROR; - } - else - { - return pFunc->nxcompmakedata (pFunc->pNexusData, name, datatype, rank, dimensions, compress_type, chunk_size); - } + pNexusFunction pFunc = handleToNexusFunc(fid); + return pFunc->nxcompmakedata (pFunc->pNexusData, name, datatype, rank, dimensions, compress_type, chunk_size); } @@ -363,7 +576,7 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXcompress (NXhandle fid, int compress_type) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxcompress (pFunc->pNexusData, compress_type); } @@ -372,7 +585,7 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXopendata (NXhandle fid, CONSTCHAR *name) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxopendata(pFunc->pNexusData, name); } @@ -381,7 +594,7 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXclosedata (NXhandle fid) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxclosedata(pFunc->pNexusData); } @@ -389,7 +602,7 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXputdata (NXhandle fid, void *data) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxputdata(pFunc->pNexusData, data); } @@ -398,7 +611,7 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXputattr (NXhandle fid, CONSTCHAR *name, void *data, int datalen, int iType) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxputattr(pFunc->pNexusData, name, data, datalen, iType); } @@ -406,7 +619,7 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXputslab (NXhandle fid, void *data, int iStart[], int iSize[]) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxputslab(pFunc->pNexusData, data, iStart, iSize); } @@ -414,7 +627,7 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXgetdataID (NXhandle fid, NXlink* sRes) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxgetdataID(pFunc->pNexusData, sRes); } @@ -423,9 +636,16 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXmakelink (NXhandle fid, NXlink* sLink) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxmakelink(pFunc->pNexusData, sLink); } + /* ------------------------------------------------------------------- */ + + NXstatus NXmakenamedlink (NXhandle fid, CONSTCHAR *newname, NXlink* sLink) + { + pNexusFunction pFunc = handleToNexusFunc(fid); + return pFunc->nxmakenamedlink(pFunc->pNexusData, newname, sLink); + } /* --------------------------------------------------------------------*/ NXstatus NXopensourcegroup(NXhandle fid) { @@ -445,10 +665,12 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXflush(NXhandle *pHandle) { NXhandle hfil; + pFileStack fileStack = NULL; int status; pNexusFunction pFunc=NULL; - pFunc = (pNexusFunction)*pHandle; + fileStack = (pFileStack)*pHandle; + pFunc = peekFileOnStack(fileStack); hfil = pFunc->pNexusData; status = pFunc->nxflush(&hfil); pFunc->pNexusData = hfil; @@ -469,7 +691,7 @@ static int determineFileType(CONSTCHAR *filename) if ((datatype == NX_CHAR) || (datatype == NX_INT8) || (datatype == NX_UINT8)) { /* allow for terminating \0 */ - size += 1; + size += 2; } else if ((datatype == NX_INT16) || (datatype == NX_UINT16)) { size *= 2; @@ -478,6 +700,9 @@ static int determineFileType(CONSTCHAR *filename) || (datatype == NX_FLOAT32)) { size *= 4; } + else if ((datatype == NX_INT64) || (datatype == NX_UINT64)){ + size *= 8; + } else if (datatype == NX_FLOAT64) { size *= 8; } @@ -513,7 +738,7 @@ static int determineFileType(CONSTCHAR *filename) NXstatus NXgetnextentry (NXhandle fid, NXname name, NXname nxclass, int *datatype) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxgetnextentry(pFunc->pNexusData, name, nxclass, datatype); } /*----------------------------------------------------------------------*/ @@ -524,7 +749,7 @@ static int determineFileType(CONSTCHAR *filename) */ #define NUL '\0' -static char *nxitrim(char *str) +char *nxitrim(char *str) { char *ibuf = str, *obuf = str; int i = 0, cnt = 0; @@ -563,12 +788,13 @@ static char *nxitrim(char *str) int status, type, rank, iDim[NX_MAXRANK]; char *pPtr, *pPtr2; - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); status = pFunc->nxgetinfo(pFunc->pNexusData, &rank, iDim, &type); /* unstripped size if string */ - if ( (type == NX_CHAR) && (pFunc->stripFlag == 1) ) + /* only strip one dimensional strings */ + if ( (type == NX_CHAR) && (pFunc->stripFlag == 1) && (rank == 1) ) { - pPtr = (char*)malloc(iDim[0]+1); - memset(pPtr, 0, iDim[0]+1); + pPtr = (char*)malloc(iDim[0]+5); + memset(pPtr, 0, iDim[0]+5); status = pFunc->nxgetdata(pFunc->pNexusData, pPtr); pPtr2 = nxitrim(pPtr); strncpy((char*)data, pPtr2, strlen(pPtr2)); /* not NULL terminated by default */ @@ -589,12 +815,13 @@ static char *nxitrim(char *str) int status; char *pPtr = NULL; - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); status = pFunc->nxgetinfo(pFunc->pNexusData, rank, dimension, iType); /* the length of a string may be trimmed.... */ - if(*iType == NX_CHAR && pFunc->stripFlag == 1){ + /* only strip one dimensional strings */ + if((*iType == NX_CHAR) && (pFunc->stripFlag == 1) && (*rank == 1)){ pPtr = (char *)malloc((dimension[0]+1)*sizeof(char)); if(pPtr != NULL){ memset(pPtr,0,(dimension[0]+1)*sizeof(char)); @@ -603,11 +830,6 @@ static char *nxitrim(char *str) free(pPtr); } } - if ( (*iType == NX_CHAR) && (*rank > 1) ) - { - NXIReportError(NXpData, - "WARNING: multi-dimensional character arrays are not really supported"); - } return status; } @@ -616,7 +838,7 @@ static char *nxitrim(char *str) NXstatus NXgetslab (NXhandle fid, void *data, int iStart[], int iSize[]) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxgetslab(pFunc->pNexusData, data, iStart, iSize); } @@ -626,7 +848,7 @@ static char *nxitrim(char *str) NXstatus NXgetnextattr (NXhandle fileid, NXname pName, int *iLength, int *iType) { - pNexusFunction pFunc = (pNexusFunction)fileid; + pNexusFunction pFunc = handleToNexusFunc(fileid); return pFunc->nxgetnextattr(pFunc->pNexusData, pName, iLength, iType); } @@ -635,7 +857,7 @@ static char *nxitrim(char *str) NXstatus NXgetattr (NXhandle fid, char *name, void *data, int* datalen, int* iType) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxgetattr(pFunc->pNexusData, name, data, datalen, iType); } @@ -644,7 +866,7 @@ static char *nxitrim(char *str) NXstatus NXgetattrinfo (NXhandle fid, int *iN) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxgetattrinfo(pFunc->pNexusData, iN); } @@ -653,7 +875,7 @@ static char *nxitrim(char *str) NXstatus NXgetgroupID (NXhandle fileid, NXlink* sRes) { - pNexusFunction pFunc = (pNexusFunction)fileid; + pNexusFunction pFunc = handleToNexusFunc(fileid); return pFunc->nxgetgroupID(pFunc->pNexusData, sRes); } @@ -661,7 +883,7 @@ static char *nxitrim(char *str) NXstatus NXgetgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxgetgroupinfo(pFunc->pNexusData, iN, pName, pClass); } @@ -670,7 +892,7 @@ static char *nxitrim(char *str) NXstatus NXsameID (NXhandle fileid, NXlink* pFirstID, NXlink* pSecondID) { - pNexusFunction pFunc = (pNexusFunction)fileid; + pNexusFunction pFunc = handleToNexusFunc(fileid); return pFunc->nxsameID(pFunc->pNexusData, pFirstID, pSecondID); } @@ -678,7 +900,7 @@ static char *nxitrim(char *str) NXstatus NXinitattrdir (NXhandle fid) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxinitattrdir(pFunc->pNexusData); } /*-------------------------------------------------------------------------*/ @@ -686,7 +908,7 @@ static char *nxitrim(char *str) NXstatus NXsetnumberformat (NXhandle fid, int type, char *format) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); if(pFunc->nxsetnumberformat != NULL) { return pFunc->nxsetnumberformat(pFunc->pNexusData,type,format); @@ -706,10 +928,78 @@ static char *nxitrim(char *str) NXstatus NXinitgroupdir (NXhandle fid) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxinitgroupdir(pFunc->pNexusData); } +/*----------------------------------------------------------------------*/ + NXstatus NXinquirefile(NXhandle handle, char *filename, + int filenameBufferLength){ + pFileStack fileStack; + char *pPtr = NULL; + int length; + fileStack = (pFileStack)handle; + pPtr = peekFilenameOnStack(fileStack); + if(pPtr != NULL){ + length = strlen(pPtr); + if(length > filenameBufferLength){ + length = filenameBufferLength -1; + } + memset(filename,0,filenameBufferLength); + memcpy(filename,pPtr, length); + return NX_OK; + } else { + return NX_ERROR; + } +} +/*------------------------------------------------------------------------*/ +NXstatus NXisexternalgroup(NXhandle fid, CONSTCHAR *name, CONSTCHAR *class, + char *url, int urlLen){ + int status, attStatus, length = 1023, type = NX_CHAR; + ErrFunc oldError; + char nxurl[1024]; + + pNexusFunction pFunc = handleToNexusFunc(fid); + + status = pFunc->nxopengroup(pFunc->pNexusData, name,class); + if(status != NX_OK){ + return status; + } + oldError = NXMGetError(); + NXIReportError = NXNXNoReport; + attStatus = NXgetattr(fid,"napimount",nxurl,&length, &type); + NXIReportError = oldError; + pFunc->nxclosegroup(pFunc->pNexusData); + if(attStatus == NX_OK){ + length = strlen(nxurl); + if(length > urlLen){ + length = urlLen - 1; + } + memset(url,0,urlLen); + memcpy(url,nxurl,length); + return attStatus; + } else { + return NX_ERROR; + } +} +/*------------------------------------------------------------------------*/ +NXstatus NXlinkexternal(NXhandle fid, CONSTCHAR *name, CONSTCHAR *class, + CONSTCHAR *url){ + int status, type = NX_CHAR, length; + pNexusFunction pFunc = handleToNexusFunc(fid); + + status = pFunc->nxopengroup(pFunc->pNexusData,name,class); + if(status != NX_OK){ + return status; + } + length = strlen(url); + status = NXputattr(fid, "napimount",(void *)url,length, type); + if(status != NX_OK){ + return status; + } + pFunc->nxclosegroup(pFunc->pNexusData); + return NX_OK; +} /*------------------------------------------------------------------------ Implementation of NXopenpath. --------------------------------------------------------------------------*/ @@ -1009,7 +1299,7 @@ NXstatus NXopengrouppath(NXhandle hfil, CONSTCHAR *path) NXstatus NXIprintlink(NXhandle fid, NXlink* link) { - pNexusFunction pFunc = (pNexusFunction)fid; + pNexusFunction pFunc = handleToNexusFunc(fid); return pFunc->nxprintlink(pFunc->pNexusData, link); } @@ -1228,241 +1518,3 @@ char *NXIformatNeXusTime(){ return ret; } -/* - * windows stdcall aliases - */ -#ifdef _WIN32 - -NXstatus __stdcall NXISETCACHE(long newVal) -{ - return NXsetcache(newVal); -} - -void __stdcall NXNXNXREPORTERROR(void *pData, char *string) -{ - NXNXNXReportError(pData, string); -} - -NXstatus __stdcall NXIOPEN(CONSTCHAR *filename, NXaccess am, NXhandle *gHandle) -{ - return NXopen(filename, am, gHandle); -} - -NXstatus __stdcall NXICLOSE(NXhandle *fid) -{ - return NXclose(fid); -} - -NXstatus __stdcall NXIFLUSH(NXhandle* pHandle) -{ - return NXflush(pHandle); -} - -NXstatus __stdcall NXIMAKEGROUP(NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass) -{ - return NXmakegroup(handle, name, NXclass); -} - -NXstatus __stdcall NXIOPENGROUP(NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass) -{ - return NXopengroup(handle, name, NXclass); -} - -NXstatus __stdcall NXIOPENPATH(NXhandle handle, CONSTCHAR *path) -{ - return NXopenpath(handle, path); -} - -NXstatus __stdcall NXIOPENGROUPPATH (NXhandle handle, CONSTCHAR *path) -{ - return NXopengrouppath(handle, path); -} - -NXstatus __stdcall NXICLOSEGROUP(NXhandle handle) -{ - return NXclosegroup(handle); -} - -NXstatus __stdcall NXIMAKEDATA (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]) -{ - return NXmakedata (handle, label, datatype, rank, dim); -} - -NXstatus __stdcall NXICOMPMAKEDATA (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[], int comp_typ, int bufsize[]) -{ - return NXcompmakedata (handle, label, datatype, rank, dim, comp_typ, bufsize); -} - -NXstatus __stdcall NXICOMPRESS (NXhandle handle, int compr_type) -{ - return NXcompress (handle, compr_type); -} - -NXstatus __stdcall NXIOPENDATA (NXhandle handle, CONSTCHAR* label) -{ - return NXopendata (handle, label); -} - -NXstatus __stdcall NXICLOSEDATA(NXhandle handle) -{ - return NXclosedata(handle); -} - -NXstatus __stdcall NXIPUTDATA(NXhandle handle, void* data) -{ - return NXputdata(handle, data); -} - -NXstatus __stdcall NXIPUTATTR(NXhandle handle, CONSTCHAR* name, void* data, int iDataLen, int iType) -{ - return NXputattr(handle, name, data, iDataLen, iType); -} - -NXstatus __stdcall NXIPUTSLAB(NXhandle handle, void* data, int start[], int size[]) -{ - return NXputslab(handle, data, start, size); -} - -NXstatus __stdcall NXIGETDATAID(NXhandle handle, NXlink* pLink) -{ - return NXgetdataID(handle, pLink); -} - -NXstatus __stdcall NXIMAKELINK(NXhandle handle, NXlink* pLink) -{ - return NXmakelink(handle, pLink); -} - -NXstatus __stdcall NXIOPENSOURCEGROUP(NXhandle handle) -{ - return NXopensourcegroup(handle); -} - -NXstatus __stdcall NXIGETDATA(NXhandle handle, void* data) -{ - return NXgetdata(handle, data); -} - -NXstatus __stdcall NXIGETINFO(NXhandle handle, int* rank, int dimension[], int* datatype) -{ - return NXgetinfo(handle, rank, dimension, datatype); -} - -NXstatus __stdcall NXIGETNEXTENTRY(NXhandle handle, NXname name, NXname nxclass, int* datatype) -{ - return NXgetnextentry(handle, name, nxclass, datatype); -} - -NXstatus __stdcall NXIGETSLAB(NXhandle handle, void* data, int start[], int size[]) -{ - return NXgetslab(handle, data, start, size); -} - -NXstatus __stdcall NXIGETNEXTATTR(NXhandle handle, NXname pName, int *iLength, int *iType) -{ - return NXgetnextattr(handle, pName, iLength, iType); -} - -NXstatus __stdcall NXIGETATTR(NXhandle handle, char* name, void* data, int* iDataLen, int* iType) -{ - return NXgetattr(handle, name, data, iDataLen, iType); -} - -NXstatus __stdcall NXIGETATTRINFO(NXhandle handle, int* no_items) -{ - return NXgetattrinfo(handle, no_items); -} - -NXstatus __stdcall NXIGETGROUPID(NXhandle handle, NXlink* pLink) -{ - return NXgetgroupID(handle, pLink); -} - -NXstatus __stdcall NXIGETGROUPINFO(NXhandle handle, int* no_items, NXname name, NXname nxclass) -{ - return NXgetgroupinfo(handle, no_items, name, nxclass); -} - -NXstatus __stdcall NXISAMEID(NXhandle handle, NXlink* pFirstID, NXlink* pSecondID) -{ - return NXsameID(handle, pFirstID, pSecondID); -} - -NXstatus __stdcall NXIINITGROUPDIR(NXhandle handle) -{ - return NXinitgroupdir(handle); -} -NXstatus __stdcall NXIINITATTRDIR(NXhandle handle) -{ - return NXinitattrdir(handle); -} -NXstatus __stdcall NXISETNUMBERFORMAT(NXhandle handle, int type, char *format) -{ - return NXsetnumberformat(handle,type, format); -} - -NXstatus __stdcall NXIMALLOC(void** data, int rank, int dimensions[], int datatype) -{ - return NXmalloc(data, rank, dimensions, datatype); -} - -NXstatus __stdcall NXIFREE(void** data) -{ - return NXfree(data); -} - -#if 0 -/*----------------------------------------------------------------------- - NAPI internals -------------------------------------------------------------------------*/ -extern void NXMSetError(void *pData, void (*ErrFunc)(void *pD, char *text)); -extern void (*NXIReportError)(void *pData,char *text); -extern void *NXpData; -extern char *NXIformatNeXusTime(); -#endif - -/* FORTRAN internals */ - -NXstatus __stdcall NXIFOPEN(char * filename, NXaccess* am, - NexusFunction* pHandle) -{ - return NXfopen(filename, am, pHandle); -} - -NXstatus __stdcall NXIFCLOSE (NexusFunction* pHandle) -{ - return NXfclose (pHandle); -} - -NXstatus __stdcall NXIFPUTATTR(NXhandle fid, char *name, void *data, - int *pDatalen, int *pIType) -{ - return NXfputattr(fid, name, data, pDatalen, pIType); -} - -NXstatus __stdcall NXIFCOMPRESS(NXhandle fid, int *compr_type) -{ - return NXfcompress(fid, compr_type); -} - -NXstatus __stdcall NXIFCOMPMAKEDATA(NXhandle fid, char *name, - int *pDatatype, - int *pRank, int dimensions[], - int *compression_type, int chunk[]) -{ - return NXfcompmakedata(fid, name, pDatatype, pRank, dimensions, - compression_type, chunk); -} - -NXstatus __stdcall NXIFMAKEDATA(NXhandle fid, char *name, int *pDatatype, - int *pRank, int dimensions[]) -{ - return NXfmakedata(fid, name, pDatatype, pRank, dimensions); -} - -NXstatus __stdcall NXIFFLUSH(NexusFunction* pHandle) -{ - return NXfflush(pHandle); -} - -#endif /* _WIN32 */ diff --git a/napi.h b/napi.h index 1195de07..92307eb7 100644 --- a/napi.h +++ b/napi.h @@ -3,7 +3,7 @@ Application Program Interface Header File - Copyright (C) 2000-2005 Mark Koennecke, Uwe Filges + Copyright (C) 2000-2007 Mark Koennecke, Uwe Filges This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -19,9 +19,9 @@ 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 + For further information, see - $Id: napi.h,v 1.11 2007/06/22 11:44:47 koennecke Exp $ + $Id: napi.h,v 1.12 2008/01/03 09:56:56 koennecke Exp $ ----------------------------------------------------------------------------*/ @@ -29,14 +29,14 @@ #define NEXUSAPI /* NeXus HDF45 */ -#define NEXUS_VERSION "3.0.0" /* major.minor.patch */ +#define NEXUS_VERSION "4.1.0" /* major.minor.patch */ #define CONSTCHAR const char -#ifdef _WIN32 -//#define snprintf nxisnprintf +#ifdef _MSC_VER +#define snprintf nxisnprintf extern int nxisnprintf(char* buffer, int len, const char* format, ... ); -#endif /* _WIN32 */ +#endif /* _MSC_VER */ typedef void* NXhandle; /* really a pointer to a NexusFile structure */ typedef int NXstatus; @@ -101,6 +101,8 @@ typedef struct { #define NX_UINT16 23 #define NX_INT32 24 #define NX_UINT32 25 +#define NX_INT64 26 +#define NX_UINT64 27 #define NX_CHAR 4 #define NX_BINARY 21 @@ -113,11 +115,8 @@ typedef struct { typedef struct { long iTag; /* HDF4 variable */ long iRef; /* HDF4 variable */ - char iTag5[1024]; /* HDF5 variable */ - char iRef5[1024]; /* HDF5 variable */ - char iRefd[1024]; /* HDF5 variable */ - char targetPath[1024]; /* XML path */ - int linkType; + char targetPath[1024]; /* path to item to link */ + int linkType; /* HDF5: 0 for group link, 1 for SDS link */ } NXlink; #define NXMAXSTACK 50 @@ -147,6 +146,7 @@ typedef struct { # define NXputattr MANGLE(nxiputattr) # define NXgetdataID MANGLE(nxigetdataid) # define NXmakelink MANGLE(nximakelink) +# define NXmakenamedlink MANGLE(nximakenamedlink) # define NXopensourcegroup MANGLE(nxiopensourcegroup) # define NXmalloc MANGLE(nximalloc) # define NXfree MANGLE(nxifree) @@ -165,8 +165,11 @@ typedef struct { # define NXsameID MANGLE(nxisameid) # define NXinitgroupdir MANGLE(nxiinitgroupdir) # define NXinitattrdir MANGLE(nxiinitattrdir) -# define NXsetnumberformat MANGLE(nxisetnumberformat) +# define NXsetnumberformat MANGLE(nxisetnumberformat) # define NXsetcache MANGLE(nxisetcache) +# define NXinquirefile MANGLE(nxiinquirefile) +# define NXisexternalgroup MANGLE(nxiisexternalgroup) +# define NXlinkexternal MANGLE(nxilinkexternal) /* * FORTRAN helpers - for NeXus internal use only @@ -182,6 +185,11 @@ typedef struct { /* * Standard interface + * + * Functions added here are not automatically exported from + * a shared library/dll - the symbol name must also be added + * to the file src/nexus_symbols.txt + * */ #ifdef __cplusplus @@ -210,6 +218,7 @@ extern NXstatus NXputslab(NXhandle handle, void* data, int start[], int size[] extern NXstatus NXgetdataID(NXhandle handle, NXlink* pLink); extern NXstatus NXmakelink(NXhandle handle, NXlink* pLink); +extern NXstatus NXmakenamedlink(NXhandle handle, CONSTCHAR* newname, NXlink* pLink); extern NXstatus NXopensourcegroup(NXhandle handle); extern NXstatus NXgetdata(NXhandle handle, void* data); @@ -227,7 +236,11 @@ extern NXstatus NXsameID(NXhandle handle, NXlink* pFirstID, NXlink* pSecondID) extern NXstatus NXinitgroupdir(NXhandle handle); extern NXstatus NXinitattrdir(NXhandle handle); extern NXstatus NXsetnumberformat(NXhandle handle, - int type, char *format); + int type, char *format); + +extern NXstatus NXinquirefile(NXhandle handle, char *filename, int filenameBufferLength); +extern NXstatus NXisexternalgroup(NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass, char *url, int urlLen); +extern NXstatus NXlinkexternal(NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass, CONSTCHAR *url); extern NXstatus NXmalloc(void** data, int rank, int dimensions[], int datatype); extern NXstatus NXfree(void** data); @@ -239,6 +252,8 @@ extern NXstatus NXfree(void** data); typedef void (*ErrFunc)(void *data, char *text); extern void NXMSetError(void *pData, ErrFunc); extern ErrFunc NXMGetError(); +extern void NXMDisableErrorReporting(); +extern void NXMEnableErrorReporting(); extern void (*NXIReportError)(void *pData,char *text); extern void *NXpData; extern char *NXIformatNeXusTime(); @@ -267,6 +282,7 @@ extern NXstatus NXsetcache(long newVal); NXstatus ( *nxputslab)(NXhandle handle, void* data, int start[], int size[]); NXstatus ( *nxgetdataID)(NXhandle handle, NXlink* pLink); NXstatus ( *nxmakelink)(NXhandle handle, NXlink* pLink); + NXstatus ( *nxmakenamedlink)(NXhandle handle, CONSTCHAR *newname, 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); diff --git a/napi4.c b/napi4.c index 1dd21969..e0f3bb9a 100644 --- a/napi4.c +++ b/napi4.c @@ -3,7 +3,7 @@ Application Program Interface (HDF4) Routines - Copyright (C) 1997-2002 Mark Koennecke, Przemek Klosowski + Copyright (C) 1997-2006 Mark Koennecke, Przemek Klosowski This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -21,7 +21,7 @@ For further information, see - $Id: napi4.c,v 1.8 2006/03/31 15:24:53 koennecke Exp $ + $Id: napi4.c,v 1.9 2008/01/03 09:56:56 koennecke Exp $ ----------------------------------------------------------------------------*/ #include @@ -64,13 +64,50 @@ extern void *NXpData; assert(pRes->iNXID == NXSIGNATURE); return pRes; } - + /*----------------------------------------------------------------------*/ +static int findNapiClass(pNexusFile pFile, int groupRef, NXname nxclass) +{ + NXname classText, linkClass; + int32 tags[2], attID, linkID, groupID; + + groupID = Vattach(pFile->iVID,groupRef,"r"); + Vgetclass(groupID, classText); + if(strcmp(classText,"NAPIlink") != 0) + { + /* normal group */ + strcpy(nxclass,classText); + Vdetach(groupID); + return groupRef; + } + else + { + /* code for linked renamed groups */ + attID = Vfindattr(groupID,"NAPIlink"); + if(attID >= 0) + { + Vgetattr(groupID,attID, tags); + linkID = Vattach(pFile->iVID,tags[1],"r"); + Vgetclass(linkID, linkClass); + Vdetach(groupID); + Vdetach(linkID); + strcpy(nxclass,linkClass); + return tags[1]; + } + else + { + /* this allows for finding the NAPIlink group in NXmakenamedlink */ + strcpy(nxclass,classText); + Vdetach(groupID); + return groupRef; + } + } +} /* --------------------------------------------------------------------- */ static int32 NXIFindVgroup (pNexusFile pFile, CONSTCHAR *name, CONSTCHAR *nxclass) { int32 iNew, iRef, iTag; - int iN, i; + int iN, i, status; int32 *pArray = NULL; NXname pText; @@ -93,17 +130,16 @@ extern void *NXpData; for (i = 0; i < iN; i++) { iNew = Vattach (pFile->iVID, pArray[i], "r"); Vgetname (iNew, pText); + Vdetach(iNew); if (strcmp (pText, name) == 0) { - Vgetclass (iNew, pText); + pArray[i] = findNapiClass(pFile,pArray[i],pText); if (strcmp (pText, nxclass) == 0) { /* found ! */ - Vdetach (iNew); iNew = pArray[i]; free (pArray); return iNew; } } - Vdetach (iNew); } /* nothing found */ free (pArray); @@ -115,15 +151,13 @@ extern void *NXpData; if (iTag == DFTAG_VG) { iNew = Vattach (pFile->iVID, iRef, "r"); Vgetname (iNew, pText); + Vdetach(iNew); if (strcmp (pText, name) == 0) { - Vgetclass (iNew, pText); + iRef = findNapiClass(pFile,iRef, pText); if (strcmp (pText, nxclass) == 0) { - /* found ! */ - Vdetach (iNew); return iRef; } } - Vdetach (iNew); } } /* end for */ } /* end else */ @@ -264,8 +298,15 @@ extern void *NXpData; if (pFile->iCurrentSDS != 0) { /* SDS level */ iRet = SDgetinfo (pFile->iCurrentSDS, pNam, &iRank, iDim, &iType, &iAtt); - } else { /* global level */ - iRet = SDfileinfo (pFile->iSID, &iData, &iAtt); + } else { + if(pFile->iCurrentVG == 0){ + /* global level */ + iRet = SDfileinfo (pFile->iSID, &iData, &iAtt); + } else { + /* group attribute */ + iRet = Vnattrs(pFile->iCurrentVG); + iAtt = iRet; + } } if (iRet < 0) { NXIReportError (NXpData, "ERROR: HDF cannot read attribute numbers"); @@ -325,7 +366,7 @@ extern void *NXpData; { pNexusFile pNew = NULL; char pBuffer[512]; - char *time_puffer; + char *time_puffer = NULL; char HDF_VERSION[64]; uint32 lmajor, lminor, lrelease; int32 am1=0; @@ -350,8 +391,6 @@ extern void *NXpData; } memset (pNew, 0, sizeof (NexusFile)); - time_puffer = NXIformatNeXusTime(); - #if WRITE_OLD_IDENT /* not used at moment */ /* * write something that can be used by OLE @@ -402,6 +441,8 @@ extern void *NXpData; return NX_ERROR; } } + + time_puffer = NXIformatNeXusTime(); if (am == NXACC_CREATE || am == NXACC_CREATE4) { if (SDsetattr(pNew->iSID, "file_name", DFNT_CHAR8, strlen(filename), (char*)filename) < 0) { NXIReportError (NXpData, "ERROR: HDF failed to store file_name attribute "); @@ -415,9 +456,11 @@ extern void *NXpData; free(time_puffer); return NX_ERROR; } - free(time_puffer); } } + if (time_puffer != NULL) { + free(time_puffer); + } /* * Otherwise we try to create the file two times which makes HDF @@ -534,8 +577,6 @@ extern void *NXpData; /*------------------------------------------------------------------------*/ - - NXstatus NX4opengroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) { pNexusFile pFile; @@ -566,7 +607,6 @@ extern void *NXpData; NXIKillDir (pFile); return NX_OK; } - /* ------------------------------------------------------------------- */ @@ -661,6 +701,11 @@ extern void *NXpData; { type=DFNT_FLOAT64; } + else + { + NXIReportError (NXpData, "ERROR: invalid type in NX4makedata"); + return NX_ERROR; + } if (rank <= 0) { sprintf (pBuffer, "ERROR: invalid rank specified for SDS %s", @@ -787,6 +832,11 @@ extern void *NXpData; { type=DFNT_FLOAT64; } + else + { + NXIReportError (NXpData, "ERROR: invalid datatype in NX4compmakedata"); + return NX_ERROR; + } if (rank <= 0) { sprintf (pBuffer, "ERROR: invalid rank specified for SDS %s", @@ -877,7 +927,7 @@ extern void *NXpData; else { NXIReportError (NXpData, "Unknown compression method!"); - NX_ERROR; + return NX_ERROR; } /* link into Vgroup, if in one */ if (pFile->iCurrentVG != 0) { @@ -900,7 +950,7 @@ extern void *NXpData; pNexusFile pFile; int32 iRank, iAtt, iType, iRet; int32 iSize[MAX_VAR_DIMS]; - int compress_typei; + int compress_typei = COMP_CODE_NONE; NXname pBuffer; char pError[512]; comp_info compstruct; @@ -962,7 +1012,7 @@ extern void *NXpData; NXstatus NX4opendata (NXhandle fid, CONSTCHAR *name) { pNexusFile pFile; - int32 iNew; + int32 iNew, attID, tags[2]; char pBuffer[256]; int iRet; @@ -986,10 +1036,19 @@ extern void *NXpData; } /* clear pending attribute directories first */ NXIKillAttDir (pFile); - - /* open the SDS */ + + /* open the SDS, thereby watching for linked SDS under a different name */ iNew = SDreftoindex (pFile->iSID, iNew); pFile->iCurrentSDS = SDselect (pFile->iSID, iNew); + attID = SDfindattr(pFile->iCurrentSDS,"NAPIlink"); + if(attID >= 0) + { + SDreadattr(pFile->iCurrentSDS,attID, tags); + SDendaccess(pFile->iCurrentSDS); + iNew = SDreftoindex (pFile->iSID, tags[1]); + pFile->iCurrentSDS = SDselect (pFile->iSID, iNew); + } + if (pFile->iCurrentSDS < 0) { NXIReportError (NXpData, "ERROR: HDF error opening SDS"); pFile->iCurrentSDS = 0; @@ -1105,15 +1164,25 @@ extern void *NXpData; { type=DFNT_FLOAT64; } + else + { + NXIReportError (NXpData, "ERROR: Invalid data type for HDF attribute"); + return NX_ERROR; + } if (pFile->iCurrentSDS != 0) { /* SDS attribute */ iRet = SDsetattr (pFile->iCurrentSDS, (char*)name, (int32)type, (int32)datalen, data); } else { - /* global attribute */ - iRet = SDsetattr (pFile->iSID, (char*)name, (int32)type, - (int32)datalen, data); - + if(pFile->iCurrentVG == 0){ + /* global attribute */ + iRet = SDsetattr (pFile->iSID, (char*)name, (int32)type, + (int32)datalen, data); + } else { + /* group attribute */ + iRet = Vsetattr(pFile->iCurrentVG, (char *)name, (int32) type, + (int32)datalen,data); + } } iType = type; if (iRet < 0) { @@ -1218,15 +1287,66 @@ extern void *NXpData; return NX_ERROR; } Vaddtagref(pFile->iCurrentVG, sLink->iTag, sLink->iRef); + length = strlen(sLink->targetPath); 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); } + else + { + dataID = Vattach(pFile->iVID,sLink->iRef,"w"); + Vsetattr(dataID, (char *)name, type, (int32) length, sLink->targetPath); + Vdetach(dataID); + } + return NX_OK; + } + /* ------------------------------------------------------------------- */ + + + NXstatus NX4makenamedlink (NXhandle fid, CONSTCHAR* newname, NXlink* sLink) + { + pNexusFile pFile; + int32 iVG, iRet, dataID, type = DFNT_CHAR8, length, dataType = NX_CHAR, + rank = 1, attType = NX_INT32; + int iDim[1]; + char name[] = "target"; + int tags[2]; + + pFile = NXIassert (fid); + + if (pFile->iCurrentVG == 0) { /* root level, can not link here */ + return NX_ERROR; + } + + tags[0] = sLink->iTag; + tags[1] = sLink->iRef; + + length = strlen(sLink->targetPath); + if(sLink->iTag == DFTAG_SDG || sLink->iTag == DFTAG_NDG || + sLink->iTag == DFTAG_SDS) + { + iDim[0] = 1; + NX4makedata(fid,newname, dataType,rank,iDim); + NX4opendata(fid,newname); + NX4putattr(fid,"NAPIlink",tags, 2, attType); + NX4closedata(fid); + dataID = SDreftoindex(pFile->iSID,sLink->iRef); + dataID = SDselect(pFile->iSID,dataID); + SDsetattr(dataID,name,type,length,sLink->targetPath); + SDendaccess(dataID); + } else { + NX4makegroup(fid,newname,"NAPIlink"); + NX4opengroup(fid,newname,"NAPIlink"); + NX4putattr(fid,"NAPIlink",tags, 2, attType); + NX4closegroup(fid); + dataID = Vattach(pFile->iVID,sLink->iRef,"w"); + Vsetattr(dataID, (char *)name, type, (int32) length, sLink->targetPath); + Vdetach(dataID); + } return NX_OK; } @@ -1236,8 +1356,7 @@ extern void *NXpData; { pNexusFile pFile; pFile = NXIassert (fid); - printf("HDF4 link: iTag = %ld, iRef = %ld, target=\"%s\"\n", - sLink->iTag, sLink->iRef, sLink->targetPath); + printf("HDF4 link: iTag = %ld, iRef = %ld, target=\"%s\"\n", sLink->iTag, sLink->iRef, sLink->targetPath); return NX_OK; } @@ -1272,6 +1391,10 @@ extern void *NXpData; ac = NXACC_READ; }else if(pFile->iAccess[0] == 'w') { ac = NXACC_RDWR; + } else { + NXIReportError (NXpData, + "ERROR: NX4flush failed to determine file access mode"); + return NX_ERROR; } pCopy = (char *)malloc((strlen(pFileName)+10)*sizeof(char)); if(!pCopy) { @@ -1345,11 +1468,13 @@ extern void *NXpData; return NX_EOD; } } + /* Next case: end of directory */ if (iCurDir >= pFile->iStack[pFile->iStackPtr].iNDir) { NXIKillDir (pFile); return NX_EOD; } + /* Next case: we have data! supply it and increment counter */ if (pFile->iCurrentVG == 0) { /* root level */ iTemp = Vattach (pFile->iVID, @@ -1359,10 +1484,10 @@ extern void *NXpData; return NX_ERROR; } Vgetname (iTemp, name); - Vgetclass (iTemp, nxclass); + Vdetach (iTemp); + findNapiClass(pFile, pFile->iStack[pFile->iStackPtr].iRefDir[iCurDir], nxclass); *datatype = DFTAG_VG; pFile->iStack[pFile->iStackPtr].iCurDir++; - Vdetach (iTemp); return NX_OK; } else { /* in Vgroup */ if (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_VG) {/* Vgroup */ @@ -1373,7 +1498,8 @@ extern void *NXpData; return NX_ERROR; } Vgetname (iTemp, name); - Vgetclass (iTemp, nxclass); + Vdetach(iTemp); + findNapiClass(pFile, pFile->iStack[pFile->iStackPtr].iRefDir[iCurDir], nxclass); *datatype = DFTAG_VG; pFile->iStack[pFile->iStackPtr].iCurDir++; Vdetach (iTemp); @@ -1511,7 +1637,7 @@ extern void *NXpData; { pNexusFile pFile; int iRet; - int32 iPType, iCount; + int32 iPType, iCount, count; pFile = NXIassert (fileid); @@ -1528,9 +1654,16 @@ extern void *NXpData; return NX_EOD; } /* well, there must be data to copy */ - if (pFile->iCurrentSDS == 0) { /* global attribute */ - iRet = SDattrinfo (pFile->iSID, pFile->iAtt.iCurDir, - pName, &iPType, &iCount); + if (pFile->iCurrentSDS == 0) { + if(pFile->iCurrentVG == 0) { + /* global attribute */ + iRet = SDattrinfo (pFile->iSID, pFile->iAtt.iCurDir, + pName, &iPType, &iCount); + }else { + /* group attribute */ + iRet = Vattrinfo(pFile->iCurrentVG, pFile->iAtt.iCurDir, + pName, &iPType, &iCount, &count); + } } else { iRet = SDattrinfo (pFile->iCurrentSDS, pFile->iAtt.iCurDir, pName, &iPType, &iCount); @@ -1552,7 +1685,7 @@ extern void *NXpData; NXstatus NX4getattr (NXhandle fid, char *name, void *data, int* datalen, int* iType) { pNexusFile pFile; - int32 iNew, iType32; + int32 iNew, iType32, count; void *pData = NULL; int32 iLen, iRet; int type; @@ -1604,8 +1737,13 @@ extern void *NXpData; /* SDS attribute */ iNew = SDfindattr (pFile->iCurrentSDS, name); } else { - /* global attribute */ - iNew = SDfindattr (pFile->iSID, name); + if(pFile->iCurrentVG == 0){ + /* global attribute */ + iNew = SDfindattr (pFile->iSID, name); + } else { + /* group attribute */ + iNew = Vfindattr(pFile->iCurrentVG, name); + } } if (iNew < 0) { sprintf (pBuffer, "ERROR: attribute %s not found", name); @@ -1617,7 +1755,12 @@ extern void *NXpData; if (pFile->iCurrentSDS != 0) { iRet = SDattrinfo (pFile->iCurrentSDS, iNew, pNam, &iType32, &iLen); } else { - iRet = SDattrinfo (pFile->iSID, iNew, pNam, &iType32, &iLen); + if(pFile->iCurrentVG == 0){ + iRet = SDattrinfo (pFile->iSID, iNew, pNam, &iType32, &iLen); + } else { + iRet = Vattrinfo(pFile->iCurrentVG,iNew,pNam,&iType32,&count, + &iLen); + } } if (iRet < 0) { sprintf (pBuffer, "ERROR: HDF could not read attribute info"); @@ -1637,7 +1780,11 @@ extern void *NXpData; if (pFile->iCurrentSDS != 0) { iRet = SDreadattr (pFile->iCurrentSDS, iNew, pData); } else { - iRet = SDreadattr (pFile->iSID, iNew, pData); + if(pFile->iCurrentVG == 0){ + iRet = SDreadattr (pFile->iSID, iNew, pData); + } else { + iRet = Vgetattr(pFile->iCurrentVG, iNew, pData); + } } if (iRet < 0) { sprintf (pBuffer, "ERROR: HDF could not read attribute data"); @@ -1646,7 +1793,8 @@ extern void *NXpData; } /* copy data to caller */ memset (data, 0, *datalen); - if ((*datalen <= iLen) && (*iType == DFNT_UINT8 || *iType == DFNT_CHAR8 || *iType == DFNT_UCHAR8)) { + if ((*datalen <= iLen) && + (*iType == DFNT_UINT8 || *iType == DFNT_CHAR8 || *iType == DFNT_UCHAR8)) { iLen = *datalen - 1; } memcpy (data, pData, iLen); @@ -1670,8 +1818,14 @@ extern void *NXpData; if (pFile->iCurrentSDS != 0) { /* SDS level */ iRet = SDgetinfo (pFile->iCurrentSDS, pNam, &iRank, iDim, &iType, &iAtt); - } else { /* global level */ - iRet = SDfileinfo (pFile->iSID, &iData, &iAtt); + } else { + if(pFile->iCurrentVG == 0){ + /* global level */ + iRet = SDfileinfo (pFile->iSID, &iData, &iAtt); + } else { + iRet = Vnattrs(pFile->iCurrentVG); + iAtt = iRet; + } } if (iRet < 0) { NXIReportError (NXpData, "NX_ERROR: HDF cannot read attribute numbers"); @@ -1793,6 +1947,7 @@ void NX4assignFunctions(pNexusFunction fHandle) fHandle->nxputslab=NX4putslab; fHandle->nxgetdataID=NX4getdataID; fHandle->nxmakelink=NX4makelink; + fHandle->nxmakenamedlink=NX4makenamedlink; fHandle->nxgetdata=NX4getdata; fHandle->nxgetinfo=NX4getinfo; fHandle->nxgetnextentry=NX4getnextentry; diff --git a/napi5.c b/napi5.c index f730d98e..939b9972 100644 --- a/napi5.c +++ b/napi5.c @@ -93,6 +93,7 @@ static void ignoreError(void *data, char *text){ /*---------------------------------------------------------------------*/ static void buildCurrentPath(pNexusFile5 self, char *pathBuffer, int pathBufferLen){ + int length; memset(pathBuffer,0,pathBufferLen); if(self->iCurrentG != 0) { @@ -574,6 +575,14 @@ static int nxToHDF5Type(int datatype) { type=H5T_NATIVE_UINT; } + else if (datatype == NX_INT64) + { + type = H5T_NATIVE_INT64; + } + else if (datatype == NX_UINT64) + { + type = H5T_NATIVE_UINT64; + } else if (datatype == NX_FLOAT32) { type=H5T_NATIVE_FLOAT; @@ -642,18 +651,30 @@ static int nxToHDF5Type(int datatype) { /* * This assumes string lenght is in the last dimensions and - * the logic must be the same as used in NX5getglab and NX5getinfo + * the logic must be the same as used in NX5getslab and NX5getinfo * * search for tests on H5T_STRING */ byte_zahl=dimensions[rank-1]; - dimensions[rank-1]=1; for(i = 0; i < rank; i++) { mydim1[i] = dimensions[i]; } - dimensions[rank-1] = byte_zahl; - dataspace=H5Screate_simple(rank,mydim1,NULL); + mydim1[rank-1] = 1; + if (dimensions[rank-1] > 1) + { + mydim[rank-1] = maxdims[rank-1] = size[rank-1] = 1; + } + if (chunkdims[rank-1] > 1) + { + chunkdims[rank-1] = 1; + } + if (dimensions[0] == NX_UNLIMITED) + { + mydim1[0] = 1; + maxdims[0] = H5S_UNLIMITED; + } + dataspace=H5Screate_simple(rank,mydim1,maxdims); } else { if (dimensions[0] == NX_UNLIMITED) { @@ -944,18 +965,29 @@ static void killAttVID(pNexusFile5 pFile, int vid){ return NX_ERROR; } rank = H5Sget_simple_extent_ndims(pFile->iCurrentS); + iRet = H5Sget_simple_extent_dims(pFile->iCurrentS, NULL, maxdims); for(i = 0; i < rank; i++) { myStart[i] = iStart[i]; mySize[i] = iSize[i]; size[i] = iSize[i]; } - iRet = H5Sget_simple_extent_dims(pFile->iCurrentS, NULL, maxdims); + if (H5Tget_class(pFile->iCurrentT) == H5T_STRING) + { + mySize[rank - 1] = 1; + myStart[rank - 1] = 0; + } dataspace = H5Screate_simple (rank, mySize, NULL); if (maxdims[0] == NX_UNLIMITED) { size[0]=iStart[0] + iSize[0]; iRet = H5Dextend(pFile->iCurrentD, size); + if (iRet < 0) + { + NXIReportError (NXpData, "ERROR: extend slab failed"); + return NX_ERROR; + } + filespace = H5Dget_space(pFile->iCurrentD); /* define slab */ @@ -970,6 +1002,10 @@ static void killAttVID(pNexusFile5 pFile, int vid){ /* write slab */ iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace, filespace, H5P_DEFAULT,data); + if (iRet < 0) + { + NXIReportError (NXpData, "ERROR: writing slab failed"); + } iRet = H5Sclose(filespace); } else { /* define slab */ @@ -984,12 +1020,16 @@ static void killAttVID(pNexusFile5 pFile, int vid){ /* write slab */ iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace, pFile->iCurrentS, H5P_DEFAULT,data); + if (iRet < 0) + { + NXIReportError (NXpData, "ERROR: writing slab failed"); + } } /* deal with HDF errors */ iRet = H5Sclose(dataspace); if (iRet < 0) { - NXIReportError (NXpData, "ERROR: writing slab failed"); + NXIReportError (NXpData, "ERROR: closing slab failed"); return NX_ERROR; } return NX_OK; @@ -1042,6 +1082,7 @@ static void killAttVID(pNexusFile5 pFile, int vid){ static NXstatus NX5settargetattribute(pNexusFile5 pFile, NXlink *sLink) { herr_t length, dataID, status, aid2, aid1, attID; + int type = NX_CHAR; char name[] = "target"; length = strlen(sLink->targetPath); @@ -1093,6 +1134,7 @@ NXstatus NX5makenamedlink(NXhandle fid, CONSTCHAR *name, NXlink *sLink) { pNexusFile5 pFile; char linkTarget[1024]; + int type = NX_CHAR, length; int status; pFile = NXI5assert (fid); @@ -1127,6 +1169,7 @@ NXstatus NX5makenamedlink(NXhandle fid, CONSTCHAR *name, NXlink *sLink) { pNexusFile5 pFile; char linkTarget[1024]; + int type = NX_CHAR, length; char *itemName = NULL; int status; @@ -1325,6 +1368,15 @@ static int hdf5ToNXType(int data_id, hid_t atype) } else { iPtype=NX_UINT32; } + } + else if(size_id == 8) + { + if (sign_id==H5T_SGN_2) + { + iPtype=NX_INT64; + } else { + iPtype=NX_UINT64; + } } } else if (data_id==H5T_FLOAT) { @@ -1383,6 +1435,15 @@ static int h5MemType(hid_t atype) memtype_id = H5T_NATIVE_UINT32; } } + else if (size_id==8) + { + if (sign_id==H5T_SGN_2) + { + memtype_id = H5T_NATIVE_INT64; + } else { + memtype_id = H5T_NATIVE_UINT64; + } + } } else if (data_id==H5T_FLOAT) { size_id=H5Tget_size(atype); @@ -1406,7 +1467,7 @@ static int h5MemType(hid_t atype) pNexusFile5 pFile; hid_t grp, attr1,type,atype; int iRet,iPtype, i; - int idx,data_id; + int idx,data_id,size_id, sign_id; char data[128]; char ph_name[1024]; info_type op_data; @@ -1529,7 +1590,7 @@ static int h5MemType(hid_t atype) { pNexusFile5 pFile; int iStart[H5S_MAX_RANK], status; - hid_t data_id, memtype_id; + hid_t data_id, memtype_id, size_id, sign_id; int dims; pFile = NXI5assert (fid); @@ -1576,7 +1637,7 @@ static int h5MemType(hid_t atype) pNexusFile5 pFile; int i, iRank, mType, iRet; hsize_t myDim[H5S_MAX_RANK]; - hid_t data_id; + hid_t data_id,size_id,sign_id; pFile = NXI5assert (fid); /* check if there is an Dataset open */ @@ -1612,7 +1673,7 @@ static int h5MemType(hid_t atype) hsize_t mySize[H5S_MAX_RANK]; hsize_t mStart[H5S_MAX_RANK]; hid_t memspace, iRet, data_id; - hid_t memtype_id; + hid_t memtype_id, size_id, sign_id; char *tmp_data = NULL; char *data1; int i, dims, iRank, mtype = 0; @@ -1636,6 +1697,7 @@ static int h5MemType(hid_t atype) /* * FAA 24/1/2007: I don't think this will work for multidimensional * string arrays. + * MK 23/7/2007: You are right Freddie. */ mtype = NX_CHAR; if (mySize[0] == 1) { @@ -1711,7 +1773,7 @@ static int h5MemType(hid_t atype) int *iLength, int *iType) { pNexusFile5 pFile; - hid_t attr_id; + hid_t attr_id,size_id,sign_id; hid_t iRet, atype, aspace; int iPType,rank; char *iname = NULL; @@ -1753,8 +1815,8 @@ static int h5MemType(hid_t atype) return NX5getnextattr(fileid, pName, iLength, iType); } strcpy(pName, iname); - iname = NULL; free(iname); + iname = NULL; } else { strcpy(pName,"What is this?"); } @@ -1841,8 +1903,10 @@ static int h5MemType(hid_t atype) NXstatus NX5getattrinfo (NXhandle fid, int *iN) { pNexusFile5 pFile; + char *iname = NULL; unsigned int idx; int vid; + herr_t iRet; pFile = NXI5assert (fid); idx=0; @@ -1869,7 +1933,8 @@ static int h5MemType(hid_t atype) NXstatus NX5getgroupID (NXhandle fileid, NXlink* sRes) { pNexusFile5 pFile; - int datalen, type = NX_CHAR; + int u, datalen, type = NX_CHAR; + char group_name[64], class_name[64]; ErrFunc oldErr; pFile = NXI5assert (fileid); @@ -1950,6 +2015,7 @@ void NX5assignFunctions(pNexusFunction fHandle) fHandle->nxputslab=NX5putslab; fHandle->nxgetdataID=NX5getdataID; fHandle->nxmakelink=NX5makelink; + fHandle->nxmakenamedlink=NX5makenamedlink; fHandle->nxgetdata=NX5getdata; fHandle->nxgetinfo=NX5getinfo; fHandle->nxgetnextentry=NX5getnextentry; diff --git a/napiu.c b/napiu.c index 635b0cd9..18f68e6c 100644 --- a/napiu.c +++ b/napiu.c @@ -21,10 +21,10 @@ For further information, see - $Id: napiu.c,v 1.1 2005/10/05 07:20:18 koennecke Exp $ + $Id: napiu.c,v 1.2 2008/01/03 09:56:56 koennecke Exp $ ----------------------------------------------------------------------------*/ -static const char* rscid = "$Id: napiu.c,v 1.1 2005/10/05 07:20:18 koennecke Exp $"; /* Revision interted by CVS */ +static const char* rscid = "$Id: napiu.c,v 1.2 2008/01/03 09:56:56 koennecke Exp $"; /* Revision interted by CVS */ #include #include @@ -41,7 +41,7 @@ static const char* rscid = "$Id: napiu.c,v 1.1 2005/10/05 07:20:18 koennecke Exp } \ } - NXstatus CALLING_STYLE NXUwriteglobals(NXhandle file_id, const char* user, const char* affiliation, const char* address, const char* telephone_number, const char* fax_number, const char* email) + NXstatus NXUwriteglobals(NXhandle file_id, const char* user, const char* affiliation, const char* address, const char* telephone_number, const char* fax_number, const char* email) { DO_GLOBAL(user); DO_GLOBAL(affiliation); @@ -53,7 +53,7 @@ static const char* rscid = "$Id: napiu.c,v 1.1 2005/10/05 07:20:18 koennecke Exp } /* NXUwritegroup creates and leaves open a group */ - NXstatus CALLING_STYLE NXUwritegroup(NXhandle file_id, const char* group_name, const char* group_class) + NXstatus NXUwritegroup(NXhandle file_id, const char* group_name, const char* group_class) { int status; status = NXmakegroup(file_id, group_name, group_class); @@ -64,22 +64,22 @@ static const char* rscid = "$Id: napiu.c,v 1.1 2005/10/05 07:20:18 koennecke Exp return status; } - NXstatus CALLING_STYLE NXUwritedata(NXhandle file_id, const char* data_name, const void* data, int data_type, int rank, const int dim[], const char* units, const int start[], const int size[]) + NXstatus NXUwritedata(NXhandle file_id, const char* data_name, const void* data, int data_type, int rank, const int dim[], const char* units, const int start[], const int size[]) { return NX_OK; } - NXstatus CALLING_STYLE NXUreaddata(NXhandle file_id, const char* data_name, void* data, char* units, const int start[], const int size[]) + NXstatus NXUreaddata(NXhandle file_id, const char* data_name, void* data, char* units, const int start[], const int size[]) { return NX_OK; } - NXstatus CALLING_STYLE NXUwritehistogram(NXhandle file_id, const char* data_name, const void* data, const char* units) + NXstatus NXUwritehistogram(NXhandle file_id, const char* data_name, const void* data, const char* units) { return NX_OK; } - NXstatus CALLING_STYLE NXUreadhistogram(NXhandle file_id, const char* data_name, void* data, char* units) + NXstatus NXUreadhistogram(NXhandle file_id, const char* data_name, void* data, char* units) { return NX_OK; } @@ -88,7 +88,7 @@ static int NXcompress_type = 0; static int NXcompress_size = 0; /* NXUsetcompress sets the default compression type and minimum size */ - NXstatus CALLING_STYLE NXUsetcompress(NXhandle file_id, int comp_type, int comp_size) + NXstatus NXUsetcompress(NXhandle file_id, int comp_type, int comp_size) { int status; if (comp_type == NX_COMP_LZW || comp_type == NX_COMP_HUF || @@ -110,7 +110,7 @@ static int NXcompress_size = 0; } /* !NXUfindgroup finds if a NeXus group of the specified name exists */ - NXstatus CALLING_STYLE NXUfindgroup(NXhandle file_id, const char* group_name, char* group_class) + NXstatus NXUfindgroup(NXhandle file_id, const char* group_name, char* group_class) { int status, n; NXname vname, vclass; @@ -122,38 +122,38 @@ static int NXcompress_size = 0; return NX_OK; } - NXstatus CALLING_STYLE NXUfindclass(NXhandle file_id, const char* group_class, char* group_name, int find_index) + NXstatus NXUfindclass(NXhandle file_id, const char* group_class, char* group_name, int find_index) { return NX_OK; } /* NXUfinddata finds if a NeXus data item is in the current group */ - NXstatus CALLING_STYLE NXUfinddata(NXhandle file_id, const char* data_name) + NXstatus NXUfinddata(NXhandle file_id, const char* data_name) { return NX_OK; } - NXstatus CALLING_STYLE NXUfindattr(NXhandle file_id, const char* attr_name) + NXstatus NXUfindattr(NXhandle file_id, const char* attr_name) { return NX_OK; } - NXstatus CALLING_STYLE NXUfindsignal(NXhandle file_id, int signal, char* data_name, int* data_rank, int* data_type, int data_dimensions[]) + NXstatus NXUfindsignal(NXhandle file_id, int signal, char* data_name, int* data_rank, int* data_type, int data_dimensions[]) { return NX_OK; } - NXstatus CALLING_STYLE NXUfindaxis(NXhandle file_id, int axis, int primary, char* data_name, int* data_rank, int* data_type, int data_dimensions[]) + NXstatus NXUfindaxis(NXhandle file_id, int axis, int primary, char* data_name, int* data_rank, int* data_type, int data_dimensions[]) { return NX_OK; } - NXstatus CALLING_STYLE NXUfindlink(NXhandle file_id, NXlink* group_id, const char* group_class) + NXstatus NXUfindlink(NXhandle file_id, NXlink* group_id, const char* group_class) { return NX_OK; } - NXstatus CALLING_STYLE NXUresumelink(NXhandle file_id, NXlink group_id) + NXstatus NXUresumelink(NXhandle file_id, NXlink group_id) { return NX_OK; } diff --git a/napiu.h b/napiu.h index d57915b3..75efcefd 100644 --- a/napiu.h +++ b/napiu.h @@ -21,7 +21,7 @@ For further information, see - $Id: napiu.h,v 1.1 2005/10/05 07:20:18 koennecke Exp $ + $Id: napiu.h,v 1.2 2008/01/03 09:56:56 koennecke Exp $ ----------------------------------------------------------------------------*/ @@ -34,35 +34,35 @@ extern "C" { #endif /* __cplusplus */ -NX_EXTERNAL NXstatus CALLING_STYLE NXUwriteglobals(NXhandle file_id, const char* user, const char* affiliation, const char* address, const char* phone, const char* fax, const char* email); +extern NXstatus NXUwriteglobals(NXhandle file_id, const char* user, const char* affiliation, const char* address, const char* phone, const char* fax, const char* email); -NX_EXTERNAL NXstatus CALLING_STYLE NXUwritegroup(NXhandle file_id, const char* group_name, const char* group_class); +extern NXstatus NXUwritegroup(NXhandle file_id, const char* group_name, const char* group_class); -NX_EXTERNAL NXstatus CALLING_STYLE NXUwritedata(NXhandle file_id, const char* data_name, const void* data, int data_type, int rank, const int dim[], const char* units, const int start[], const int size[]); +extern NXstatus NXUwritedata(NXhandle file_id, const char* data_name, const void* data, int data_type, int rank, const int dim[], const char* units, const int start[], const int size[]); -NX_EXTERNAL NXstatus CALLING_STYLE NXUreaddata(NXhandle file_id, const char* data_name, void* data, char* units, const int start[], const int size[]); +extern NXstatus NXUreaddata(NXhandle file_id, const char* data_name, void* data, char* units, const int start[], const int size[]); -NX_EXTERNAL NXstatus CALLING_STYLE NXUwritehistogram(NXhandle file_id, const char* data_name, const void* data, const char* units); +extern NXstatus NXUwritehistogram(NXhandle file_id, const char* data_name, const void* data, const char* units); -NX_EXTERNAL NXstatus CALLING_STYLE NXUreadhistogram(NXhandle file_id, const char* data_name, void* data, char* units); +extern NXstatus NXUreadhistogram(NXhandle file_id, const char* data_name, void* data, char* units); -NX_EXTERNAL NXstatus CALLING_STYLE NXUsetcompress(NXhandle file_id, int comp_type, int comp_size); +extern NXstatus NXUsetcompress(NXhandle file_id, int comp_type, int comp_size); -NX_EXTERNAL NXstatus CALLING_STYLE NXUfindgroup(NXhandle file_id, const char* group_name, char* group_class); +extern NXstatus NXUfindgroup(NXhandle file_id, const char* group_name, char* group_class); -NX_EXTERNAL NXstatus CALLING_STYLE NXUfindclass(NXhandle file_id, const char* group_class, char* group_name, int find_index); +extern NXstatus NXUfindclass(NXhandle file_id, const char* group_class, char* group_name, int find_index); -NX_EXTERNAL NXstatus CALLING_STYLE NXUfinddata(NXhandle file_id, const char* data_name); +extern NXstatus NXUfinddata(NXhandle file_id, const char* data_name); -NX_EXTERNAL NXstatus CALLING_STYLE NXUfindattr(NXhandle file_id, const char* attr_name); +extern NXstatus NXUfindattr(NXhandle file_id, const char* attr_name); -NX_EXTERNAL NXstatus CALLING_STYLE NXUfindsignal(NXhandle file_id, int signal, char* data_name, int* data_rank, int* data_type, int data_dimensions[]); +extern NXstatus NXUfindsignal(NXhandle file_id, int signal, char* data_name, int* data_rank, int* data_type, int data_dimensions[]); -NX_EXTERNAL NXstatus CALLING_STYLE NXUfindaxis(NXhandle file_id, int axis, int primary, char* data_name, int* data_rank, int* data_type, int data_dimensions[]); +extern NXstatus NXUfindaxis(NXhandle file_id, int axis, int primary, char* data_name, int* data_rank, int* data_type, int data_dimensions[]); -NX_EXTERNAL NXstatus CALLING_STYLE NXUfindlink(NXhandle file_id, NXlink* group_id, const char* group_class); +extern NXstatus NXUfindlink(NXhandle file_id, NXlink* group_id, const char* group_class); -NX_EXTERNAL NXstatus CALLING_STYLE NXUresumelink(NXhandle file_id, NXlink group_id); +extern NXstatus NXUresumelink(NXhandle file_id, NXlink group_id); #ifdef __cplusplus } diff --git a/network.c b/network.c index ad127726..acdddfd5 100644 --- a/network.c +++ b/network.c @@ -170,7 +170,8 @@ CreateSocketAdress( int iRet; fd_set lMask; struct timeval tmo = {1,0}; - int iLen, i; + int i; + socklen_t iLen; struct linger lili; assert(self != NULL); @@ -378,7 +379,7 @@ CreateSocketAdress( { int t; - int len; + socklen_t len; struct sockaddr_in sin; struct hostent *host; @@ -855,7 +856,7 @@ int NETReconnect(mkChannel* self) long lMask = 0L; struct timeval tmo ={0,1}; long iRet; - int iLang; + socklen_t iLang; if(!VerifyChannel(self)) { diff --git a/nxconfig.h b/nxconfig.h index 2e5df705..b532efd6 100644 --- a/nxconfig.h +++ b/nxconfig.h @@ -14,16 +14,22 @@ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `df' library (-ldf). */ -#define HAVE_LIBDF 1 +/* #undef HAVE_LIBDF */ + +/* Define to 1 if you have the `dl' library (-ldl). */ +#define HAVE_LIBDL 1 /* Define to 1 if you have the `hdf5' library (-lhdf5). */ -#define HAVE_LIBHDF5 1 +/* #undef HAVE_LIBHDF5 */ /* Define to 1 if you have the `jpeg' library (-ljpeg). */ #define HAVE_LIBJPEG 1 +/* Define to 1 if you have the `m' library (-lm). */ +#define HAVE_LIBM 1 + /* Define to 1 if you have the `mfhdf' library (-lmfhdf). */ -#define HAVE_LIBMFHDF 1 +/* #undef HAVE_LIBMFHDF */ /* Define to 1 if you have the `rpc' library (-lrpc). */ /* #undef HAVE_LIBRPC */ @@ -32,7 +38,7 @@ /* #undef HAVE_LIBSYSTEMSTUBS */ /* Define to 1 if you have the `sz' library (-lsz). */ -#define HAVE_LIBSZ 1 +/* #undef HAVE_LIBSZ */ /* Define to 1 if you have the `xml2' library (-lxml2). */ #define HAVE_LIBXML2 1 @@ -96,19 +102,25 @@ #define PACKAGE "nexus" /* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "nexus-developers@anl.gov" +#define PACKAGE_BUGREPORT "nexus-developers@nexusformat.org" /* Define to the full name of this package. */ #define PACKAGE_NAME "NeXus Library" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "NeXus Library 3.0.1" +#define PACKAGE_STRING "NeXus Library 4.1.0" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "nexus" /* Define to the version of this package. */ -#define PACKAGE_VERSION "3.0.1" +#define PACKAGE_VERSION "4.1.0" + +/* Set to printf format for int64_t */ +#define PRINTF_INT64 "lld" + +/* Set to printf format for uint64_t */ +#define PRINTF_UINT64 "llu" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 @@ -120,7 +132,7 @@ /* #undef TM_IN_SYS_TIME */ /* Version number of package */ -#define VERSION "3.0.1" +#define VERSION "4.1.0" /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ diff --git a/nxdataset.c b/nxdataset.c index c64c1321..90e47fe3 100644 --- a/nxdataset.c +++ b/nxdataset.c @@ -19,6 +19,8 @@ static int getTypeSize(int typecode){ return 4; break; case NX_FLOAT64: + case NX_INT64: + case NX_UINT64: return 8; break; case NX_INT16: @@ -208,6 +210,10 @@ double getNXDatasetValueAt(pNXDS dataset, int address){ case NX_UINT32: value = (double)dataset->u.iPtr[address]; break; + case NX_INT64: + case NX_UINT64: + value = (double)dataset->u.lPtr[address]; + break; case NX_INT16: case NX_UINT16: value = (double)dataset->u.sPtr[address]; @@ -224,10 +230,10 @@ char *getNXDatasetText(pNXDS dataset){ int length, status = 1; if(dataset == NULL){ - status = 0; + return strdup("NULL"); } if(dataset->magic != MAGIC){ - status = 0; + return strdup("NULL"); } if(dataset->rank > 1){ status = 0; @@ -236,6 +242,8 @@ char *getNXDatasetText(pNXDS dataset){ dataset->type == NX_FLOAT64 || dataset->type == NX_INT32 || dataset->type == NX_UINT32 || + dataset->type == NX_INT64 || + dataset->type == NX_UINT64 || dataset->type == NX_INT16 || dataset->type == NX_UINT16 ) { status = 0; @@ -284,6 +292,10 @@ int putNXDatasetValueAt(pNXDS dataset, int address, double value){ case NX_UINT32: dataset->u.iPtr[address] = (int)value; break; + case NX_INT64: + case NX_UINT64: + dataset->u.lPtr[address] = (int64_t)value; + break; case NX_INT16: case NX_UINT16: dataset->u.sPtr[address] = (short int)value; diff --git a/nxdataset.h b/nxdataset.h index c8613aa1..3a2d2734 100644 --- a/nxdataset.h +++ b/nxdataset.h @@ -12,6 +12,8 @@ #define MAGIC 7776622 +#include "napiconfig.h" + typedef struct { int magic; int rank; @@ -25,6 +27,7 @@ typedef struct { int *iPtr; short int *sPtr; char *cPtr; + int64_t *lPtr; } u; }*pNXDS, NXDS; @@ -41,6 +44,8 @@ typedef struct { #define NX_UINT16 23 #define NX_INT32 24 #define NX_UINT32 25 +#define NX_INT64 26 +#define NX_UINT64 27 #define NX_CHAR 4 #define NX_MAXRANK 32 diff --git a/nxio.c b/nxio.c index ca5be754..a74145e9 100644 --- a/nxio.c +++ b/nxio.c @@ -25,8 +25,15 @@ */ #include #include +#include "napi.h" #include "nxio.h" #include "nxdataset.h" +#include "napiconfig.h" + +/* fix for mxml-2.3 */ +#ifndef MXML_WRAP +#define MXML_WRAP 79 +#endif /* #define TESTMAIN 1 */ /*=================== type code handling ================================= */ @@ -36,7 +43,8 @@ typedef struct { int nx_type; }type_code; -static type_code typecode[9]; +#define NTYPECODE 11 +static type_code typecode[NTYPECODE]; /*-----------------------------------------------------------------------*/ void initializeNumberFormats(){ type_code myCode; @@ -76,21 +84,31 @@ void initializeNumberFormats(){ myCode.nx_type = NX_INT32; typecode[6] = myCode; - strcpy(myCode.name,"NX_UNIT32"); + strcpy(myCode.name,"NX_UINT32"); strcpy(myCode.format,"%12d"); myCode.nx_type = NX_UINT32; typecode[7] = myCode; + strcpy(myCode.name,"NX_INT64"); + strcpy(myCode.format,"%24" PRINTF_INT64 ); + myCode.nx_type = NX_INT64; + typecode[8] = myCode; + + strcpy(myCode.name,"NX_UINT64"); + strcpy(myCode.format,"%24" PRINTF_UINT64); + myCode.nx_type = NX_UINT64; + typecode[9] = myCode; + strcpy(myCode.name,"NX_CHAR"); strcpy(myCode.format,"%c"); myCode.nx_type = NX_CHAR; - typecode[8] = myCode; + typecode[10] = myCode; } /*----------------------------------------------------------------------*/ void setNumberFormat(int nx_type, char *format){ int i; - for(i = 0; i < 9; i++){ + for(i = 0; i < NTYPECODE; i++){ if(typecode[i].nx_type == nx_type){ strncpy(typecode[i].format,format,29); } @@ -100,7 +118,7 @@ void setNumberFormat(int nx_type, char *format){ static void getNumberFormat(int nx_type, char format[30]){ int i; - for(i = 0; i < 9; i++){ + for(i = 0; i < NTYPECODE; i++){ if(typecode[i].nx_type == nx_type){ strncpy(format,typecode[i].format,29); } @@ -110,7 +128,7 @@ static void getNumberFormat(int nx_type, char format[30]){ void getNumberText(int nx_type, char *typestring, int typeLen){ int i; - for(i = 0; i < 9; i++){ + for(i = 0; i < NTYPECODE; i++){ if(typecode[i].nx_type == nx_type){ strncpy(typestring,typecode[i].name,typeLen); } @@ -138,9 +156,14 @@ myxml_add_char(int ch, /* I - Character to add */ */ if (*bufsize < 1024) + { (*bufsize) *= 2; + } else - (*bufsize) += 1024; + { + (*bufsize) *= 3; + (*bufsize) /= 2; + } newbuffer = (char *)malloc(*bufsize*sizeof(char)); if(!newbuffer){ @@ -204,7 +227,7 @@ 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, +void analyzeDim(const char *typeString, int *rank, int *iDim, int *type){ char dimString[132]; char dim[20]; @@ -219,6 +242,8 @@ static void analyzeDim(const char *typeString, int *rank, case NX_UINT16: case NX_INT32: case NX_UINT32: + case NX_INT64: + case NX_UINT64: case NX_FLOAT32: case NX_FLOAT64: iDim[0] = 1; @@ -258,7 +283,7 @@ static void analyzeDim(const char *typeString, int *rank, int translateTypeCode(char *code){ int i, result = -1; - for(i = 0; i < 9; i++){ + for(i = 0; i < NTYPECODE; i++){ if(strstr(code,typecode[i].name) != NULL){ result = typecode[i].nx_type; break; @@ -346,7 +371,11 @@ mxml_type_t nexusTypeCallback(mxml_node_t *parent){ */ return MXML_OPAQUE; } else{ - return MXML_CUSTOM; + if(strstr(typeString,"NX_CHAR") != NULL){ + return MXML_OPAQUE; + } else { + return MXML_CUSTOM; + } } } } @@ -411,12 +440,19 @@ static void formatNumber(double value, char *txt, int txtLen, case NX_UINT32: snprintf(txt,txtLen,format,(int)value); break; + case NX_INT64: + snprintf(txt,txtLen,format,(int64_t)value); + break; + case NX_UINT64: + snprintf(txt,txtLen,format,(uint64_t)value); + break; case NX_FLOAT32: case NX_FLOAT64: snprintf(txt,txtLen,format,value); break; default: - assert(0); /* something is very wrong here */ + /*assert(0); something is very wrong here */ + printf("Problem\n"); break; } } @@ -534,8 +570,12 @@ static int isTextData(mxml_node_t *node){ } } /*---------------------------------------------------------------------*/ + +/* + * note: not reentrant or thead safe; returns pointer to static storage + */ const char *NXwhitespaceCallback(mxml_node_t *node, int where){ - char *indent; + static char *indent = NULL; int len; if(strstr(node->value.element.name,"?xml") != NULL){ @@ -545,6 +585,11 @@ const char *NXwhitespaceCallback(mxml_node_t *node, int where){ if(isTextData(node)){ if(where == MXML_WS_BEFORE_OPEN){ len = countDepth(node)*2 + 2; + if (indent != NULL) + { + free(indent); + indent = NULL; + } indent = (char *)malloc(len*sizeof(char)); if(indent != NULL){ memset(indent,' ',len); @@ -558,6 +603,11 @@ const char *NXwhitespaceCallback(mxml_node_t *node, int where){ if(where == MXML_WS_BEFORE_OPEN || where == MXML_WS_BEFORE_CLOSE){ len = countDepth(node)*2 + 2; + if (indent != NULL) + { + free(indent); + indent = NULL; + } indent = (char *)malloc(len*sizeof(char)); if(indent != NULL){ memset(indent,' ',len); diff --git a/nxio.h b/nxio.h index 98283779..0de80474 100644 --- a/nxio.h +++ b/nxio.h @@ -40,6 +40,8 @@ void getNumberText(int nx_type, char *typestring, int typeLen); void destroyDataset(void *data); int translateTypeCode(char *code); int isDataNode(mxml_node_t *node); +void analyzeDim(const char *typeString, int *rank, + int *iDim, int *type); #endif diff --git a/nxxml.c b/nxxml.c index 36f84ac5..e1ab96aa 100644 --- a/nxxml.c +++ b/nxxml.c @@ -31,6 +31,7 @@ extern void *NXpData; +char *nxitrim(char *str); /* from napi.c */ /*----------------------- our data structures -------------------------- One might wonder why a node stack is still needed even if this API @@ -388,28 +389,24 @@ NXstatus NXXmakedata (NXhandle fid, if(dimensions[0] < 0){ dimensions[0] = 1; } - if ((datatype == NX_CHAR) && (rank > 1)) { - NXIReportError(NXpData,"NeXus XML-API does not yet support multi-dimensional character arrays"); - return NX_ERROR; - } current = xmlHandle->stack[xmlHandle->stackPointer].current; + dataNode = mxmlNewElement(current,name); + typestring = buildTypeString(datatype,rank,dimensions); + if(typestring != NULL){ + mxmlElementSetAttr(dataNode,TYPENAME,typestring); + free(typestring); + } else { + NXIReportError(NXpData,"Failed to allocate typestring"); + return NX_ERROR; + } /* NX_CHAR maps to MXML_OPAQUE datasets */ - dataNode = mxmlNewElement(current,name); if(datatype == NX_CHAR){ newData = mxmlNewOpaque(dataNode,""); return NX_OK; } else { - typestring = buildTypeString(datatype,rank,dimensions); - if(typestring != NULL){ - mxmlElementSetAttr(dataNode,TYPENAME,typestring); - free(typestring); - } else { - NXIReportError(NXpData,"Failed to allocate typestring"); - return NX_ERROR; - } newData = (mxml_node_t *)malloc(sizeof(mxml_node_t)); if(!newData){ NXIReportError(NXpData,"Failed to allocate space for dataset"); @@ -458,24 +455,6 @@ static mxml_node_t *searchSDSLinks(pXMLNexus xmlHandle, CONSTCHAR *name){ } return NULL; } -/*-------------------------------------------------------------------*/ -static int strtrimcr(char *szStr, char *szSet) -{ - int i, j; /* Locale counters */ - - /*-------------------------------------------------*/ - - j = i = strlen(szStr) - 1; /* Find length of string */ - - while (strrchr(szSet, szStr[ i ]) - && (0 <= i)) - { - /* While string is terminated by one of the specified characters */ - szStr[ i-- ] = '\0'; /*- Replace character with '\0' */ - } - - return(j - i); /* Return the difference between old and new length */ -} /*-----------------------------------------------------------------------*/ NXstatus NXXopendata (NXhandle fid, CONSTCHAR *name){ pXMLNexus xmlHandle = NULL; @@ -547,7 +526,8 @@ NXstatus NXXputdata (NXhandle fid, void *data){ mxml_node_t *userData = NULL; mxml_node_t *current = NULL; pNXDS dataset; - int length; + int i, length, type, rank, dim[NX_MAXRANK]; + char *pPtr = NULL; xmlHandle = (pXMLNexus)fid; assert(xmlHandle); @@ -562,9 +542,28 @@ NXstatus NXXputdata (NXhandle fid, void *data){ assert(userData != NULL); if(userData->type == MXML_OPAQUE){ /* - text data + Text data. We have to make sure that the text is \0 terminated. + Some language bindings do not ensure that this is the case. */ - mxmlSetOpaque(userData,(const char *)data); + if(NXXgetinfo(fid,&rank, dim, &type) == NX_OK){ + length = 1; + for(i=0; ivalue.custom.data; assert(dataset); @@ -579,7 +578,7 @@ NXstatus NXXgetdata (NXhandle fid, void *data){ mxml_node_t *userData = NULL; mxml_node_t *current = NULL; pNXDS dataset; - int length; + int i, length, type, rank, dim[NX_MAXRANK]; xmlHandle = (pXMLNexus)fid; assert(xmlHandle); @@ -596,7 +595,17 @@ NXstatus NXXgetdata (NXhandle fid, void *data){ /* text data */ - strcpy((char *)data,userData->value.opaque); + if(NXXgetinfo(fid,&rank, dim, &type) == NX_OK){ + length = 1; + for(i=0; ivalue.opaque,length); + } else { + strcpy((char *)data,nxitrim(userData->value.opaque)); + } + } else { dataset = (pNXDS)userData->value.custom.data; assert(dataset); @@ -613,6 +622,7 @@ NXstatus NXXgetinfo (NXhandle fid, int *rank, mxml_node_t *current = NULL; pNXDS dataset; int myRank, i; + const char *attr = NULL; xmlHandle = (pXMLNexus)fid; assert(xmlHandle); @@ -629,9 +639,15 @@ NXstatus NXXgetinfo (NXhandle fid, int *rank, /* text data */ - *rank = 1; - *iType = NX_CHAR; - dimension[0]= strlen(userData->value.opaque); + attr = mxmlElementGetAttr(current, TYPENAME); + if(attr == NULL){ + *rank = 1; + *iType = NX_CHAR; + dimension[0]= strlen(userData->value.opaque); + } else { + analyzeDim(attr,rank,dimension,iType); + *iType = NX_CHAR; + } } else { dataset = (pNXDS)userData->value.custom.data; assert(dataset); @@ -868,14 +884,18 @@ static NXstatus NXXsetnumberformat(NXhandle fid, /*============================ Attributes ============================*/ static char *formatAttributeData(void *data, int datalen, int iType){ int intData = 0; - long iValue; - double dValue; + long iValue = -99999; + double dValue = -1e38; char type[20]; char *number; if(iType == NX_CHAR){ - return strdup((char *)data); +/* data may not be NULL terminated */ + number = (char*)malloc((datalen+1) * sizeof(char)); + memcpy(number, data, datalen * sizeof(char)); + number[datalen] = '\0'; + return number; } number = (char *)malloc(132*sizeof(char)); @@ -1454,7 +1474,7 @@ NXstatus NXXmakelink (NXhandle fid, NXlink* sLink){ } /*-----------------------------------------------------------------------*/ -NXstatus NXXmakenamedlink (NXhandle fid, char *name, NXlink* sLink){ +NXstatus NXXmakenamedlink (NXhandle fid, CONSTCHAR *name, NXlink* sLink){ pXMLNexus xmlHandle = NULL; mxml_node_t *current = NULL, *linkNode = NULL; mxml_node_t *linkedNode = NULL; @@ -1511,6 +1531,7 @@ void NXXassignFunctions(pNexusFunction fHandle){ fHandle->nxputslab=NXXputslab; fHandle->nxgetdataID=NXXgetdataID; fHandle->nxmakelink=NXXmakelink; + fHandle->nxmakenamedlink=NXXmakenamedlink; fHandle->nxgetdata=NXXgetdata; fHandle->nxgetinfo=NXXgetinfo; fHandle->nxgetnextentry=NXXgetnextentry; diff --git a/remob.c b/remob.c index a716c90f..98d4ecdc 100644 --- a/remob.c +++ b/remob.c @@ -636,7 +636,7 @@ int RemServerAction(SConnection *pCon, SicsInterp *pSics, void *pData, TokenList *pCurrent; TokenList *pName; int iRet; - int i; + socklen_t i; int pos; float fValue; long lID; diff --git a/sicshipadaba.c b/sicshipadaba.c index 0cc0e784..1f3ff857 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -2595,6 +2595,7 @@ static int SicsCommandNode(SConnection *pCon, SicsInterp *pSics, void *pData, } node->value.v.text = strdup(argv[2]); node->value.arrayLength = strlen(argv[2]); + SetHdbProperty(node,"sicscommand", argv[2]); kalle = MakeHipadabaCallback(CommandSetCallback,NULL, NULL, -1,-1); if(kalle == NULL){ diff --git a/sinfox.c b/sinfox.c index 75cfc21e..e4c6b449 100644 --- a/sinfox.c +++ b/sinfox.c @@ -439,7 +439,7 @@ static int SinfoxList(pSinfox pSin, SicsInterp* pSics, SConnection *pCon, iRet = EnumChoice(pIFaces,iNumIFaces,objName); if(-1 < iRet) { - if((0==strcmp(keyName,"device")) || (0==strcmp(keyName,NULL))) + if((0==strcmp(keyName,"device")) || keyName == NULL ) { /* format as sinfox list server interface interfaceName */ setOKE(objName,keyName,eltName,"server","interface",objName); } else if(0==strcmp(keyName,"command")) diff --git a/sllinux_def b/sllinux_def index ea98bcdb..38576c3a 100644 --- a/sllinux_def +++ b/sllinux_def @@ -9,4 +9,4 @@ MFLAGS=-f makefile_linux$(DUMMY) -HDFROOT=/afs/psi.ch/project/sinq/sl-linux +HDFROOT=/afs/psi.ch/project/sinq/sl5 diff --git a/stdscan.c b/stdscan.c index aacbd9dc..2f1ae4d1 100644 --- a/stdscan.c +++ b/stdscan.c @@ -765,8 +765,8 @@ int prepareDataFile(pScanData self){ pVarEntry pVar = NULL; void *pDings; int i, iRet, status; - char pStatus[512], pItem[20]; - char pHead[512]; + char pStatus[2024], pItem[20]; + char pHead[2024]; float fVal; CountEntry sCount; @@ -820,8 +820,10 @@ int prepareDataFile(pScanData self){ strcat(pStatus,pItem); /* write progress */ - strcat(pHead,"\n"); - strcat(pStatus,"\n"); + /* + strcat(pHead,"\r\n"); + strcat(pStatus,"\r\n"); + */ SCWrite(self->pCon,pHead,eWarning); SCWrite(self->pCon,pStatus,eWarning); diff --git a/test/DataNumber b/test/DataNumber index 7f22e2d7..75148a66 100644 --- a/test/DataNumber +++ b/test/DataNumber @@ -1,3 +1,3 @@ - 99 + 131 NEVER, EVER modify or delete this file You'll risk eternal damnation and a reincarnation as a cockroach!|n \ No newline at end of file