From 5a06bb9b90e69acfa05b7387dd6915441b615037 Mon Sep 17 00:00:00 2001 From: koennecke Date: Wed, 14 Aug 2013 09:50:22 +0000 Subject: [PATCH] - Removed napi from SICS - Added error fields to hwardware objects: motor, counter, histmem - Optimised sinqhttpopt - Added haddcheck which adds checks to hipadaba nodes. The current implementation only checks for selctions agaisnt the values property. Expand when more checks are required. SKIPPED: psi/polterwrite.c psi/sinqhttpopt.c psi/tasinit.c --- ascon.c | 2 +- asynnet.c | 2 +- counter.c | 29 +- counter.h | 1 + dynstring.c | 10 +- dynstring.h | 5 + hipadaba.c | 4 + histmem.c | 17 + macro.c | 29 +- make_gen | 10 +- makefile_slinux | 2 +- motor.c | 25 +- motor.h | 1 + napi.c | 2133 ----------------------------------------- napi.h | 959 ------------------- napi4.c | 1983 -------------------------------------- napi4.h | 60 -- napi5.c | 2301 --------------------------------------------- napi5.h | 54 -- nxio.c | 747 --------------- nxio.h | 50 - nxscript.c | 19 + nxstack.c | 145 --- nxstack.h | 52 - nxxml.c | 1992 --------------------------------------- nxxml.h | 78 -- sctdriveobj.c | 2 - sicshipadaba.c | 81 ++ sicsobj.c | 6 + sicvar.c | 5 + sllinux_def | 2 +- tasublib.c | 2 +- test/sicsstat.tcl | 30 +- test/testini.tcl | 9 + trace.c | 6 +- 35 files changed, 255 insertions(+), 10598 deletions(-) delete mode 100644 napi.c delete mode 100644 napi.h delete mode 100644 napi4.c delete mode 100644 napi4.h delete mode 100644 napi5.c delete mode 100644 napi5.h delete mode 100644 nxio.c delete mode 100644 nxio.h delete mode 100644 nxstack.c delete mode 100755 nxstack.h delete mode 100644 nxxml.c delete mode 100644 nxxml.h diff --git a/ascon.c b/ascon.c index 6b5f3e25..69c3e840 100644 --- a/ascon.c +++ b/ascon.c @@ -668,7 +668,7 @@ Ascon *AsconMake(SConnection * con, int argc, char *argv[]) free(args); return NULL; } - a->rdBuffer = CreateDynString(60, 63); + a->rdBuffer = CreateDynString(60, 65536); a->wrBuffer = CreateDynString(60, 63); a->errmsg = CreateDynString(60, 63); diff --git a/asynnet.c b/asynnet.c index d59c854d..8aa349b1 100644 --- a/asynnet.c +++ b/asynnet.c @@ -395,7 +395,7 @@ void ANETprocess(void) { int i, status, count = 0, socke = 0, length; fd_set readMask, writeMask; - struct timeval tmo = { 0, 10 }; + struct timeval tmo = { 0, 20 }; FD_ZERO(&readMask); FD_ZERO(&writeMask); diff --git a/counter.c b/counter.c index bc562b15..bf05593a 100644 --- a/counter.c +++ b/counter.c @@ -71,7 +71,19 @@ static int Halt(void *pData) return self->pDriv->Halt(self->pDriv); } +/*-------------------------------------------------------------------------*/ +static void SetCounterError(void *pData, char *text) +{ + pCounter self = NULL; + assert(pData); + self = (pCounter) pData; + + if(self->error != NULL){ + free(self->error); + } + self->error = strdup(text); +} /*--------------------------------------------------------------------------*/ static void SetCountParameters(void *pData, float fPreset, CounterMode eMode) @@ -103,6 +115,7 @@ static int StartCount(void *pData, SConnection * pCon) return 0; } + SetCounterError(pData,"None"); /* try at least three times to do it */ for (i = 0; i < 3; i++) { iRet = self->pDriv->Start(self->pDriv); @@ -122,6 +135,7 @@ static int StartCount(void *pData, SConnection * pCon) eError); SCSetInterrupt(pCon, eAbortBatch); ReleaseCountLock(self->pCountInt); + SetCounterError(pData,pError); return HWFault; } } @@ -233,6 +247,7 @@ static int TransferData(void *pData, SConnection * pCon) SCWrite(pCon, "ERROR: Cannot fix counter problem, aborting", eError); SCSetInterrupt(pCon, eAbortBatch); + SetCounterError(pData,pError); return HWFault; } } @@ -269,6 +284,7 @@ static int CheckCountStatus(void *pData, SConnection * pCon) SCSetInterrupt(pCon, eAbortBatch); InvokeCallBack(self->pCall, COUNTEND, NULL); ReleaseCountLock(self->pCountInt); + SetCounterError(pData,pError); return eCt; } else { return HWBusy; @@ -695,7 +711,7 @@ static int isAuthorised(SConnection * pCon, int iCode) } /*-----------------------------------------------------------------------*/ -static int CounterInterest(int iEvent, void *pEvent, void *pUser) +int CounterInterest(int iEvent, void *pEvent, void *pUser) { SConnection *pCon = NULL; pMonEvent pMon = NULL; @@ -775,6 +791,7 @@ pCounter CreateCounter(char *name, pCounterDriver pDriv) pRes->isUpToDate = 1; pRes->iExponent = 0; pRes->name = strdup(name); + pRes->error = strdup("None"); return pRes; } @@ -816,7 +833,8 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData, {"setpar", 3, {FUPATEXT, FUPAINT, FUPAFLOAT}}, {"getpar", 2, {FUPATEXT, FUPAOPT}}, {"getnmon", 0, {0, 0}}, - {"state", 0, {0, 0}} + {"state", 0, {0, 0}}, + {"error", 0, {0, 0}} }; char *pMode[] = { "timer", @@ -833,7 +851,7 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData, argtolower(argc, argv); argx = &argv[1]; iRet = - EvaluateFuPa((pFuncTemplate) & ActionTemplate, 24, argc - 1, argx, + EvaluateFuPa((pFuncTemplate) & ActionTemplate, 25, argc - 1, argx, &PaRes); if (iRet < 0) { snprintf(pBueffel, 255,"%s", PaRes.pError); @@ -1150,6 +1168,11 @@ int CountAction(SConnection * pCon, SicsInterp * pSics, void *pData, SCWrite(pCon, pBueffel, eValue); return 1; break; + case 24: /* error */ + snprintf(pBueffel, 131, "%s.error = %s", argv[0],self->error); + SCWrite(pCon, pBueffel, eValue); + return 1; + break; default: assert(0); /* internal error */ } diff --git a/counter.h b/counter.h index 02b7a21e..298dc7dc 100644 --- a/counter.h +++ b/counter.h @@ -32,6 +32,7 @@ typedef struct __Counter{ int haltFixFlag; /* solely here to prevent multiple calls to the halt function on overrun timers in countersec.c*/ int tbLength; /* These two for caching float time bins in second generation HM's */ float *timeBinning; + char *error; int (*setMode)(struct __Counter *self, CounterMode eMode); CounterMode (*getMode)(struct __Counter *self); int (*getNMonitor)(struct __Counter *self); diff --git a/dynstring.c b/dynstring.c index 83977115..c45a6afd 100644 --- a/dynstring.c +++ b/dynstring.c @@ -83,7 +83,15 @@ static int Resize(pDynString self, int iRequested) self->iBufferSize = iNewSize; return 1; } - +/*--------------------------------------------------------------------------*/ +int DynStringCapacity(pDynString self, int length) +{ + if(self->iBufferSize < length){ + return Resize(self,length); + } else { + return 1; + } +} /*--------------------------------------------------------------------------*/ void DeleteDynString(pDynString self) { diff --git a/dynstring.h b/dynstring.h index be9d90be..95013c3d 100644 --- a/dynstring.h +++ b/dynstring.h @@ -109,4 +109,9 @@ char *Dyn2Cstring(pDynString self); /* convert to C string and delete dynstring. The result must be freed when no longer used. */ +/* + Ensures that the DynString has the capacity length. In order to avoid unnecessary + concatenation when the length is already known. +*/ +int DynStringCapacity(pDynString self, int length); #endif diff --git a/hipadaba.c b/hipadaba.c index 7ebe44b1..806cdf4f 100644 --- a/hipadaba.c +++ b/hipadaba.c @@ -303,6 +303,10 @@ static pHdb locateChild(pHdb root, char *name) { pHdb current = NULL; + if(root == NULL){ + return NULL; + } + current = root->child; while (current != NULL) { if (strcmp(current->name, name) == 0) { diff --git a/histmem.c b/histmem.c index a3424dfd..8b31114a 100644 --- a/histmem.c +++ b/histmem.c @@ -18,6 +18,10 @@ Mark Koennecke, March 2009 + Added an error field in the options stringdict + + Mark Koennecke, June 2013 + Copyright: Labor fuer Neutronenstreuung @@ -204,6 +208,7 @@ static int HistStartCount(void *pData, SConnection * pCon) } /* try at least three times to do it */ + StringDictUpdate(self->pDriv->pOption, "error", "None"); for (i = 0; i < 3; i++) { iRet = self->pDriv->Start(self->pDriv, pCon); if (iRet == OKOK) { @@ -221,6 +226,7 @@ static int HistStartCount(void *pData, SConnection * pCon) eLogError); SCSetInterrupt(pCon, eAbortBatch); ReleaseCountLock(self->pCountInt); + StringDictUpdate(self->pDriv->pOption, "error", pError); return HWFault; } } @@ -344,6 +350,7 @@ static int HistCountStatus(void *pData, SConnection * pCon) SCSetInterrupt(pCon, eAbortBatch); InvokeCallBack(self->pCall, COUNTEND, NULL); ReleaseCountLock(self->pCountInt); + StringDictUpdate(self->pDriv->pOption, "error", pError); return eCt; } else { updateHMData(self->pDriv->data); @@ -399,6 +406,7 @@ static int HistTransfer(void *pData, SConnection * pCon) SCWrite(pCon, "ERROR: failed to fix histogram memory problem", eError); SCSetInterrupt(pCon, eAbortBatch); + StringDictUpdate(self->pDriv->pOption, "error", pError); iStatus = HWFault; } } @@ -465,6 +473,7 @@ pHistMem CreateHistMemory(char *driver) } StringDictAddPair(pOption, "driver", driver); StringDictAddPair(pOption, "update", "0"); + StringDictAddPair(pOption, "error", "None"); /* initialise driver */ if (strcmp(driver, "sim") == 0) { @@ -912,6 +921,7 @@ int GetHistogramDirect(pHistMem self, SConnection * pCon, SCWrite(pCon, pBueffel, eError); iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr); if (iRet == COTERM) { + StringDictUpdate(self->pDriv->pOption, "error", pError); return 0; } } @@ -963,6 +973,7 @@ int PresetHistogram(pHistMem self, SConnection * pCon, HistInt lVal) SCWrite(pCon, pBueffel, eError); iRet = self->pDriv->TryAndFixIt(self->pDriv, iErr); if (iRet == COTERM) { + StringDictUpdate(self->pDriv->pOption, "error", pError); return 0; } } @@ -1790,6 +1801,12 @@ int HistAction(SConnection * pCon, SicsInterp * pSics, void *pData, SCSendOK(pCon); return 1; } + /* error */ + else if (strcmp(argv[1], "error") == 0) { + StringDictGet(self->pDriv->pOption, "error", pBueffel, sizeof(pBueffel)); + SCPrintf(pCon,eValue,"%s.error = %s", argv[0], pBueffel); + return 1; + } /*-------- sum */ else if (strcmp(argv[1], "sum") == 0) { /* read following arguments as ints and put them diff --git a/macro.c b/macro.c index 71257632..6ef29fd3 100644 --- a/macro.c +++ b/macro.c @@ -172,19 +172,22 @@ static int SicsUnknownProc(ClientData pData, Tcl_Interp * pInter, } /* check for endless loop */ - Arg2Text(margc, myarg, comBuffer, 131); - if (lastCommand != NULL) { - if (strcmp(lastCommand, comBuffer) == 0) { - Tcl_AppendResult(pInter, "ERROR: Never ending loop in unknown\n", - "Offending command: ", comBuffer, - " Probably Tcl command not found", NULL); - SCSetInterrupt(pCon, eAbortBatch); - return TCL_ERROR; - } - } - if (pSics->lastUnknown[pSics->iStack]) - free(pSics->lastUnknown[pSics->iStack]); - pSics->lastUnknown[pSics->iStack] = strdup(comBuffer); + /* Arg2Text(margc, myarg, comBuffer, 131); */ + /* if (lastCommand != NULL) { */ + /* if (strcmp(lastCommand, comBuffer) == 0) { */ + /* Tcl_AppendResult(pInter, "ERROR: Never ending loop in unknown\n", */ + /* "Offending command: ", comBuffer, */ + /* " Probably Tcl command not found", NULL); */ + /* /\* SCSetInterrupt(pCon, eAbortBatch); */ + /* The interrupt cause me a problem in a race condition at BOA. */ + /* Try to understand why this check is necessary in the first place. */ + /* *\/ */ + /* return TCL_ERROR; */ + /* } */ + /* } */ + /* if (pSics->lastUnknown[pSics->iStack]) */ + /* free(pSics->lastUnknown[pSics->iStack]); */ + /* pSics->lastUnknown[pSics->iStack] = strdup(comBuffer); */ /* invoke */ pCon->sicsError = 0; diff --git a/make_gen b/make_gen index 2c280282..ae8169cd 100644 --- a/make_gen +++ b/make_gen @@ -13,9 +13,9 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ sicsexit.o costa.o task.o $(FORTIFYOBJ) testprot.o\ 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 napi5.o napi4.o\ - script.o o2t.o alias.o napi.o stringdict.o sdynar.o \ - histmem.o histdriv.o histsim.o interface.o callback.o nxio.o \ + lld_blob.o strrepl.o lin2ang.o fomerge.o \ + script.o o2t.o alias.o stringdict.o sdynar.o \ + histmem.o histdriv.o histsim.o interface.o callback.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\ @@ -25,7 +25,7 @@ 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\ 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 nxxml.o\ + d_sign.o d_mod.o tcldrivable.o stdscan.o diffscan.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 nxdataset.o \ @@ -38,7 +38,7 @@ SOBJ = network.o ifile.o conman.o SCinter.o splitter.o passwd.o \ moregress.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 frame.o syncedprot.o\ - nxcopy.o nxinterhelper.o nxinter_wrap.o nxstack.o arrayutil.o \ + nxcopy.o nxinterhelper.o nxinter_wrap.o arrayutil.o \ sctdriveadapter.o sctdriveobj.o reflist.o singlex.o fourmess.o \ sgclib.o sgfind.o sgio.o sgsi.o sghkl.o singlediff.o singlebi.o \ singlenb.o simindex.o simidx.o uselect.o singletas.o motorsec.o \ diff --git a/makefile_slinux b/makefile_slinux index 3c4c5ed5..eca1ed3d 100644 --- a/makefile_slinux +++ b/makefile_slinux @@ -26,7 +26,7 @@ EXTRA=nintf.o SUBLIBS = psi/libpsi.a psi/hardsup/libhlib.a matrix/libmatrix.a \ psi/tecs/libtecsl.a LIBS = -L$(HDFROOT)/lib $(SUBLIBS) $(NILIB) $(EPICSLIBS) \ - -ltcl $(HDFROOT)/lib/libhdf5.a \ + -ltcl -lNeXus $(HDFROOT)/lib/libhdf5.a \ $(HDFROOT)/lib/libsz.a \ $(HDFROOT)/lib/libjson.a \ -ldl -lz $(HDFROOT)/lib/libmxml.a $(HDFROOT)/lib/libghttp.a -lm -lc -lpthread diff --git a/motor.c b/motor.c index b9a5f836..8b08a43e 100644 --- a/motor.c +++ b/motor.c @@ -81,7 +81,14 @@ #define IGNOREFAULT 10 #define MOVECOUNT 11 - +/*-------------------------------------------------------------------------*/ +static void SetMotorError(pMotor self, char *text) +{ + if(self->error != NULL){ + free(self->error); + } + self->error = strdup(text); +} /*-------------------------------------------------------------------------*/ static void *MotorGetInterface(void *pData, int iID) { @@ -378,17 +385,18 @@ static int reportAndFixError(pMotor self, SConnection * pCon) switch (iRet) { case MOTFAIL: snprintf(pBueffel, 255, "ERROR: %s on %s", pError, self->name); - SCWrite(pCon, pBueffel, eError); + SCWrite(pCon, pBueffel, eLogError); newStatus = HWFault; + SetMotorError(self,pError); break; case MOTREDO: snprintf(pBueffel, 255, "WARNING: %s on %s", pError, self->name); - SCWrite(pCon, pBueffel, eWarning); + SCWrite(pCon, pBueffel, eLog); newStatus = statusRunTo(self, pCon); break; case MOTOK: snprintf(pBueffel, 255, "WARNING: %s on %s", pError, self->name); - SCWrite(pCon, pBueffel, eWarning); + SCWrite(pCon, pBueffel, eLog); newStatus = HWIdle; break; default: @@ -702,6 +710,7 @@ static long MotorRunImpl(void *sulf, SConnection * pCon, float fNew) SCSetInterrupt(pCon, eAbortBatch); return 0; } + SetMotorError(self,"None"); /* check boundaries first */ iRet = MotorCheckBoundaryImpl(self, fNew, &fHard, pError, 131); @@ -709,6 +718,7 @@ static long MotorRunImpl(void *sulf, SConnection * pCon, float fNew) snprintf(pBueffel, 511, "ERROR: %s", pError); SCWrite(pCon, pBueffel, eError); SCSetInterrupt(pCon, eAbortOperation); + SetMotorError(self,pError); return 0; } @@ -731,6 +741,7 @@ static long MotorRunImpl(void *sulf, SConnection * pCon, float fNew) ServerWriteGlobal(pBueffel, eError); SCSetInterrupt(pCon, eAbortBatch); self->pDrivInt->iErrorCount = 0; + SetMotorError(self,"Motor ALARM!!!!"); return 0; } @@ -753,6 +764,7 @@ static long MotorRunImpl(void *sulf, SConnection * pCon, float fNew) SCWrite(pCon, pError, eError); SCWrite(pCon, "\n", eError); SCSetInterrupt(pCon, (int) ObVal(self->ParArray, INT)); + SetMotorError(self,pError); return HWFault; case MOTREDO: iRet = self->pDriver->RunTo(self->pDriver, fHard); @@ -821,6 +833,7 @@ pMotor MotorInit(char *drivername, char *name, MotorDriver * pDriv) pM->pDriver = pDriv; pM->drivername = strdup(drivername); pM->name = strdup(name); + pM->error = strdup("None"); /* initialise object descriptor */ @@ -1286,6 +1299,10 @@ int MotorAction(SConnection * pCon, SicsInterp * pSics, void *pData, DeleteTokenList(pList); SCSendOK(pCon); return 1; + } /* check for error */ + else if (strcmp(pCurrent->text, "error") == 0) { + SCPrintf(pCon,eValue,"%s.error = %s", argv[0], self->error); + return 1; } else if (strcmp(pCurrent->text, "interest") == 0) { /* interest */ pMoti = (pMotInfo) malloc(sizeof(MotInfo)); if (!pMoti) { diff --git a/motor.h b/motor.h index f06bc2c6..72e32d50 100644 --- a/motor.h +++ b/motor.h @@ -28,6 +28,7 @@ typedef struct __Motor { float *fVal); char *drivername; char *name; + char *error; MotorDriver *pDriver; float fTarget; float fPosition; diff --git a/napi.c b/napi.c deleted file mode 100644 index 921d618f..00000000 --- a/napi.c +++ /dev/null @@ -1,2133 +0,0 @@ -/*--------------------------------------------------------------------------- - NeXus - Neutron & X-ray Common Data Format - - Application Program Interface Routines - - 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 - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - For further information, see - -----------------------------------------------------------------------------*/ - -static const char* rscid = "$Id: napi.c,v 1.16 2012/03/29 08:41:05 koennecke Exp $"; /* Revision inserted by CVS */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "nxconfig.h" -#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 "\\" -#define THREAD_LOCAL __declspec(thread) -#else -#define LIBSEP ":" -#define PATHSEP "/" -#define THREAD_LOCAL __thread -#endif - -#ifdef _MSC_VER -#define snprintf _snprintf -#endif /* _MSC_VER */ - -#include "nx_stptok.h" - -#if defined(_WIN32) -/* - * HDF5 on windows does not do locking for multiple threads conveniently so we will implement it ourselves. - * Freddie Akeroyd, 16/06/2011 - */ -#include - - -static CRITICAL_SECTION nx_critical; - -static int nxilock() -{ - static int first_call = 1; - if (first_call) - { - first_call = 0; - InitializeCriticalSection(&nx_critical); - } - EnterCriticalSection(&nx_critical); - return NX_OK; -} - -static int nxiunlock(int ret) -{ - LeaveCriticalSection(&nx_critical); - return ret; -} - -#define LOCKED_CALL(__call) \ - ( nxilock() , nxiunlock(__call) ) - -#elif HAVE_LIBPTHREAD - -#include - -static pthread_mutex_t nx_mutex; - -#ifdef PTHREAD_MUTEX_RECURSIVE -#define RECURSIVE_LOCK PTHREAD_MUTEX_RECURSIVE -#else -#define RECURSIVE_LOCK PTHREAD_MUTEX_RECURSIVE_NP -#endif /* PTHREAD_MUTEX_RECURSIVE */ - -static void nx_pthread_init() -{ - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, RECURSIVE_LOCK); - pthread_mutex_init(&nx_mutex, &attr); -} - -static int nxilock() -{ - static pthread_once_t once_control = PTHREAD_ONCE_INIT; - if (pthread_once(&once_control, nx_pthread_init) != 0) - { - NXReportError("pthread_once failed"); - return NX_ERROR; - } - if (pthread_mutex_lock(&nx_mutex) != 0) - { - NXReportError("pthread_mutex_lock failed"); - return NX_ERROR; - } - return NX_OK; -} - -static int nxiunlock(int ret) -{ - if (pthread_mutex_unlock(&nx_mutex) != 0) - { - NXReportError("pthread_mutex_unlock failed"); - return NX_ERROR; - } - return ret; -} - -#define LOCKED_CALL(__call) \ - ( nxilock() , nxiunlock(__call) ) - -#else - -#define LOCKED_CALL(__call) \ - __call - -#endif /* _WIN32 */ - -/** - * valid NeXus names - */ -int validNXName(const char* name, int allow_colon) -{ - int i; - if (name == NULL) - { - return 0; - } - for(i=0; i= 'a' && name[i] <= 'z') || - (name[i] >= 'A' && name[i] <= 'Z') || - (name[i] >= '0' && name[i] <= '9') || - (name[i] == '_') ) - { - ; - } - else if (allow_colon && name[i] == ':') - { - ; - } - else - { - return 0; - } - } - return 1; -} - -static int64_t* dupDimsArray(int* dims_array, int rank) -{ - int i; - int64_t* dims64 = (int64_t*)malloc(rank * sizeof(int64_t)); - if (dims64 != NULL) - { - for(i=0; i 0) - { - nx_cacheSize = newVal; - return NX_OK; - } - return NX_ERROR; -} - -/*-----------------------------------------------------------------------*/ -static NXstatus NXisXML(CONSTCHAR *filename) -{ - FILE *fd = NULL; - char line[132]; - - fd = fopen(filename,"r"); - if(fd) { - int fgets_ok = (fgets(line,131,fd) != NULL); - fclose(fd); - if (fgets_ok) { - if(strstr(line,"?xml") != NULL){ - return NX_OK; - } - } - else { - return NX_ERROR; - } - } - return NX_ERROR; -} - -/*-------------------------------------------------------------------------*/ - static void NXNXNXReportError(void *pData, char *string) - { - fprintf(stderr, "%s \n", string); - } - /*---------------------------------------------------------------------*/ - - static void *NXEHpData = NULL; - static void (*NXEHIReportError)(void *pData, char *string) = NXNXNXReportError; -#ifdef HAVE_TLS - static THREAD_LOCAL void *NXEHpTData = NULL; - static THREAD_LOCAL void (*NXEHIReportTError)(void *pData, char *string) = NULL; -#endif - - void NXIReportError(void *pData, char *string) { - fprintf(stderr, "Your application uses NXIReportError, but its first parameter is ignored now - you should use NXReportError."); - NXReportError(string); - } - - void NXReportError(char *string) { -#ifdef HAVE_TLS - if (NXEHIReportTError) { - (*NXEHIReportTError)(NXEHpTData, string); - return; - } -#endif - if (NXEHIReportError) { - (*NXEHIReportError)(NXEHpData, string); - } - } - - /*---------------------------------------------------------------------*/ - extern void NXMSetError(void *pData, void (*NewError)(void *pD, char *text)) - { - NXEHpData = pData; - NXEHIReportError = NewError; - } -/*----------------------------------------------------------------------*/ - extern void NXMSetTError(void *pData, void (*NewError)(void *pD, char *text)) - { -#ifdef HAVE_TLS - NXEHpTData = pData; - NXEHIReportTError = NewError; -#else - NXMSetError(pData, NewError); -#endif - } -/*----------------------------------------------------------------------*/ -extern ErrFunc NXMGetError(){ -#ifdef HAVE_TLS - if (NXEHIReportTError) { - return NXEHIReportTError; - } -#endif - return NXEHIReportError; -} - -/*----------------------------------------------------------------------*/ -static void NXNXNoReport(void *pData, char *string){ - /* do nothing */ -} -/*----------------------------------------------------------------------*/ - -static ErrFunc last_global_errfunc = NXNXNXReportError; -#ifdef HAVE_TLS -static THREAD_LOCAL ErrFunc last_thread_errfunc = NULL; -#endif - -extern void NXMDisableErrorReporting() -{ -#ifdef HAVE_TLS - if (NXEHIReportTError) { - last_thread_errfunc = NXEHIReportTError; - NXEHIReportTError = NXNXNoReport; - return; - } -#endif - if (NXEHIReportError) { - last_global_errfunc = NXEHIReportError; - NXEHIReportError = NXNXNoReport; - } -} - -extern void NXMEnableErrorReporting() -{ -#ifdef HAVE_TLS - if (last_thread_errfunc) { - NXEHIReportTError = last_thread_errfunc; - last_thread_errfunc = NULL; - return; - } -#endif - if (last_global_errfunc) { - NXEHIReportError = last_global_errfunc; - last_global_errfunc = NULL; - } -} - -/*----------------------------------------------------------------------*/ -#ifdef HDF5 -#include "napi5.h" -#endif -#ifdef HDF4 -#include "napi4.h" -#endif -#ifdef NXXML -#include "nxxml.h" -#endif - /* ---------------------------------------------------------------------- - - Definition of NeXus API - - ---------------------------------------------------------------------*/ -static int determineFileTypeImpl(CONSTCHAR *filename) -{ - FILE *fd = NULL; - int iRet; - - /* - 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; -} - -static int determineFileType(CONSTCHAR *filename) -{ - return LOCKED_CALL(determineFileTypeImpl(filename)); -} - -/*---------------------------------------------------------------------*/ -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; - - *gHandle = NULL; - fileStack = makeFileStack(); - if(fileStack == NULL){ - NXReportError("ERROR: no memory to create filestack"); - return NX_ERROR; - } - status = NXinternalopen(userfilename,am,fileStack); - if(status == NX_OK){ - *gHandle = fileStack; - } - - return status; -} -/*-----------------------------------------------------------------------*/ -static NXstatus NXinternalopenImpl(CONSTCHAR *userfilename, NXaccess am, pFileStack fileStack) - { - int hdf_type=0; - int iRet=0; - NXhandle hdf5_handle = NULL; - NXhandle hdf4_handle = NULL; - NXhandle xmlHandle = NULL; - pNexusFunction fHandle = NULL; - NXstatus retstat = NX_ERROR; - char error[1024]; - char *filename = NULL; - int my_am = (am & NXACCMASK_REMOVEFLAGS); - - /* configure fortify - iFortifyScope = Fortify_EnterScope(); - Fortify_CheckAllMemory(); - */ - - /* - allocate data - */ - fHandle = (pNexusFunction)malloc(sizeof(NexusFunction)); - if (fHandle == NULL) { - NXReportError("ERROR: no memory to create Function structure"); - return NX_ERROR; - } - 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 - */ - fHandle->stripFlag = 1; - if(am & NXACC_NOSTRIP){ - fHandle->stripFlag = 0; - am = (NXaccess)(am & ~NXACC_NOSTRIP); - } - fHandle->checkNameSyntax = 0; - if (am & NXACC_CHECKNAMESYNTAX) { - fHandle->checkNameSyntax = 1; - am = (NXaccess)(am & ~NXACC_CHECKNAMESYNTAX); - } - - - if (my_am==NXACC_CREATE) { - /* HDF4 will be used ! */ - hdf_type=1; - filename = strdup(userfilename); - } else if (my_am==NXACC_CREATE4) { - /* HDF4 will be used ! */ - hdf_type=1; - filename = strdup(userfilename); - } else if (my_am==NXACC_CREATE5) { - /* HDF5 will be used ! */ - hdf_type=2; - filename = strdup(userfilename); - } else if (my_am==NXACC_CREATEXML) { - /* XML will be used ! */ - hdf_type=3; - filename = strdup(userfilename); - } else { - filename = locateNexusFileInPath((char *)userfilename); - if(filename == NULL){ - NXReportError("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); - NXReportError(error); - free(filename); - return NX_ERROR; - } - if(iRet == 0){ - snprintf(error,1023,"failed to determine filetype for %s ", - filename); - NXReportError(error); - free(filename); - free(fHandle); - return NX_ERROR; - } - hdf_type = iRet; - } - if(filename == NULL){ - NXReportError("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); - pushFileStack(fileStack,fHandle,filename); -#else - NXReportError( - "ERROR: Attempt to create HDF4 file when not linked with HDF4"); - retstat = NX_ERROR; -#endif /* HDF4 */ - free(filename); - return retstat; - } else if (hdf_type==2) { - /* HDF5 type */ -#ifdef HDF5 - retstat = NX5open(filename,am,&hdf5_handle); - if(retstat != NX_OK){ - free(fHandle); - free(filename); - return retstat; - } - fHandle->pNexusData=hdf5_handle; - NX5assignFunctions(fHandle); - pushFileStack(fileStack,fHandle, filename); -#else - NXReportError( - "ERROR: Attempt to create HDF5 file when not linked with HDF5"); - retstat = NX_ERROR; -#endif /* HDF5 */ - free(filename); - return retstat; - } else if(hdf_type == 3){ - /* - XML type - */ -#ifdef NXXML - retstat = NXXopen(filename,am,&xmlHandle); - if(retstat != NX_OK){ - free(fHandle); - free(filename); - return retstat; - } - fHandle->pNexusData=xmlHandle; - NXXassignFunctions(fHandle); - pushFileStack(fileStack,fHandle, filename); -#else - NXReportError( - "ERROR: Attempt to create XML file when not linked with XML"); - retstat = NX_ERROR; -#endif - } else { - NXReportError( - "ERROR: Format not readable by this NeXus library"); - retstat = NX_ERROR; - } - if (filename != NULL) { - free(filename); - } - return retstat; - } - -static NXstatus NXinternalopen(CONSTCHAR *userfilename, NXaccess am, pFileStack fileStack) -{ - return LOCKED_CALL(NXinternalopenImpl(userfilename, am, fileStack)); -} - - -NXstatus NXreopen(NXhandle pOrigHandle, NXhandle* pNewHandle) -{ - pFileStack newFileStack; - pFileStack origFileStack = (pFileStack)pOrigHandle; - pNexusFunction fOrigHandle = NULL, fNewHandle = NULL; - *pNewHandle = NULL; - newFileStack = makeFileStack(); - if(newFileStack == NULL){ - NXReportError ("ERROR: no memory to create filestack"); - return NX_ERROR; - } - // The code below will only open the last file on a stack - // for the moment raise an error, but this behaviour may be OK - if (fileStackDepth(origFileStack) > 0) - { - NXReportError ( - "ERROR: handle stack referes to many files - cannot reopen"); - return NX_ERROR; - } - fOrigHandle = peekFileOnStack(origFileStack); - if (fOrigHandle->nxreopen == NULL) - { - NXReportError ( - "ERROR: NXreopen not implemented for this underlying file format"); - return NX_ERROR; - } - fNewHandle = (NexusFunction*)malloc(sizeof(NexusFunction)); - memcpy(fNewHandle, fOrigHandle, sizeof(NexusFunction)); - LOCKED_CALL(fNewHandle->nxreopen( fOrigHandle->pNexusData, &(fNewHandle->pNexusData) )); - pushFileStack( newFileStack, fNewHandle, peekFilenameOnStack(origFileStack) ); - *pNewHandle = newFileStack; - return NX_OK; -} - - -/* ------------------------------------------------------------------------- */ - - NXstatus NXclose (NXhandle *fid) - { - NXhandle hfil; - int status; - pFileStack fileStack = NULL; - pNexusFunction pFunc=NULL; - if (*fid == NULL) - { - return NX_OK; - } - fileStack = (pFileStack)*fid; - pFunc = peekFileOnStack(fileStack); - hfil = pFunc->pNexusData; - status = LOCKED_CALL(pFunc->nxclose(&hfil)); - pFunc->pNexusData = hfil; - free(pFunc); - popFileStack(fileStack); - if(fileStackDepth(fileStack) < 0){ - killFileStack(fileStack); - *fid = NULL; - } - /* we can't set fid to NULL always as the handle points to a stack of files for external file support */ - /* - Fortify_CheckAllMemory(); - */ - - return status; - } - - /*-----------------------------------------------------------------------*/ - - NXstatus NXmakegroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) - { - char buffer[256]; - pNexusFunction pFunc = handleToNexusFunc(fid); - if ( pFunc->checkNameSyntax && (nxclass != NULL) /* && !strncmp("NX", nxclass, 2) */ && !validNXName(name, 0) ) - { - sprintf(buffer, "ERROR: invalid characters in group name \"%s\"", name); - NXReportError(buffer); - return NX_ERROR; - } - return LOCKED_CALL(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){ - NXReportError("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){ - NXReportError("ERROR: internal errro with external linking"); - return NXBADURL; - } - memcpy(extFile,pPtr,length); - length = strlen(path-1); - if(length > extPathLen){ - NXReportError("ERROR: internal error with external linking"); - return NXBADURL; - } - strcpy(extPath,path+1); - return NXFILE; - } - return NXBADURL; -} - /*------------------------------------------------------------------------*/ - - NXstatus NXopengroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) - { - int status, attStatus, type = NX_CHAR, length = 1023; - NXaccess access = NXACC_READ; - NXlink breakID; - pFileStack fileStack; - char nxurl[1024], exfile[512], expath[512]; - pNexusFunction pFunc = NULL; - - fileStack = (pFileStack)fid; - pFunc = handleToNexusFunc(fid); - - status = LOCKED_CALL(pFunc->nxopengroup(pFunc->pNexusData, name, nxclass)); - if(status == NX_OK){ - pushPath(fileStack,name); - } - NXMDisableErrorReporting(); - attStatus = NXgetattr(fid,"napimount",nxurl,&length, &type); - NXMEnableErrorReporting(); - 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) - { - int status; - pFileStack fileStack = NULL; - NXlink closeID, currentID; - - pNexusFunction pFunc = handleToNexusFunc(fid); - fileStack = (pFileStack)fid; - if(fileStackDepth(fileStack) == 0){ - status = LOCKED_CALL(pFunc->nxclosegroup(pFunc->pNexusData)); - if(status == NX_OK){ - popPath(fileStack); - } - return status; - } 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 = LOCKED_CALL(pFunc->nxclosegroup(pFunc->pNexusData)); - if(status == NX_OK){ - popPath(fileStack); - } - } - return status; - } - } - - /* --------------------------------------------------------------------- */ - - NXstatus NXmakedata (NXhandle fid, CONSTCHAR *name, int datatype, - int rank, int dimensions[]) - { - int status; - int64_t* dims64 = dupDimsArray(dimensions, rank); - status = NXmakedata64(fid, name, datatype, rank, dims64); - free(dims64); - return status; - } - - NXstatus NXmakedata64 (NXhandle fid, CONSTCHAR *name, int datatype, - int rank, int64_t dimensions[]) - { - char buffer[256]; - pNexusFunction pFunc = handleToNexusFunc(fid); - if ( pFunc->checkNameSyntax && !validNXName(name, 0) ) - { - sprintf(buffer, "ERROR: invalid characters in dataset name \"%s\"", name); - NXReportError(buffer); - return NX_ERROR; - } - return LOCKED_CALL(pFunc->nxmakedata64(pFunc->pNexusData, name, datatype, rank, dimensions)); - } - - /* --------------------------------------------------------------------- */ - - NXstatus NXcompmakedata (NXhandle fid, CONSTCHAR *name, int datatype, - int rank, int dimensions[], int compress_type, int chunk_size[]) - { - int status; - int64_t* dims64 = dupDimsArray(dimensions, rank); - int64_t* chunk64 = dupDimsArray(chunk_size, rank); - status = NXcompmakedata64(fid, name, datatype, rank, dims64, compress_type, chunk64); - free(dims64); - free(chunk64); - return status; - } - - NXstatus NXcompmakedata64 (NXhandle fid, CONSTCHAR *name, int datatype, - int rank, int64_t dimensions[], int compress_type, int64_t chunk_size[]) - { - char buffer[256]; - pNexusFunction pFunc = handleToNexusFunc(fid); - if ( pFunc->checkNameSyntax && !validNXName(name, 0) ) - { - sprintf(buffer, "ERROR: invalid characters in dataset name \"%s\"", name); - NXReportError(buffer); - return NX_ERROR; - } - return LOCKED_CALL(pFunc->nxcompmakedata64 (pFunc->pNexusData, name, datatype, rank, dimensions, compress_type, chunk_size)); - } - - /* --------------------------------------------------------------------- */ - - NXstatus NXcompress (NXhandle fid, int compress_type) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxcompress (pFunc->pNexusData, compress_type)); - } - - - /* --------------------------------------------------------------------- */ - - NXstatus NXopendata (NXhandle fid, CONSTCHAR *name) - { - int status, attStatus, type = NX_CHAR, length = 1023; - NXaccess access = NXACC_READ; - NXlink breakID; - pFileStack fileStack; - char nxurl[1024], exfile[512], expath[512]; - pNexusFunction pFunc = NULL; - - fileStack = (pFileStack)fid; - pFunc = handleToNexusFunc(fid); - status = LOCKED_CALL(pFunc->nxopendata(pFunc->pNexusData, name)); - - if(status == NX_OK){ - pushPath(fileStack,name); - } - - NXMDisableErrorReporting(); - attStatus = NXgetattr(fid,"napimount",nxurl,&length, &type); - NXMEnableErrorReporting(); - 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); - NXgetdataID(fid,&breakID); - setCloseID(fileStack,breakID); - } - - return status; - } - - /* ----------------------------------------------------------------- */ - - NXstatus NXclosedata (NXhandle fid) - { - int status; - pFileStack fileStack = NULL; - NXlink closeID, currentID; - - pNexusFunction pFunc = handleToNexusFunc(fid); - fileStack = (pFileStack)fid; - - if(fileStackDepth(fileStack) == 0){ - status = LOCKED_CALL(pFunc->nxclosedata(pFunc->pNexusData)); - if(status == NX_OK){ - popPath(fileStack); - } - return status; - } else { - /* we have to check for leaving an external file */ - NXgetdataID(fid,¤tID); - peekIDOnStack(fileStack,&closeID); - if(NXsameID(fid,&closeID,¤tID) == NX_OK){ - NXclose(&fid); - status = NXclosedata(fid); - } else { - status = LOCKED_CALL(pFunc->nxclosedata(pFunc->pNexusData)); - if(status == NX_OK){ - popPath(fileStack); - } - } - return status; - } - } - - /* ------------------------------------------------------------------- */ - - NXstatus NXputdata (NXhandle fid, const void *data) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxputdata(pFunc->pNexusData, data)); - } - - /* ------------------------------------------------------------------- */ - - NXstatus NXputattr (NXhandle fid, CONSTCHAR *name, const void *data, - int datalen, int iType) - { - char buffer[256]; - pNexusFunction pFunc = handleToNexusFunc(fid); - if (datalen > 1 && iType != NX_CHAR) - { - NXReportError("NXputattr: numeric arrays are not allowed as attributes - only character strings and single numbers"); - return NX_ERROR; - } - if ( pFunc->checkNameSyntax && !validNXName(name, 0) ) - { - sprintf(buffer, "ERROR: invalid characters in attribute name \"%s\"", name); - NXReportError(buffer); - return NX_ERROR; - } - return LOCKED_CALL(pFunc->nxputattr(pFunc->pNexusData, name, data, datalen, iType)); - } - - /* ------------------------------------------------------------------- */ - - NXstatus NXputslab (NXhandle fid, const void *data, const int iStart[], const int iSize[]) - { - int i, iType, rank; - int64_t iStart64[NX_MAXRANK], iSize64[NX_MAXRANK]; - if (NXgetinfo64(fid, &rank, iStart64, &iType) != NX_OK) - { - return NX_ERROR; - } - for(i=0; i < rank; ++i) - { - iStart64[i] = iStart[i]; - iSize64[i] = iSize[i]; - } - return NXputslab64(fid, data, iStart64, iSize64); - } - - NXstatus NXputslab64 (NXhandle fid, const void *data, const int64_t iStart[], const int64_t iSize[]) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxputslab64(pFunc->pNexusData, data, iStart, iSize)); - } - - /* ------------------------------------------------------------------- */ - - NXstatus NXgetdataID (NXhandle fid, NXlink* sRes) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxgetdataID(pFunc->pNexusData, sRes)); - } - - - /* ------------------------------------------------------------------- */ - - NXstatus NXmakelink (NXhandle fid, NXlink* sLink) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxmakelink(pFunc->pNexusData, sLink)); - } - /* ------------------------------------------------------------------- */ - - NXstatus NXmakenamedlink (NXhandle fid, CONSTCHAR *newname, NXlink* sLink) - { - char buffer[256]; - pNexusFunction pFunc = handleToNexusFunc(fid); - if ( pFunc->checkNameSyntax && !validNXName(newname, 0) ) - { - sprintf(buffer, "ERROR: invalid characters in link name \"%s\"", newname); - NXReportError(buffer); - return NX_ERROR; - } - return LOCKED_CALL(pFunc->nxmakenamedlink(pFunc->pNexusData, newname, sLink)); - } - /* --------------------------------------------------------------------*/ - NXstatus 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) - { - NXReportError("ERROR: item not linked"); - return NX_ERROR; - } - return NXopengrouppath(fid,target_path); - } - /*----------------------------------------------------------------------*/ - - NXstatus NXflush(NXhandle *pHandle) - { - NXhandle hfil; - pFileStack fileStack = NULL; - int status; - - pNexusFunction pFunc=NULL; - fileStack = (pFileStack)*pHandle; - pFunc = peekFileOnStack(fileStack); - hfil = pFunc->pNexusData; - status = LOCKED_CALL(pFunc->nxflush(&hfil)); - pFunc->pNexusData = hfil; - return status; - } - - - /*-------------------------------------------------------------------------*/ - - - NXstatus NXmalloc (void** data, int rank, - int dimensions[], int datatype) - { - int status; - int64_t* dims64 = dupDimsArray(dimensions, rank); - status = NXmalloc64(data, rank, dims64, datatype); - free(dims64); - return status; - } - - NXstatus NXmalloc64 (void** data, int rank, - int64_t dimensions[], int datatype) - { - int i; - size_t size = 1; - *data = NULL; - for(i=0; inxgetnextentry(pFunc->pNexusData, name, nxclass, datatype)); - } -/*----------------------------------------------------------------------*/ -/* -** TRIM.C - Remove leading, trailing, & excess embedded spaces -** -** public domain by Bob Stout -*/ -#define NUL '\0' - -char *nxitrim(char *str) -{ - char *ibuf = str; - int i = 0; - - /* - ** Trap NULL - */ - - if (str) - { - /* - ** Remove leading spaces (from RMLEAD.C) - */ - - for (ibuf = str; *ibuf && isspace(*ibuf); ++ibuf) - ; - str = ibuf; - - /* - ** Remove trailing spaces (from RMTRAIL.C) - */ - i = strlen(str); - while (--i >= 0) - { - if (!isspace(str[i])) - break; - } - str[++i] = NUL; - } - return str; -} - /*-------------------------------------------------------------------------*/ - - NXstatus NXgetdata (NXhandle fid, void *data) - { - int status, type, rank; - int64_t iDim[NX_MAXRANK]; - char *pPtr, *pPtr2; - - pNexusFunction pFunc = handleToNexusFunc(fid); - status = LOCKED_CALL(pFunc->nxgetinfo64(pFunc->pNexusData, &rank, iDim, &type)); /* unstripped size if string */ - /* only strip one dimensional strings */ - if ( (type == NX_CHAR) && (pFunc->stripFlag == 1) && (rank == 1) ) - { - pPtr = (char*)malloc(iDim[0]+5); - memset(pPtr, 0, iDim[0]+5); - status = LOCKED_CALL(pFunc->nxgetdata(pFunc->pNexusData, pPtr)); - pPtr2 = nxitrim(pPtr); - strncpy((char*)data, pPtr2, strlen(pPtr2)); /* not NULL terminated by default */ - free(pPtr); - } - else - { - status = LOCKED_CALL(pFunc->nxgetdata(pFunc->pNexusData, data)); - } - return status; - } -/*---------------------------------------------------------------------------*/ - NXstatus NXgetrawinfo64 (NXhandle fid, int *rank, - int64_t dimension[], int *iType) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxgetinfo64(pFunc->pNexusData, rank, dimension, iType)); - } - - NXstatus NXgetrawinfo (NXhandle fid, int *rank, - int dimension[], int *iType) - { - int i, status; - int64_t dims64[NX_MAXRANK]; - pNexusFunction pFunc = handleToNexusFunc(fid); - status = LOCKED_CALL(pFunc->nxgetinfo64(pFunc->pNexusData, rank, dims64, iType)); - for(i=0; i < *rank; ++i) - { - dimension[i] = dims64[i]; - } - return status; - } - /*-------------------------------------------------------------------------*/ - - NXstatus NXgetinfo (NXhandle fid, int *rank, - int dimension[], int *iType) - { - int i, status; - int64_t dims64[NX_MAXRANK]; - status = NXgetinfo64(fid, rank, dims64, iType); - for(i=0; i < *rank; ++i) - { - dimension[i] = dims64[i]; - } - return status; - } - - NXstatus NXgetinfo64 (NXhandle fid, int *rank, - int64_t dimension[], int *iType) - { - int status; - char *pPtr = NULL; - pNexusFunction pFunc = handleToNexusFunc(fid); - *rank = 0; - status = LOCKED_CALL(pFunc->nxgetinfo64(pFunc->pNexusData, rank, dimension, iType)); - /* - the length of a string may be trimmed.... - */ - /* 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)); - LOCKED_CALL(pFunc->nxgetdata(pFunc->pNexusData, pPtr)); - dimension[0] = strlen(nxitrim(pPtr)); - free(pPtr); - } - } - return status; - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NXgetslab (NXhandle fid, void *data, - int iStart[], int iSize[]) - { - int i, iType, rank; - int64_t iStart64[NX_MAXRANK], iSize64[NX_MAXRANK]; - if (NXgetinfo64(fid, &rank, iStart64, &iType) != NX_OK) - { - return NX_ERROR; - } - for(i=0; i < rank; ++i) - { - iStart64[i] = iStart[i]; - iSize64[i] = iSize[i]; - } - return NXgetslab64(fid, data, iStart64, iSize64); - } - - NXstatus NXgetslab64 (NXhandle fid, void *data, - const int64_t iStart[], const int64_t iSize[]) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxgetslab64(pFunc->pNexusData, data, iStart, iSize)); - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NXgetnextattr (NXhandle fileid, NXname pName, - int *iLength, int *iType) - { - pNexusFunction pFunc = handleToNexusFunc(fileid); - return LOCKED_CALL(pFunc->nxgetnextattr(pFunc->pNexusData, pName, iLength, iType)); - } - - - /*-------------------------------------------------------------------------*/ - - NXstatus NXgetattr (NXhandle fid, char *name, void *data, int* datalen, int* iType) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxgetattr(pFunc->pNexusData, name, data, datalen, iType)); - } - - - /*-------------------------------------------------------------------------*/ - - NXstatus NXgetattrinfo (NXhandle fid, int *iN) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxgetattrinfo(pFunc->pNexusData, iN)); - } - - - /*-------------------------------------------------------------------------*/ - - NXstatus NXgetgroupID (NXhandle fileid, NXlink* sRes) - { - pNexusFunction pFunc = handleToNexusFunc(fileid); - return LOCKED_CALL(pFunc->nxgetgroupID(pFunc->pNexusData, sRes)); - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NXgetgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxgetgroupinfo(pFunc->pNexusData, iN, pName, pClass)); - } - - - /*-------------------------------------------------------------------------*/ - - NXstatus NXsameID (NXhandle fileid, NXlink* pFirstID, NXlink* pSecondID) - { - pNexusFunction pFunc = handleToNexusFunc(fileid); - return LOCKED_CALL(pFunc->nxsameID(pFunc->pNexusData, pFirstID, pSecondID)); - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NXinitattrdir (NXhandle fid) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxinitattrdir(pFunc->pNexusData)); - } - /*-------------------------------------------------------------------------*/ - - NXstatus NXsetnumberformat (NXhandle fid, - int type, char *format) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - if(pFunc->nxsetnumberformat != NULL) - { - return LOCKED_CALL(pFunc->nxsetnumberformat(pFunc->pNexusData,type,format)); - } - else - { - /* - silently ignore this. Most NeXus file formats do not require - this - */ - return NX_OK; - } - } - - - /*-------------------------------------------------------------------------*/ - - NXstatus NXinitgroupdir (NXhandle fid) - { - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxinitgroupdir(pFunc->pNexusData)); - } -/*----------------------------------------------------------------------*/ - NXstatus NXinquirefile(NXhandle handle, char *filename, - int filenameBufferLength){ - pFileStack fileStack; - char *pPtr = NULL; - int length, status; - - pNexusFunction pFunc = handleToNexusFunc(handle); - if (pFunc->nxnativeinquirefile != NULL) { - - status = LOCKED_CALL(pFunc->nxnativeinquirefile(pFunc->pNexusData, filename, filenameBufferLength)); - if (status < 0) { - return NX_ERROR; - } else { - return NX_OK; - } - - } - - 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 *nxclass, - char *url, int urlLen){ - int status, attStatus, length = 1023, type = NX_CHAR; - char nxurl[1024]; - - pNexusFunction pFunc = handleToNexusFunc(fid); - - if (pFunc->nxnativeisexternallink != NULL) { - status = LOCKED_CALL(pFunc->nxnativeisexternallink(pFunc->pNexusData, name, url, urlLen)); - if (status == NX_OK) { - return NX_OK; - } - // need to continue, could still be old style link - } - - status = LOCKED_CALL(pFunc->nxopengroup(pFunc->pNexusData, name, nxclass)); - if(status != NX_OK){ - return status; - } - NXMDisableErrorReporting(); - attStatus = NXgetattr(fid,"napimount",nxurl,&length, &type); - NXMEnableErrorReporting(); - LOCKED_CALL(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 NXisexternaldataset(NXhandle fid, CONSTCHAR *name, - char *url, int urlLen){ - int status, attStatus, length = 1023, type = NX_CHAR; - char nxurl[1024]; - - pNexusFunction pFunc = handleToNexusFunc(fid); - - if (pFunc->nxnativeisexternallink != NULL) { - status = LOCKED_CALL(pFunc->nxnativeisexternallink(pFunc->pNexusData, name, url, urlLen)); - if (status == NX_OK) { - return NX_OK; - } - // need to continue, could still be old style link - } - - status = LOCKED_CALL(pFunc->nxopendata(pFunc->pNexusData, name)); - if(status != NX_OK){ - return status; - } - NXMDisableErrorReporting(); - attStatus = NXgetattr(fid,"napimount",nxurl,&length, &type); - NXMEnableErrorReporting(); - LOCKED_CALL(pFunc->nxclosedata(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 *nxclass, CONSTCHAR *url) { - int status, type = NX_CHAR, length=1024, urllen; - char nxurl[1024], exfile[512], expath[512]; - pNexusFunction pFunc = handleToNexusFunc(fid); - - // in HDF5 we support external linking natively - if (pFunc->nxnativeexternallink != NULL) { - urllen = strlen(url); - memset(nxurl, 0, length); - if(urllen >= length){ - urllen = length - 1; - } - memcpy(nxurl, url, urllen); - status = analyzeNapimount(nxurl,exfile,511,expath,511); - if(status != NX_OK){ - return status; - } - status = LOCKED_CALL(pFunc->nxnativeexternallink(pFunc->pNexusData, name, exfile, expath)); - if(status != NX_OK){ - return status; - } - return NX_OK; - } - - NXMDisableErrorReporting(); - LOCKED_CALL(pFunc->nxmakegroup(pFunc->pNexusData,name,nxclass)); - NXMEnableErrorReporting(); - - status = LOCKED_CALL(pFunc->nxopengroup(pFunc->pNexusData,name,nxclass)); - if(status != NX_OK){ - return status; - } - length = strlen(url); - status = NXputattr(fid, "napimount",url,length, type); - if(status != NX_OK){ - return status; - } - LOCKED_CALL(pFunc->nxclosegroup(pFunc->pNexusData)); - return NX_OK; -} -/*------------------------------------------------------------------------*/ -NXstatus NXlinkexternaldataset(NXhandle fid, CONSTCHAR *name, - CONSTCHAR *url){ - int status, type = NX_CHAR, length=1024, urllen; - char nxurl[1024], exfile[512], expath[512]; - pNexusFunction pFunc = handleToNexusFunc(fid); - int rank = 1; - int64_t dims[1] = {1}; - - //TODO cut and paste - - // in HDF5 we support external linking natively - if (pFunc->nxnativeexternallink != NULL) { - urllen = strlen(url); - memset(nxurl, 0, length); - if(urllen > length){ - urllen = length - 1; - } - memcpy(nxurl, url, urllen); - status = analyzeNapimount(nxurl,exfile,511,expath,511); - if(status != NX_OK){ - return status; - } - status = LOCKED_CALL(pFunc->nxnativeexternallink(pFunc->pNexusData, name, exfile, expath)); - if(status != NX_OK){ - return status; - } - return NX_OK; - } - - - status = LOCKED_CALL(pFunc->nxmakedata64(pFunc->pNexusData, name, NX_CHAR, rank, dims)); - if(status != NX_OK){ - return status; - } - status = LOCKED_CALL(pFunc->nxopendata(pFunc->pNexusData, name)); - if(status != NX_OK){ - return status; - } - length = strlen(url); - status = NXputattr(fid, "napimount",url,length, type); - if(status != NX_OK){ - return status; - } - LOCKED_CALL(pFunc->nxclosedata(pFunc->pNexusData)); - return NX_OK; -} -/*------------------------------------------------------------------------ - Implementation of NXopenpath - --------------------------------------------------------------------------*/ -static int isDataSetOpen(NXhandle hfil) -{ - NXlink id; - - /* - This uses the (sensible) feauture that NXgetdataID returns NX_ERROR - when no dataset is open - */ - if(NXgetdataID(hfil,&id) == NX_ERROR) - { - return 0; - } - else - { - return 1; - } -} -/*----------------------------------------------------------------------*/ -static int isRoot(NXhandle hfil) -{ - NXlink id; - - /* - This uses the feauture that NXgetgroupID returns NX_ERROR - when we are at root level - */ - if(NXgetgroupID(hfil,&id) == NX_ERROR) - { - return 1; - } - else - { - return 0; - } -} -/*-------------------------------------------------------------------- - copies the next path element into element. - returns a pointer into path beyond the extracted path - ---------------------------------------------------------------------*/ -static char *extractNextPath(char *path, NXname element) -{ - char *pPtr, *pStart; - int length; - - pPtr = path; - /* - skip over leading / - */ - if(*pPtr == '/') - { - pPtr++; - } - pStart = pPtr; - - /* - find next / - */ - pPtr = strchr(pStart,'/'); - if(pPtr == NULL) - { - /* - this is the last path element - */ - strcpy(element,pStart); - return NULL; - } else { - length = pPtr - pStart; - strncpy(element,pStart,length); - element[length] = '\0'; - } - return pPtr + 1; -} -/*-------------------------------------------------------------------*/ -static NXstatus gotoRoot(NXhandle hfil) -{ - int status; - - if(isDataSetOpen(hfil)) - { - status = NXclosedata(hfil); - if(status == NX_ERROR) - { - return status; - } - } - while(!isRoot(hfil)) - { - status = NXclosegroup(hfil); - if(status == NX_ERROR) - { - return status; - } - } - return NX_OK; -} -/*--------------------------------------------------------------------*/ -static int isRelative(char *path) -{ - if(path[0] == '.' && path[1] == '.') - return 1; - else - return 0; -} -/*------------------------------------------------------------------*/ -static NXstatus moveOneDown(NXhandle hfil) -{ - if(isDataSetOpen(hfil)) - { - return NXclosedata(hfil); - } - else - { - return NXclosegroup(hfil); - } -} -/*------------------------------------------------------------------- - returns a pointer to the remaining path string to move up - --------------------------------------------------------------------*/ -static char *moveDown(NXhandle hfil, char *path, int *code) -{ - int status; - char *pPtr; - - *code = NX_OK; - - if(path[0] == '/') - { - *code = gotoRoot(hfil); - return path; - } - else - { - pPtr = path; - while(isRelative(pPtr)) - { - status = moveOneDown(hfil); - if(status == NX_ERROR) - { - *code = status; - return pPtr; - } - pPtr += 3; - } - return pPtr; - } -} -/*--------------------------------------------------------------------*/ -static NXstatus stepOneUp(NXhandle hfil, char *name) -{ - int datatype; - NXname name2, xclass; - char pBueffel[256]; - - /* - catch the case when we are there: i.e. no further stepping - necessary. This can happen with paths like ../ - */ - if (strlen(name) < 1) { - return NX_OK; - } - - NXinitgroupdir(hfil); - - while(NXgetnextentry(hfil, name2, xclass, &datatype) != NX_EOD) - { - if(strcmp(name2,name) == 0) - { - if(strcmp(xclass,"SDS") == 0) - { - return NXopendata(hfil,name); - } else { - return NXopengroup(hfil,name,xclass); - } - } - } - snprintf(pBueffel,255,"ERROR: NXopenpath cannot step into %s",name); - NXReportError( pBueffel); - return NX_ERROR; -} -/*--------------------------------------------------------------------*/ -static NXstatus stepOneGroupUp(NXhandle hfil, char *name) -{ - int 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); - NXReportError( pBueffel); - return NX_ERROR; -} -/*---------------------------------------------------------------------*/ -NXstatus NXopenpath(NXhandle hfil, CONSTCHAR *path) -{ - int status, run = 1; - NXname pathElement; - char *pPtr; - - if(hfil == NULL || path == NULL) - { - NXReportError( - "ERROR: NXopendata needs both a file handle and a path string"); - return NX_ERROR; - } - - pPtr = moveDown(hfil,(char *)path,&status); - if(status != NX_OK) - { - NXReportError( - "ERROR: NXopendata failed to move down in hierarchy"); - return status; - } - - while(run == 1) - { - pPtr = extractNextPath(pPtr, pathElement); - status = stepOneUp(hfil,pathElement); - if(status != NX_OK) - { - return status; - } - if(pPtr == NULL) - { - run = 0; - } - } - return NX_OK; -} -/*---------------------------------------------------------------------*/ -NXstatus NXopengrouppath(NXhandle hfil, CONSTCHAR *path) -{ - int status, run = 1; - NXname pathElement; - char *pPtr; - - if(hfil == NULL || path == NULL) - { - NXReportError( - "ERROR: NXopendata needs both a file handle and a path string"); - return NX_ERROR; - } - - pPtr = moveDown(hfil,(char *)path,&status); - if(status != NX_OK) - { - NXReportError( - "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; -} -/*---------------------------------------------------------------------*/ -NXstatus NXIprintlink(NXhandle fid, NXlink* link) -{ - pNexusFunction pFunc = handleToNexusFunc(fid); - return LOCKED_CALL(pFunc->nxprintlink(pFunc->pNexusData, link)); -} -/*----------------------------------------------------------------------*/ -NXstatus NXgetpath(NXhandle fid, char *path, int pathlen){ - int status; - pFileStack fileStack = NULL; - - fileStack = (pFileStack)fid; - status = buildPath(fileStack,path,pathlen); - if(status != 1){ - return NX_ERROR; - } - return NX_OK; -} - -/*-------------------------------------------------------------------- - format NeXus time. Code needed in every NeXus file driver - ---------------------------------------------------------------------*/ -char *NXIformatNeXusTime(){ - 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){ - NXReportError("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 - { - NXReportError( - "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-%02dT%02d:%02d:%02d-%02d:%02d"; - } - else - { - time_format = "%04d-%02d-%02dT%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-01T00:00:00+00:00"); - } - return time_buffer; -} -/*---------------------------------------------------------------------- - 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 NXfopen(char * filename, NXaccess* am, - NXhandle pHandle) - { - NXstatus ret; - NXhandle fileid = NULL; - ret = NXopen(filename, *am, &fileid); - if (ret == NX_OK) - { - memcpy(pHandle, fileid, getFileStackSize()); - } - else - { - memset(pHandle, 0, getFileStackSize()); - } - 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 NXfclose (NXhandle pHandle) - { - NXhandle h; - NXstatus ret; - h = (NXhandle)malloc(getFileStackSize()); - memcpy(h, pHandle, getFileStackSize()); - ret = NXclose(&h); /* does free(h) */ - memset(pHandle, 0, getFileStackSize()); - return ret; - } - -/*---------------------------------------------------------------------*/ - NXstatus NXfflush(NXhandle pHandle) - { - NXhandle h; - NXstatus ret; - h = (NXhandle)malloc(getFileStackSize()); - memcpy(h, pHandle, getFileStackSize()); - ret = NXflush(&h); /* modifies and reallocates h */ - memcpy(pHandle, h, getFileStackSize()); - return ret; - } -/*----------------------------------------------------------------------*/ - NXstatus 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); - NXReportError( 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 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); - NXReportError( 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 NXfcompress(NXhandle fid, int *compr_type) - { - return NXcompress(fid,*compr_type); - } -/*-----------------------------------------------------------------------*/ - NXstatus NXfputattr(NXhandle fid, const char *name, const void *data, - int *pDatalen, int *pIType) - { - 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; - } - -/*--------------------------------------------------------------------------*/ -NXstatus NXfgetpath(NXhandle fid, char *path, int *pathlen) -{ - return NXgetpath(fid,path,*pathlen); -} - -const char* NXgetversion() -{ - return NEXUS_VERSION ; -} - diff --git a/napi.h b/napi.h deleted file mode 100644 index b7d3e1c9..00000000 --- a/napi.h +++ /dev/null @@ -1,959 +0,0 @@ -/*--------------------------------------------------------------------------- - NeXus - Neutron & X-ray Common Data Format - - Application Program Interface Header File - - Copyright (C) 2000-2011 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 - 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 - - $Id: napi.h,v 1.14 2012/03/29 08:41:06 koennecke Exp $ - - ----------------------------------------------------------------------------*/ -/** \file - * Documentation for the NeXus-API version 4.3 - * 2000-2011, the NeXus International Advisory Commitee - * \defgroup c_main C API - * \defgroup c_types Data Types - * \ingroup c_main - * \defgroup c_init General Initialisation and shutdown - * \ingroup c_main - * \defgroup c_group Reading and Writing Groups - * \ingroup c_main - * \defgroup c_readwrite Reading and Writing Data - * \ingroup c_main - * \defgroup c_navigation General File navigation - * \ingroup c_main - * \defgroup c_metadata Meta data routines - * \ingroup c_main - * \defgroup c_linking Linking - * \ingroup c_main - * \defgroup c_memory Memory allocation - * \ingroup c_main - * \defgroup c_external External linking - * \ingroup c_main - */ - -#ifndef NEXUSAPI -#define NEXUSAPI - -#include - -/* NeXus HDF45 */ -#define NEXUS_VERSION "4.3.0" /* major.minor.patch */ - -#define CONSTCHAR const char - -typedef void* NXhandle; /* really a pointer to a NexusFile structure */ -typedef int NXstatus; -typedef char NXname[128]; - -/* - * Any new NXaccess_mode options should be numbered in 2^n format - * (8, 16, 32, etc) so that they can be bit masked and tested easily. - * - * To test older non bit masked options (values below 8) use e.g. - * - * if ( (mode & NXACCMASK_REMOVEFLAGS) == NXACC_CREATE ) - * - * To test new (>=8) options just use normal bit masking e.g. - * - * if ( mode & NXACC_NOSTRIP ) - * - */ -#define NXACCMASK_REMOVEFLAGS (0x7) /* bit mask to remove higher flag options */ - -/** \enum NXaccess_mode - * NeXus file access codes. - * \li NXACC_READ read-only - * \li NXACC_RDWR open an existing file for reading and writing. - * \li NXACC_CREATE create a NeXus HDF-4 file - * \li NXACC_CREATE4 create a NeXus HDF-4 file - * \li NXACC_CREATE5 create a NeXus HDF-5 file. - * \li NXACC_CREATEXML create a NeXus XML file. - * \li NXACC_CHECKNAMESYNTAX Check names conform to NeXus allowed characters. - */ -typedef enum {NXACC_READ=1, NXACC_RDWR=2, NXACC_CREATE=3, NXACC_CREATE4=4, - NXACC_CREATE5=5, NXACC_CREATEXML=6, NXACC_TABLE=8, NXACC_NOSTRIP=128, NXACC_CHECKNAMESYNTAX=256 } NXaccess_mode; - -/** - * A combination of options from #NXaccess_mode - */ -typedef int NXaccess; - -typedef struct { - char *iname; - int type; - }info_type, *pinfo; - -#define NX_OK 1 -#define NX_ERROR 0 -#define NX_EOD -1 - -#define NX_UNLIMITED -1 - -#define NX_MAXRANK 32 -#define NX_MAXNAMELEN 64 -#define NX_MAXPATHLEN 1024 - - -/** - * \ingroup c_types - * \def NX_FLOAT32 - * 32 bit float - * \def NX_FLOAT64 - * 64 bit float == double - * \def NX_INT8 - * 8 bit integer == byte - * \def NX_UINT8 - * 8 bit unsigned integer - * \def NX_INT16 - * 16 bit integer - * \def NX_UINT16 - * 16 bit unsigned integer - * \def NX_INT32 - * 32 bit integer - * \def NX_UINT32 - * 32 bit unsigned integer - * \def NX_CHAR - * 8 bit character - * \def NX_BINARY - * lump of binary data == NX_UINT8 -*/ -/*--------------------------------------------------------------------------*/ - -/* Map NeXus to HDF types */ -#define NX_FLOAT32 5 -#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 -#define NX_UINT32 25 -#define NX_INT64 26 -#define NX_UINT64 27 -#define NX_CHAR 4 -#define NX_BINARY 21 - -/* Map NeXus compression methods to HDF compression methods */ -#define NX_CHUNK 0 -#define NX_COMP_NONE 100 -#define NX_COMP_LZW 200 -#define NX_COMP_RLE 300 -#define NX_COMP_HUF 400 - -/* to test for these we use ((value / 100) == NX_COMP_LZW) */ -#define NX_COMP_LZW_LVL0 (100*NX_COMP_LZW + 0) -#define NX_COMP_LZW_LVL1 (100*NX_COMP_LZW + 1) -#define NX_COMP_LZW_LVL2 (100*NX_COMP_LZW + 2) -#define NX_COMP_LZW_LVL3 (100*NX_COMP_LZW + 3) -#define NX_COMP_LZW_LVL4 (100*NX_COMP_LZW + 4) -#define NX_COMP_LZW_LVL5 (100*NX_COMP_LZW + 5) -#define NX_COMP_LZW_LVL6 (100*NX_COMP_LZW + 6) -#define NX_COMP_LZW_LVL7 (100*NX_COMP_LZW + 7) -#define NX_COMP_LZW_LVL8 (100*NX_COMP_LZW + 8) -#define NX_COMP_LZW_LVL9 (100*NX_COMP_LZW + 9) - -typedef struct { - long iTag; /* HDF4 variable */ - long iRef; /* HDF4 variable */ - char targetPath[1024]; /* path to item to link */ - int linkType; /* HDF5: 0 for group link, 1 for SDS link */ - } NXlink; - -#define NXMAXSTACK 50 - -#define CONCAT(__a,__b) __a##__b /* token concatenation */ - -# ifdef __VMS -# define MANGLE(__arg) __arg -# else -# define MANGLE(__arg) CONCAT(__arg,_) -# endif - -# define NXopen MANGLE(nxiopen) -# define NXreopen MANGLE(nxireopen) -# define NXclose MANGLE(nxiclose) -# define NXmakegroup MANGLE(nximakegroup) -# define NXopengroup MANGLE(nxiopengroup) -# define NXopenpath MANGLE(nxiopenpath) -# define NXgetpath MANGLE(nxigetpath) -# define NXopengrouppath MANGLE(nxiopengrouppath) -# define NXclosegroup MANGLE(nxiclosegroup) -# define NXmakedata MANGLE(nximakedata) -# define NXmakedata64 MANGLE(nximakedata64) -# define NXcompmakedata MANGLE(nxicompmakedata) -# define NXcompmakedata64 MANGLE(nxicompmakedata64) -# define NXcompress MANGLE(nxicompress) -# define NXopendata MANGLE(nxiopendata) -# define NXclosedata MANGLE(nxiclosedata) -# define NXputdata MANGLE(nxiputdata) -# define NXputslab MANGLE(nxiputslab) -# define NXputslab64 MANGLE(nxiputslab64) -# 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 NXmalloc64 MANGLE(nximalloc64) -# define NXfree MANGLE(nxifree) -# define NXflush MANGLE(nxiflush) - -# define NXgetinfo MANGLE(nxigetinfo) -# define NXgetinfo64 MANGLE(nxigetinfo64) -# define NXgetrawinfo MANGLE(nxigetrawinfo) -# define NXgetrawinfo64 MANGLE(nxigetrawinfo64) -# define NXgetnextentry MANGLE(nxigetnextentry) -# define NXgetdata MANGLE(nxigetdata) - -# define NXgetslab MANGLE(nxigetslab) -# define NXgetslab64 MANGLE(nxigetslab64) -# define NXgetnextattr MANGLE(nxigetnextattr) -# define NXgetattr MANGLE(nxigetattr) -# define NXgetattrinfo MANGLE(nxigetattrinfo) -# define NXgetgroupID MANGLE(nxigetgroupid) -# define NXgetgroupinfo MANGLE(nxigetgroupinfo) -# define NXsameID MANGLE(nxisameid) -# define NXinitgroupdir MANGLE(nxiinitgroupdir) -# define NXinitattrdir MANGLE(nxiinitattrdir) -# define NXsetnumberformat MANGLE(nxisetnumberformat) -# define NXsetcache MANGLE(nxisetcache) -# define NXinquirefile MANGLE(nxiinquirefile) -# define NXisexternalgroup MANGLE(nxiisexternalgroup) -# define NXisexternaldataset MANGLE(nxiisexternaldataset) -# define NXlinkexternal MANGLE(nxilinkexternal) -# define NXlinkexternaldataset MANGLE(nxilinkexternaldataset) -# define NXgetversion MANGLE(nxigetversion) - -/* - * FORTRAN helpers - for NeXus internal use only - */ -# define NXfopen MANGLE(nxifopen) -# define NXfclose MANGLE(nxifclose) -# define NXfflush MANGLE(nxifflush) -# define NXfmakedata MANGLE(nxifmakedata) -# define NXfcompmakedata MANGLE(nxifcompmakedata) -# define NXfcompress MANGLE(nxifcompress) -# define NXfputattr MANGLE(nxifputattr) -# define NXfgetpath MANGLE(nxifgetpath) - -/* - * 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 -extern "C" { -#endif /* __cplusplus */ - /** - * Open a NeXus file. - * NXopen honours full path file names. But it also searches - * for files in all the paths given in the NX_LOAD_PATH environment variable. - * NX_LOAD_PATH is supposed to hold a list of path string separated by the platform - * specific path separator. For unix this is the : , for DOS the ; . Please note - * that crashing on an open NeXus file will result in corrupted data. Only after a NXclose - * or a NXflush will the data file be valid. - * \param filename The name of the file to open - * \param access_method The file access method. This can be: - * \li NXACC__READ read access - * \li NXACC_RDWR read write access - * \li NXACC_CREATE, NXACC_CREATE4 create a new HDF-4 NeXus file - * \li NXACC_CREATE5 create a new HDF-5 NeXus file - * \li NXACC_CREATEXML create an XML NeXus file. - * see #NXaccess_mode - * Support for HDF-4 is deprecated. - * \param pHandle A file handle which will be initialized upon successfull completeion of NXopen. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_init - */ -extern NXstatus NXopen(CONSTCHAR * filename, NXaccess access_method, NXhandle* pHandle); - - /** - * Opens an existing NeXus file a second time for e.g. access from another thread. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_init - */ -extern NXstatus NXreopen(NXhandle pOrigHandle, NXhandle* pNewHandle); - - /** - * close a NeXus file - * \param pHandle A NeXus file handle as returned from NXopen. pHandle is invalid after this - * call. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_init - */ -extern NXstatus NXclose(NXhandle* pHandle); - - /** - * flush data to disk - * \param pHandle A NeXus file handle as initialized by NXopen. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_readwrite - */ -extern NXstatus NXflush(NXhandle* pHandle); - - /** - * NeXus groups are NeXus way of structuring information into a hierarchy. - * This function creates a group but does not open it. - * \param handle A NeXus file handle as initialized NXopen. - * \param name The name of the group - * \param NXclass the class name of the group. Should start with the prefix NX - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_group - */ -extern NXstatus NXmakegroup (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass); - - /** - * Step into a group. All further access will be within the opened group. - * \param handle A NeXus file handle as initialized by NXopen. - * \param name The name of the group - * \param NXclass the class name of the group. Should start with the prefix NX - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_group - */ -extern NXstatus NXopengroup (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass); - - /** - * Open the NeXus object with the path specified - * \param handle A NeXus file handle as returned from NXopen. - * \param path A unix like path string to a NeXus group or dataset. The path string - * is a list of group names and SDS names separated with / (slash). - * Example: /entry1/sample/name - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_navigation - */ -extern NXstatus NXopenpath (NXhandle handle, CONSTCHAR *path); - - /** - * Opens the group in which the NeXus object with the specified path exists - * \param handle A NeXus file handle as initialized by NXopen. - * \param path A unix like path string to a NeXus group or dataset. The path string - * is a list of group names and SDS names separated with / (slash). - * Example: /entry1/sample/name - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_navigation - */ -extern NXstatus NXopengrouppath (NXhandle handle, CONSTCHAR *path); - - /** - * Retrieve the current path in the NeXus file - * \param handle a NeXus file handle - * \param path A buffer to copy the path too - * \param pathlen The maximum number of characters to copy into path - * \return NX_OK or NX_ERROR - * \ingroup c_navigation - */ -extern NXstatus NXgetpath(NXhandle handle, char *path, int pathlen); - - /** - * Closes the currently open group and steps one step down in the NeXus file - * hierarchy. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_group - */ -extern NXstatus NXclosegroup(NXhandle handle); - - /** - * Create a multi dimensional data array or dataset. The dataset is NOT opened. - * \param handle A NeXus file handle as initialized by NXopen. - * \param label The name of the dataset - * \param datatype The data type of this data set. - * \param rank The number of dimensions this dataset is going to have - * \param dim An array of size rank holding the size of the dataset in each dimension. The first dimension - * can be NX_UNLIMITED. Data can be appended to such a dimension using NXputslab. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_readwrite - */ -extern NXstatus NXmakedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[]); - - - /** - * @copydoc NXmakedata() - */ -extern NXstatus NXmakedata64 (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[]); - - -/** - * Create a compressed dataset. The dataset is NOT opened. Data from this set will automatically be compressed when - * writing and decompressed on reading. - * \param handle A NeXus file handle as initialized by NXopen. - * \param label The name of the dataset - * \param datatype The data type of this data set. - * \param rank The number of dimensions this dataset is going to have - * \param comp_typ The compression scheme to use. Possible values: - * \li NX_COMP_NONE no compression - * \li NX_COMP_LZW lossless Lempel Ziv Welch compression (recommended) - * \li NX_COMP_RLE run length encoding (only HDF-4) - * \li NX_COMP_HUF Huffmann encoding (only HDF-4) - * \param dim An array of size rank holding the size of the dataset in each dimension. The first dimension - * can be NX_UNLIMITED. Data can be appended to such a dimension using NXputslab. - * \param bufsize The dimensions of the subset of the data which usually be writen in one go. - * This is a parameter used by HDF for performance optimisations. If you write your data in one go, this - * should be the same as the data dimension. If you write it in slabs, this is your preferred slab size. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_readwrite - */ -extern NXstatus NXcompmakedata (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int dim[], int comp_typ, int bufsize[]); - - -/** - * @copydoc NXcompmakedata() - */ -extern NXstatus NXcompmakedata64 (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[], int comp_typ, int64_t chunk_size[]); - - - /** - * Switch compression on. This routine is superseeded by NXcompmakedata and thus - * is deprecated. - * \param handle A NeXus file handle as initialized by NXopen. - * \param compr_type The compression scheme to use. Possible values: - * \li NX_COMP_NONE no compression - * \li NX_COMP_LZW lossless Lempel Ziv Welch compression (recommended) - * \li NX_COMP_RLE run length encoding (only HDF-4) - * \li NX_COMP_HUF Huffmann encoding (only HDF-4) - * \ingroup c_readwrite - */ -extern NXstatus NXcompress (NXhandle handle, int compr_type); - - /** - * Open access to a dataset. After this call it is possible to write and read data or - * attributes to and from the dataset. - * \param handle A NeXus file handle as initialized by NXopen. - * \param label The name of the dataset - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_readwrite - */ -extern NXstatus NXopendata (NXhandle handle, CONSTCHAR* label); - - /** - * Close access to a dataset. - * \param handle A NeXus file handle as initialized by NXopen. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_readwrite - */ -extern NXstatus NXclosedata(NXhandle handle); - - /** - * Write data to a datset which has previouly been opened with NXopendata. - * This writes all the data in one go. Data should be a pointer to a memory - * area matching the datatype and dimensions of the dataset. - * \param handle A NeXus file handle as initialized by NXopen. - * \param data Pointer to data to write. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_readwrite - */ -extern NXstatus NXputdata(NXhandle handle, const void* data); - - /** - * Write an attribute. The kind of attribute written depends on the - * poistion in the file: at root level, a global attribute is written, if - * agroup is open but no dataset, a group attribute is written, if a dataset is - * open, a dataset attribute is written. - * \param handle A NeXus file handle as initialized by NXopen. - * \param name The name of the attribute. - * \param data A pointer to the data to write for the attribute. - * \param iDataLen The length of the data in data in bytes. - * \param iType The NeXus data type of the attribute. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_readwrite - */ -extern NXstatus NXputattr(NXhandle handle, CONSTCHAR* name, const void* data, int iDataLen, int iType); - - /** - * Write a subset of a multi dimensional dataset. - * \param handle A NeXus file handle as initialized by NXopen. - * \param data A pointer to a memory area holding the data to write. - * \param start An array holding the start indices where to start the data subset. - * \param size An array holding the size of the data subset to write in each dimension. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_readwrite - */ -extern NXstatus NXputslab(NXhandle handle, const void* data, const int start[], const int size[]); - - /** - * @copydoc NXputdata() - */ -extern NXstatus NXputslab64(NXhandle handle, const void* data, const int64_t start[], const int64_t size[]); - - /** - * Retrieve link data for a dataset. This link data can later on be used to link this - * dataset into a different group. - * \param handle A NeXus file handle as initialized by NXopen. - * \param pLink A link data structure which will be initialized with the required information - * for linking. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_linking - */ -extern NXstatus NXgetdataID(NXhandle handle, NXlink* pLink); - - /** - * Create a link to the group or dataset described by pLink in the currently open - * group. - * \param handle A NeXus file handle as initialized by NXopen. - * \param pLink A link data structure describing the object to link. This must have been initialized - * by either a call to NXgetdataID or NXgetgroupID. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_linking - */ -extern NXstatus NXmakelink(NXhandle handle, NXlink* pLink); - - /** - * Create a link to the group or dataset described by pLink in the currently open - * group. But give the linked item a new name. - * \param handle A NeXus file handle as initialized by NXopen. - * \param newname The new name of the item in the currently open group. - * \param pLink A link data structure describing the object to link. This must have been initialized - * by either a call to NXgetdataID or NXgetgroupID. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_linking - */ -extern NXstatus NXmakenamedlink(NXhandle handle, CONSTCHAR* newname, NXlink* pLink); - - /** - * Open the source group of a linked group or dataset. Returns an error when the item is - * not a linked item. - * \param handle A NeXus file handle as initialized by NXopen. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_navigation - */ -extern NXstatus NXopensourcegroup(NXhandle handle); - - /** - * Read a complete dataset from the currently open dataset into memory. - * \param handle A NeXus file handle as initialized by NXopen. - * \param data A pointer to the memory area where to read the data, too. Data must point to a memory - * area large enough to accomodate the data read. Otherwise your program may behave in unexpected - * and unwelcome ways. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_readwrite - */ -extern NXstatus NXgetdata(NXhandle handle, void* data); - - /** - * Retrieve information about the curretly open dataset. - * \param handle A NeXus file handle as initialized by NXopen. - * \param rank A pointer to an integer which will be filled with the rank of - * the dataset. - * \param dimension An array which will be initialized with the size of the dataset in any of its - * dimensions. The array must have at least the size of rank. - * \param datatype A pointer to an integer which be set to the NeXus data type code for this dataset. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_metadata - */ -extern NXstatus NXgetinfo(NXhandle handle, int* rank, int dimension[], int* datatype); - - /** - * @copydoc NXgetinfo() - */ -extern NXstatus NXgetinfo64(NXhandle handle, int* rank, int64_t dimension[], int* datatype); - - /** - * Get the next entry in the currently open group. This is for retrieving infromation about the - * content of a NeXus group. In order to search a group #NXgetnextentry is called in a loop until - * #NXgetnextentry returns NX_EOD which indicates that there are no further items in the group. - * Reset search using #NXinitgroupdir - * \param handle A NeXus file handle as initialized by NXopen. - * \param name The name of the object - * \param nxclass The NeXus class name for a group or the string SDS for a dataset. - * \param datatype The NeXus data type if the item is a SDS. - * \return NX_OK on success, NX_ERROR in the case of an error, NX_EOD when there are no more items. - * \ingroup c_navigation - */ -extern NXstatus NXgetnextentry(NXhandle handle, NXname name, NXname nxclass, int* datatype); - - /** - * Read a subset of data from file into memory. - * \param handle A NeXus file handle as initialized by NXopen. - * \param data A pointer to the memory data where to copy the data too. The pointer must point - * to a memory area large enough to accomodate the size of the data read. - * \param start An array holding the start indices where to start reading the data subset. - * \param size An array holding the size of the data subset to read for each dimension. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_readwrite - */ -extern NXstatus NXgetslab(NXhandle handle, void* data, int start[], int size[]); - - - /** - * @copydoc NXgetslab() - */ -extern NXstatus NXgetslab64(NXhandle handle, void* data, const int64_t start[], const int64_t size[]); - -/** - * Iterate over global, group or dataset attributes depending on the currently open group or - * dataset. In order to search attributes multiple calls to #NXgetnextattr are performed in a loop - * until #NXgetnextattr returns NX_EOD which indicates that there are no further attributes. - * reset search using #NXinitattrdir - * \param handle A NeXus file handle as initialized by NXopen. - * \param pName The name of the attribute - * \param iLength A pointer to an integer which be set to the length of the attribute data. - * \param iType A pointer to an integer which be set to the NeXus data type of the attribute. - * \return NX_OK on success, NX_ERROR in the case of an error, NX_EOD when there are no more items. - * \ingroup c_readwrite - */ -extern NXstatus NXgetnextattr(NXhandle handle, NXname pName, int *iLength, int *iType); - - /** - * Read an attribute. - * \param handle A NeXus file handle as initialized by NXopen. - * \param name The name of the atrribute to read. - * \param data A pointer to a memory area large enough to hold the attributes value. - * \param iDataLen The length of data in bytes. - * \param iType A pointer to an integer which will had been set to the NeXus data type of the attribute. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_readwrite - */ -extern NXstatus NXgetattr(NXhandle handle, char* name, void* data, int* iDataLen, int* iType); - - /** - * Get the count of attributes in the currently open dataset, group or global attributes when at root level. - * \param handle A NeXus file handle as initialized by NXopen. - * \param no_items A pointer to an integer which be set to the number of attributes available. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_metadata - */ -extern NXstatus NXgetattrinfo(NXhandle handle, int* no_items); - - /** - * Retrieve link data for the currently open group. This link data can later on be used to link this - * group into a different group. - * \param handle A NeXus file handle as initialized by NXopen. - * \param pLink A link data structure which will be initialized with the required information - * for linking. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_linking - */ -extern NXstatus NXgetgroupID(NXhandle handle, NXlink* pLink); - - /** - * Retrieve information about the currently open group. - * \param handle A NeXus file handle as initialized by NXopen. - * \param no_items A pointer to an integer which will be set to the count - * of group elements available. This is the count of other groups and - * data sets in this group. - * \param name The name of the group. - * \param nxclass The NeXus class name of the group. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_metadata - */ -extern NXstatus NXgetgroupinfo(NXhandle handle, int* no_items, NXname name, NXname nxclass); - - /** - * Tests if two link data structures describe the same item. - * \param handle A NeXus file handle as initialized by NXopen. - * \param pFirstID The first link data for the test. - * \param pSecondID The second link data structure. - * \return NX_OK when both link data structures describe the same item, NX_ERROR else. - * \ingroup c_linking - */ -extern NXstatus NXsameID(NXhandle handle, NXlink* pFirstID, NXlink* pSecondID); - - /** - * Resets a pending group search to the start again. To be called in a #NXgetnextentry loop when - * a group search has to be restarted. - * \param handle A NeXus file handle as initialized by NXopen. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_navigation - */ -extern NXstatus NXinitgroupdir(NXhandle handle); - - /** - * Resets a pending attribute search to the start again. To be called in a #NXgetnextattr loop when - * an attribute search has to be restarted. - * \param handle A NeXus file handle as initialized by NXopen. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_navigation - */ -extern NXstatus NXinitattrdir(NXhandle handle); - - /** - * Sets the format for number printing. This call has only an effect when using the XML physical file - * format. - * \param handle A NeXus file handle as initialized by NXopen. - * \param type The NeXus data type to set the format for. - * \param format The C-language format string to use for this data type. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_readwrite - */ -extern NXstatus NXsetnumberformat(NXhandle handle, int type, char *format); - - /** - * Inquire the filename of the currently open file. FilenameBufferLength of the file name - * will be copied into the filename buffer. - * \param handle A NeXus file handle as initialized by NXopen. - * \param filename The buffer to hold the filename. - * \param filenameBufferLength The length of the filename buffer. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_metadata - */ -extern NXstatus NXinquirefile(NXhandle handle, char *filename, int filenameBufferLength); - - /** - * Test if a group is actually pointing to an external file. If so, retrieve the URL of the - * external file. - * \param handle A NeXus file handle as initialized by NXopen. - * \param name The name of the group to test. - * \param nxclass The class name of the group to test. - * \param url A buffer to copy the URL too. - * \param urlLen The length of the Url buffer. At maximum urlLen bytes will be copied to url. - * \return NX_OK when the group is pointing to an external file, NX_ERROR else. - * \ingroup c_external - */ -extern NXstatus NXisexternalgroup(NXhandle handle, CONSTCHAR *name, CONSTCHAR *nxclass, char *url, int urlLen); - - - /** - * Test if a dataset is actually pointing to an external file. If so, retrieve the URL of the - * external file. - * \param handle A NeXus file handle as initialized by NXopen. - * \param name The name of the dataset to test. - * \param url A buffer to copy the URL too. - * \param urlLen The length of the Url buffer. At maximum urlLen bytes will be copied to url. - * \return NX_OK when the dataset is pointing to an external file, NX_ERROR else. - * \ingroup c_external - */ -extern NXstatus NXisexternaldataset(NXhandle handle, CONSTCHAR *name, char *url, int urlLen); - - /** - * Create a link to a group in an external file. This works by creating a NeXus group under the current level in - * the hierarchy which actually points to a group in another file. - * \param handle A NeXus file handle as initialized by NXopen. - * \param name The name of the group which points to the external file. - * \param nxclass The class name of the group which points to the external file. - * \param url The URL of the external file. Currently only one URL format is supported: nxfile://path-tofile\#path-in-file. - * This consists of two parts: the first part is of course the path to the file. The second part, path-in-file, is the - * path to the group in the external file which appears in the first file. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_external - */ -extern NXstatus NXlinkexternal(NXhandle handle, CONSTCHAR *name, CONSTCHAR *nxclass, CONSTCHAR *url); - - - /** - * Create a link to a dataset in an external file. This works by creating a dataset under the current level in - * the hierarchy which actually points to a dataset in another file. - * \param handle A NeXus file handle as initialized by NXopen. - * \param name The name of the dataset which points to the external file. - * \param url The URL of the external file. Currently only one URL format is supported: nxfile://path-tofile\#path-in-file. - * This consists of two parts: the first part is of course the path to the file. The second part, path-in-file, is the - * path to the dataset in the external file which appears in the first file. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_external - */ -extern NXstatus NXlinkexternaldataset(NXhandle handle, CONSTCHAR *name, CONSTCHAR *url); - - /** - * Utility function which allocates a suitably sized memory area for the dataset characteristics specified. - * \param data A pointer to a pointer which will be initialized with a pointer to a suitably sized memory area. - * \param rank the rank of the data. - * \param dimensions An array holding the size of the data in each dimension. - * \param datatype The NeXus data type of the data. - * \return NX_OK when allocation succeeds, NX_ERROR in the case of an error. - * \ingroup c_memory - */ -extern NXstatus NXmalloc(void** data, int rank, int dimensions[], int datatype); - - /** - * @copydoc NXmalloc() - */ -extern NXstatus NXmalloc64(void** data, int rank, int64_t dimensions[], int datatype); - - - /** - * Utility function to return NeXus version - * \return pointer to string in static storage. Version in - * same format as NEXUS_VERSION string in napi.h i.e. "major.minor.patch" - * \ingroup c_metadata - */ -extern const char* NXgetversion(); - - /** - * Utility function to release the memory for data. - * \param data A pointer to a pointer to free. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_memory - */ -extern NXstatus NXfree(void** data); - - -/*----------------------------------------------------------------------- - NAPI internals -------------------------------------------------------------------------*/ - /** - * Retrieve information about the currently open dataset. In contrast to the main function below, - * this function does not try to find out about the size of strings properly. - * \param handle A NeXus file handle as initialized by NXopen. - * \param rank A pointer to an integer which will be filled with the rank of - * the dataset. - * \param dimension An array which will be initialized with the size of the dataset in any of its - * dimensions. The array must have at least the size of rank. - * \param datatype A pointer to an integer which be set to the NeXus data type code for this dataset. - * \return NX_OK on success, NX_ERROR in the case of an error. - * \ingroup c_metadata - */ -extern NXstatus NXgetrawinfo(NXhandle handle, int* rank, int dimension[], int* datatype); - - /** - * @copydoc NXgetrawinfo - */ -extern NXstatus NXgetrawinfo64(NXhandle handle, int* rank, int64_t dimension[], int* datatype); - -/** \typedef void (*ErrFunc)(void *data, char *text) - * All NeXus error reporting happens through this special function, the - * ErrFunc. The NeXus-API allows to replace this error reporting function - * through a user defined implementation. The default error function prints to stderr. User - * defined ones may pop up dialog boxes or whatever. - * \param data A pointer to some user defined data structure - * \param text The text of the error message to display. - */ -typedef void (*ErrFunc)(void *data, char *text); - - /** - * Set a global error function. - * Not threadsafe. - * \param pData A pointer to a user defined data structure which be passed to - * the error display function. - * \param newErr The new error display function. - */ -extern void NXMSetError(void *pData, ErrFunc newErr); - - /** - * Set an error function for the current thread. - * When used this overrides anything set in NXMSetError (for the current thread). - * Use this method in threaded applications. - * \param pData A pointer to a user defined data structure which be passed to - * the error display function. - * \param newErr The new error display function. - */ -extern void NXMSetTError(void *pData, ErrFunc newErr); - - /** - * Retrieve the current error display function - * \return The current error display function. - */ -extern ErrFunc NXMGetError(); - - /** - * Suppress error reports from the NeXus-API - */ -extern void NXMDisableErrorReporting(); - - /** - * Enable error reports from the NeXus-API - */ -extern void NXMEnableErrorReporting(); - - /** - * Dispatches the error message to the error function defined by NXMSetTError - */ -extern void NXReportError(char *text); - - /** - * Do not use, first parameter should be set by NXMSetTError - */ -extern void NXIReportError(void *pData,char *text); -/* extern void *NXpData; */ -extern char *NXIformatNeXusTime(); -extern NXstatus NXIprintlink(NXhandle fid, NXlink* link); - -/** - * A function for setting the default cache size for HDF-5 - * \ingroup c_init - */ -extern NXstatus NXsetcache(long newVal); - - typedef struct { - NXhandle pNexusData; - NXstatus ( *nxreopen)(NXhandle pOrigHandle, NXhandle* pNewHandle); - NXstatus ( *nxclose)(NXhandle* pHandle); - NXstatus ( *nxflush)(NXhandle* pHandle); - NXstatus ( *nxmakegroup) (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass); - NXstatus ( *nxopengroup) (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass); - NXstatus ( *nxclosegroup)(NXhandle handle); - NXstatus ( *nxmakedata64) (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[]); - NXstatus ( *nxcompmakedata64) (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[], int comp_typ, int64_t bufsize[]); - NXstatus ( *nxcompress) (NXhandle handle, int compr_type); - NXstatus ( *nxopendata) (NXhandle handle, CONSTCHAR* label); - NXstatus ( *nxclosedata)(NXhandle handle); - NXstatus ( *nxputdata)(NXhandle handle, const void* data); - NXstatus ( *nxputattr)(NXhandle handle, CONSTCHAR* name, const void* data, int iDataLen, int iType); - NXstatus ( *nxputslab64)(NXhandle handle, const void* data, const int64_t start[], const int64_t 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 ( *nxgetinfo64)(NXhandle handle, int* rank, int64_t dimension[], int* datatype); - NXstatus ( *nxgetnextentry)(NXhandle handle, NXname name, NXname nxclass, int* datatype); - NXstatus ( *nxgetslab64)(NXhandle handle, void* data, const int64_t start[], const int64_t 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 ( *nxsameID)(NXhandle handle, NXlink* pFirstID, NXlink* pSecondID); - NXstatus ( *nxinitgroupdir)(NXhandle handle); - NXstatus ( *nxinitattrdir)(NXhandle handle); - NXstatus ( *nxsetnumberformat)(NXhandle handle, int type, char *format); - NXstatus ( *nxprintlink)(NXhandle handle, NXlink* link); - NXstatus ( *nxnativeexternallink)(NXhandle handle, CONSTCHAR* name, CONSTCHAR* externalfile, CONSTCHAR* remotetarget); - NXstatus ( *nxnativeinquirefile)(NXhandle handle, char* externalfile, const int filenamelength); - NXstatus ( *nxnativeisexternallink)(NXhandle handle, CONSTCHAR* name, char* url, int urllen); - int stripFlag; - int checkNameSyntax; - } NexusFunction, *pNexusFunction; - /*---------------------*/ - extern long nx_cacheSize; - -/* FORTRAN internals */ - - extern NXstatus NXfopen(char * filename, NXaccess* am, - NXhandle pHandle); - extern NXstatus NXfclose (NXhandle pHandle); - extern NXstatus NXfputattr(NXhandle fid, const char *name, const void *data, - int *pDatalen, int *pIType); - extern NXstatus NXfcompress(NXhandle fid, int *compr_type); - extern NXstatus NXfcompmakedata(NXhandle fid, char *name, - int *pDatatype, - int *pRank, int dimensions[], - int *compression_type, int chunk[]); - extern NXstatus NXfmakedata(NXhandle fid, char *name, int *pDatatype, - int *pRank, int dimensions[]); - extern NXstatus NXfflush(NXhandle pHandle); - extern NXstatus NXfgetpath(NXhandle fid, char *path, int *pathlen); -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -/** - * Freddie Akeroyd 11/8/2009 - * Add NeXus schema support - this uses BASE.xsd as the initial file - */ -#define NEXUS_SCHEMA_VERSION "3.1" /**< version of NeXus definition schema */ -#define NEXUS_SCHEMA_ROOT "http://definition.nexusformat.org/schema/" /**< XML schema namespace specified by xmlns */ -#define NEXUS_SCHEMA_NAMESPACE NEXUS_SCHEMA_ROOT NEXUS_SCHEMA_VERSION /**< XML schema namespace specified by xmlns */ -#define NEXUS_SCHEMA_BASE "BASE" -#define NEXUS_SCHEMA_FILE NEXUS_SCHEMA_BASE ".xsd" /**< default schema file for namespace */ -#define NEXUS_SCHEMA_URL NEXUS_SCHEMA_NAMESPACE "/" NEXUS_SCHEMA_FILE /**< location of default schema file for namespace */ - -#endif /*NEXUSAPI*/ diff --git a/napi4.c b/napi4.c deleted file mode 100644 index 0545734d..00000000 --- a/napi4.c +++ /dev/null @@ -1,1983 +0,0 @@ -/*--------------------------------------------------------------------------- - NeXus - Neutron & X-ray Common Data Format - - Application Program Interface (HDF4) Routines - - 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 - 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 - - $Id: napi4.c,v 1.11 2012/03/29 08:41:06 koennecke Exp $ - -----------------------------------------------------------------------------*/ - -#ifdef HDF4 - -#include -#include -#include -#include - -#include "napi.h" -#include "napi4.h" - -extern void *NXpData; - - typedef struct __NexusFile { - struct iStack { - int32 *iRefDir; - int32 *iTagDir; - int32 iVref; - int32 __iStack_pad; - int iNDir; - int iCurDir; - } iStack[NXMAXSTACK]; - struct iStack iAtt; - int32 iVID; - int32 iSID; - int32 iCurrentVG; - int32 iCurrentSDS; - int iNXID; - int iStackPtr; - char iAccess[2]; - } NexusFile, *pNexusFile; - /*-------------------------------------------------------------------*/ - - static pNexusFile NXIassert(NXhandle fid) - { - pNexusFile pRes; - - assert(fid != NULL); - pRes = (pNexusFile)fid; - 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; - int32 *pArray = NULL; - NXname pText; - - assert (pFile != NULL); - - if (pFile->iCurrentVG == 0) { /* root level */ - /* get the number and ID's of all lone Vgroups in the file */ - iN = Vlone (pFile->iVID, NULL, 0); - if(iN == 0) { - return NX_EOD; - } - pArray = (int32 *) malloc (iN * sizeof (int32)); - if (!pArray) { - NXReportError( "ERROR: out of memory in NXIFindVgroup"); - return NX_EOD; - } - Vlone (pFile->iVID, pArray, iN); - - /* loop and check */ - for (i = 0; i < iN; i++) { - iNew = Vattach (pFile->iVID, pArray[i], "r"); - Vgetname (iNew, pText); - Vdetach(iNew); - if (strcmp (pText, name) == 0) { - pArray[i] = findNapiClass(pFile,pArray[i],pText); - if (strcmp (pText, nxclass) == 0) { - /* found ! */ - iNew = pArray[i]; - free (pArray); - return iNew; - } - } - } - /* nothing found */ - free (pArray); - return NX_EOD; - } else { /* case in Vgroup */ - iN = Vntagrefs (pFile->iCurrentVG); - for (i = 0; i < iN; i++) { - Vgettagref (pFile->iCurrentVG, i, &iTag, &iRef); - if (iTag == DFTAG_VG) { - iNew = Vattach (pFile->iVID, iRef, "r"); - Vgetname (iNew, pText); - Vdetach(iNew); - if (strcmp (pText, name) == 0) { - iRef = findNapiClass(pFile,iRef, pText); - if (strcmp (pText, nxclass) == 0) { - return iRef; - } - } - } - } /* end for */ - } /* end else */ - /* not found */ - return NX_EOD; - } - - /*----------------------------------------------------------------------*/ - - static int32 NXIFindSDS (NXhandle fid, CONSTCHAR *name) - { - pNexusFile self; - int32 iNew, iRet, iTag, iRef; - int32 i, iN, iA, iD1, iD2; - NXname pNam; - int32 iDim[H4_MAX_VAR_DIMS]; - - self = NXIassert (fid); - - /* root level search */ - if (self->iCurrentVG == 0) { - i = SDfileinfo (self->iSID, &iN, &iA); - if (i < 0) { - NXReportError( "ERROR: failure to read file information"); - return NX_EOD; - } - for (i = 0; i < iN; i++) { - iNew = SDselect (self->iSID, i); - SDgetinfo (iNew, pNam, &iA, iDim, &iD1, &iD2); - if (strcmp (pNam, name) == 0) { - iRet = SDidtoref (iNew); - SDendaccess (iNew); - return iRet; - } else { - SDendaccess (iNew); - } - } - /* not found */ - return NX_EOD; - } - /* end root level */ - else { /* search in a Vgroup */ - iN = Vntagrefs (self->iCurrentVG); - for (i = 0; i < iN; i++) { - Vgettagref (self->iCurrentVG, i, &iTag, &iRef); - /* we are now writing using DFTAG_NDG, but need others for backward compatability */ - if ((iTag == DFTAG_SDG) || (iTag == DFTAG_NDG) || (iTag == DFTAG_SDS)) { - iNew = SDreftoindex (self->iSID, iRef); - iNew = SDselect (self->iSID, iNew); - SDgetinfo (iNew, pNam, &iA, iDim, &iD1, &iD2); - if (strcmp (pNam, name) == 0) { - SDendaccess (iNew); - return iRef; - } - SDendaccess (iNew); - } - } /* end for */ - } /* end Vgroup */ - /* we get here, only if nothing found */ - return NX_EOD; - } - - /*----------------------------------------------------------------------*/ - - static int NXIInitDir (pNexusFile self) - { - int i; - int32 iTag, iRef; - int iStackPtr; - - /* - * Note: the +1 to various malloc() operations is to avoid a - * malloc(0), which is an error on some operating systems - */ - iStackPtr = self->iStackPtr; - if (self->iCurrentVG == 0 && - self->iStack[iStackPtr].iRefDir == NULL) { /* root level */ - /* get the number and ID's of all lone Vgroups in the file */ - self->iStack[iStackPtr].iNDir = Vlone (self->iVID, NULL, 0); - self->iStack[iStackPtr].iRefDir = - (int32 *) malloc (self->iStack[iStackPtr].iNDir * sizeof (int32) + 1); - if (!self->iStack[iStackPtr].iRefDir) { - NXReportError( "ERROR: out of memory in NXIInitDir"); - return NX_EOD; - } - Vlone (self->iVID, - self->iStack[self->iStackPtr].iRefDir, - self->iStack[self->iStackPtr].iNDir); - } else { - /* Vgroup level */ - self->iStack[iStackPtr].iNDir = Vntagrefs (self->iCurrentVG); - self->iStack[iStackPtr].iRefDir = - (int32 *) malloc (self->iStack[iStackPtr].iNDir * sizeof (int32) + 1); - self->iStack[iStackPtr].iTagDir = - (int32 *) malloc (self->iStack[iStackPtr].iNDir * sizeof (int32) + 1); - if ((!self->iStack[iStackPtr].iRefDir) || - (!self->iStack[iStackPtr].iTagDir)) { - NXReportError( "ERROR: out of memory in NXIInitDir"); - return NX_EOD; - } - for (i = 0; i < self->iStack[self->iStackPtr].iNDir; i++) { - Vgettagref (self->iCurrentVG, i, &iTag, &iRef); - self->iStack[iStackPtr].iRefDir[i] = iRef; - self->iStack[iStackPtr].iTagDir[i] = iTag; - } - } - self->iStack[iStackPtr].iCurDir = 0; - return 1; - } - - /*----------------------------------------------------------------------*/ - - static void NXIKillDir (pNexusFile self) - { - if (self->iStack[self->iStackPtr].iRefDir) { - free (self->iStack[self->iStackPtr].iRefDir); - self->iStack[self->iStackPtr].iRefDir = NULL; - } - if (self->iStack[self->iStackPtr].iTagDir) { - free (self->iStack[self->iStackPtr].iTagDir); - self->iStack[self->iStackPtr].iTagDir = NULL; - } - self->iStack[self->iStackPtr].iCurDir = 0; - self->iStack[self->iStackPtr].iNDir = 0; - } - - - /*-------------------------------------------------------------------------*/ - - static int NXIInitAttDir (pNexusFile pFile) - { - int iRet; - int32 iData, iAtt, iRank, iType; - int32 iDim[H4_MAX_VAR_DIMS]; - NXname pNam; - - pFile->iAtt.iCurDir = 0; - if (pFile->iCurrentSDS != 0) { /* SDS level */ - iRet = SDgetinfo (pFile->iCurrentSDS, pNam, &iRank, iDim, &iType, - &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) { - NXReportError( "ERROR: HDF cannot read attribute numbers"); - pFile->iAtt.iNDir = 0; - return NX_ERROR; - } - pFile->iAtt.iNDir = iAtt; - return NX_OK; - } - - /* --------------------------------------------------------------------- */ - - static void NXIKillAttDir (pNexusFile self) - { - if (self->iAtt.iRefDir) { - free (self->iAtt.iRefDir); - self->iAtt.iRefDir = NULL; - } - if (self->iAtt.iTagDir) { - free (self->iAtt.iTagDir); - self->iAtt.iTagDir = NULL; - } - 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[H4_MAX_VAR_DIMS]; - NXname pText; - - buffer[0] = '\0'; - for(i = 1; i <= pFile->iStackPtr; i++){ - strncat(buffer,"/",bufLen-strlen(buffer)); - groupID = Vattach(pFile->iVID,pFile->iStack[i].iVref, "r"); - if (groupID != -1) - { - if (Vgetname(groupID, pText) != -1) { - strncat(buffer,pText,bufLen-strlen(buffer)); - } else { - NXReportError( "ERROR: NXIbuildPath cannot get vgroup name"); - } - Vdetach(groupID); - } - else - { - NXReportError( "ERROR: NXIbuildPath cannot attach to vgroup"); - } - } - if(pFile->iCurrentSDS != 0){ - if (SDgetinfo(pFile->iCurrentSDS,pText,&iA,iDim,&iD1,&iD2) != -1) { - strncat(buffer,"/",bufLen-strlen(buffer)); - strncat(buffer,pText,bufLen-strlen(buffer)); - } - else - { - NXReportError( "ERROR: NXIbuildPath cannot read SDS"); - } - } - } - /* ---------------------------------------------------------------------- - - Definition of NeXus API - - ---------------------------------------------------------------------*/ - - - NXstatus NX4open(CONSTCHAR *filename, NXaccess am, - NXhandle* pHandle) - { - pNexusFile pNew = NULL; - char pBuffer[512]; - char *time_puffer = NULL; - char HDF_VERSION[64]; - uint32 lmajor, lminor, lrelease; - int32 am1=0; - - *pHandle = NULL; - - /* mask off any options for now */ - am = (NXaccess)(am & NXACCMASK_REMOVEFLAGS); - /* map Nexus NXaccess types to HDF4 types */ - if (am == NXACC_CREATE) { - am1 = DFACC_CREATE; - } else if (am == NXACC_CREATE4) { - am1 = DFACC_CREATE; - } else if (am == NXACC_READ) { - am1 = DFACC_READ; - } else if (am == NXACC_RDWR) { - am1 = DFACC_RDWR; - } - /* get memory */ - pNew = (pNexusFile) malloc (sizeof (NexusFile)); - if (!pNew) { - NXReportError( "ERROR: no memory to create File datastructure"); - return NX_ERROR; - } - memset (pNew, 0, sizeof (NexusFile)); - -#if WRITE_OLD_IDENT /* not used at moment */ -/* - * write something that can be used by OLE - */ - - if (am == NXACC_CREATE || am == NXACC_CREATE4) { - if ( (file_id = Hopen(filename, am1, 0)) == -1 ) { - sprintf (pBuffer, "ERROR: cannot open file_a: %s", filename); - NXReportError( pBuffer); - free (pNew); - return NX_ERROR; - } - an_id = ANstart(file_id); - ann_id = ANcreatef(an_id, AN_FILE_LABEL); /* AN_FILE_DESC */ - ANwriteann(ann_id, "NeXus", 5); - ANendaccess(ann_id); - ANend(an_id); - if (Hclose(file_id) == -1) { - sprintf (pBuffer, "ERROR: cannot close file: %s", filename); - NXReportError( pBuffer); - free (pNew); - return NX_ERROR; - } - am = NXACC_RDWR; - } -#endif /* WRITE_OLD_IDENT */ - - /* start SDS interface */ - pNew->iSID = SDstart (filename, am1); - if (pNew->iSID <= 0) { - sprintf (pBuffer, "ERROR: cannot open file_b: %s", filename); - NXReportError( pBuffer); - free (pNew); - return NX_ERROR; - } -/* - * need to create global attributes file_name file_time NeXus_version - * at some point for new files - */ - if (am != NXACC_READ) { - if (SDsetattr(pNew->iSID, "NeXus_version", DFNT_CHAR8, strlen(NEXUS_VERSION), NEXUS_VERSION) < 0) { - NXReportError( "ERROR: HDF failed to store NeXus_version attribute "); - return NX_ERROR; - } - Hgetlibversion(&lmajor, &lminor, &lrelease, HDF_VERSION); - if (SDsetattr(pNew->iSID, "HDF_version", DFNT_CHAR8, strlen(HDF_VERSION), HDF_VERSION) < 0) { - NXReportError( "ERROR: HDF failed to store HDF_version attribute "); - 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) { - NXReportError( "ERROR: HDF failed to store file_name attribute "); - return NX_ERROR; - } - if(time_puffer != NULL){ - if (SDsetattr(pNew->iSID, "file_time", DFNT_CHAR8, - strlen(time_puffer), time_puffer) < 0) { - NXReportError( - "ERROR: HDF failed to store file_time attribute "); - free(time_puffer); - return NX_ERROR; - } - } - } - if (time_puffer != NULL) { - free(time_puffer); - } - - /* - * Otherwise we try to create the file two times which makes HDF - * Throw up on us. - */ - if (am == NXACC_CREATE || am == NXACC_CREATE4) { - am = NXACC_RDWR; - am1 = DFACC_RDWR; - } - - /* Set Vgroup access mode */ - if (am == NXACC_READ) { - strcpy(pNew->iAccess,"r"); - } else { - strcpy(pNew->iAccess,"w"); - } - - /* start Vgroup API */ - - pNew->iVID = Hopen(filename, am1, 100); - if (pNew->iVID <= 0) { - sprintf (pBuffer, "ERROR: cannot open file_c: %s", filename); - NXReportError( pBuffer); - free (pNew); - return NX_ERROR; - } - Vstart (pNew->iVID); - pNew->iNXID = NXSIGNATURE; - pNew->iStack[0].iVref = 0; /* root! */ - - *pHandle = (NXhandle)pNew; - return NX_OK; - } - -/*-----------------------------------------------------------------------*/ - - NXstatus NX4close (NXhandle* fid) - { - pNexusFile pFile = NULL; - int iRet; - - pFile = NXIassert(*fid); - iRet = 0; - /* close links into vGroups or SDS */ - if (pFile->iCurrentVG != 0) { - Vdetach (pFile->iCurrentVG); - } - if (pFile->iCurrentSDS != 0) { - iRet = SDendaccess (pFile->iCurrentSDS); - } - if (iRet < 0) { - NXReportError( "ERROR: ending access to SDS"); - } - /* close the SDS and Vgroup API's */ - Vend (pFile->iVID); - iRet = SDend (pFile->iSID); - if (iRet < 0) { - NXReportError( "ERROR: HDF cannot close SDS interface"); - } - iRet = Hclose (pFile->iVID); - if (iRet < 0) { - NXReportError( "ERROR: HDF cannot close HDF file"); - } - /* release memory */ - NXIKillDir (pFile); - free (pFile); - *fid = NULL; - return NX_OK; - } - - -/*-----------------------------------------------------------------------*/ - - - NXstatus NX4makegroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) - { - pNexusFile pFile; - int32 iNew, iRet; - char pBuffer[256]; - - pFile = NXIassert (fid); - /* - * Make sure that a group with the same name and nxclass does not - * already exist. - */ - if ((iRet = NXIFindVgroup (pFile, (char*)name, nxclass)) >= 0) { - sprintf (pBuffer, "ERROR: Vgroup %s, class %s already exists", - name, nxclass); - NXReportError( pBuffer); - return NX_ERROR; - } - - /* create and configure the group */ - iNew = Vattach (pFile->iVID, -1, "w"); - if (iNew < 0) { - NXReportError( "ERROR: HDF could not create Vgroup"); - return NX_ERROR; - } - Vsetname (iNew, name); - Vsetclass (iNew, nxclass); - - /* Insert it into the hierarchy, when appropriate */ - iRet = 0; - if (pFile->iCurrentVG != 0) { - iRet = Vinsert (pFile->iCurrentVG, iNew); - } - Vdetach (iNew); - if (iRet < 0) { - NXReportError( "ERROR: HDF failed to insert Vgroup"); - return NX_ERROR; - } - return NX_OK; - } - - - /*------------------------------------------------------------------------*/ - NXstatus NX4opengroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) - { - pNexusFile pFile; - int32 iRef; - char pBuffer[256]; - - pFile = NXIassert (fid); - - iRef = NXIFindVgroup (pFile, (char*)name, nxclass); - if (iRef < 0) { - sprintf (pBuffer, "ERROR: Vgroup \"%s\", class \"%s\" NOT found", name, nxclass); - NXReportError( pBuffer); - return NX_ERROR; - } - /* are we at root level ? */ - if (pFile->iCurrentVG == 0) { - pFile->iCurrentVG = Vattach (pFile->iVID, iRef,pFile->iAccess); - pFile->iStackPtr++; - pFile->iStack[pFile->iStackPtr].iVref = iRef; - } else { - Vdetach (pFile->iCurrentVG); - pFile->iStackPtr++; - pFile->iStack[pFile->iStackPtr].iVref = iRef; - pFile->iCurrentVG = Vattach (pFile->iVID, - pFile->iStack[pFile->iStackPtr].iVref, - pFile->iAccess); - } - NXIKillDir (pFile); - return NX_OK; - } - /* ------------------------------------------------------------------- */ - - - NXstatus NX4closegroup (NXhandle fid) - { - pNexusFile pFile; - - pFile = NXIassert (fid); - - /* first catch the trivial case: we are at root and cannot get - deeper into a negative directory hierarchy (anti-directory) - */ - if (pFile->iCurrentVG == 0) { - NXIKillDir (pFile); - return NX_OK; - } else { /* Sighhh. Some work to do */ - /* close the current VG and decrement stack */ - Vdetach (pFile->iCurrentVG); - NXIKillDir (pFile); - pFile->iStackPtr--; - if (pFile->iStackPtr <= 0) { /* we hit root */ - pFile->iStackPtr = 0; - pFile->iCurrentVG = 0; - } else { - /* attach to the lower Vgroup */ - pFile->iCurrentVG = Vattach (pFile->iVID, - pFile->iStack[pFile->iStackPtr].iVref, - pFile->iAccess); - } - } - return NX_OK; - } - - - /* --------------------------------------------------------------------- */ - - NXstatus NX4makedata64 (NXhandle fid, CONSTCHAR *name, int datatype, int rank, - int64_t dimensions[]) - { - pNexusFile pFile; - int32 iNew; - char pBuffer[256]; - int i, iRet, type; - int32 myDim[H4_MAX_VAR_DIMS]; - - pFile = NXIassert (fid); - - if (dimensions[0] == NX_UNLIMITED) - { - dimensions[0] = SD_UNLIMITED; - } - - if ((iNew = NXIFindSDS (fid, name))>=0) { - sprintf (pBuffer, "ERROR: SDS %s already exists at this level", name); - NXReportError( pBuffer); - return NX_ERROR; - } - - if (datatype == NX_CHAR) - { - type=DFNT_CHAR8; - } - else if (datatype == NX_INT8) - { - type=DFNT_INT8; - } - else if (datatype == NX_UINT8) - { - type=DFNT_UINT8; - } - else if (datatype == NX_INT16) - { - type=DFNT_INT16; - } - else if (datatype == NX_UINT16) - { - type=DFNT_UINT16; - } - else if (datatype == NX_INT32) - { - type=DFNT_INT32; - } - else if (datatype == NX_UINT32) - { - type=DFNT_UINT32; - } - else if (datatype == NX_FLOAT32) - { - type=DFNT_FLOAT32; - } - else if (datatype == NX_FLOAT64) - { - type=DFNT_FLOAT64; - } - else - { - NXReportError( "ERROR: invalid type in NX4makedata"); - return NX_ERROR; - } - - if (rank <= 0) { - sprintf (pBuffer, "ERROR: invalid rank specified for SDS %s", - name); - NXReportError( pBuffer); - return NX_ERROR; - } - - /* - Check dimensions for consistency. The first dimension may be 0 - thus denoting an unlimited dimension. - */ - for (i = 1; i < rank; i++) { - if (dimensions[i] <= 0) { - sprintf (pBuffer, - "ERROR: invalid dimension %d, value %lld given for SDS %s", - i, (long long)dimensions[i], name); - NXReportError( pBuffer); - return NX_ERROR; - } - } - - /* cast the dimensions array properly for non 32-bit ints */ - for(i = 0; i < rank; i++) - { - myDim[i] = (int32)dimensions[i]; - } - - - /* behave nicely, if there is still an SDS open */ - if (pFile->iCurrentSDS != 0) { - SDendaccess (pFile->iCurrentSDS); - pFile->iCurrentSDS = 0; - } - - /* Do not allow creation of SDS's at the root level */ - if (pFile->iCurrentVG == 0) { - sprintf(pBuffer, "ERROR: SDS creation at root level is not permitted"); - NXReportError( pBuffer); - return NX_ERROR; - } - - /* dataset creation */ - iNew = SDcreate (pFile->iSID, (char*)name, (int32)type, - (int32)rank, myDim); - if (iNew < 0) { - sprintf (pBuffer, "ERROR: cannot create SDS %s, check arguments", - name); - NXReportError( pBuffer); - return NX_ERROR; - } - /* link into Vgroup, if in one */ - if (pFile->iCurrentVG != 0) { - iRet = Vaddtagref (pFile->iCurrentVG, DFTAG_NDG, SDidtoref (iNew)); - } - iRet = SDendaccess (iNew); - if (iRet < 0) { - NXReportError( "ERROR: HDF cannot end access to SDS"); - return NX_ERROR; - } - return NX_OK; - } - - - /* --------------------------------------------------------------------- */ - - - NXstatus NX4compmakedata64 (NXhandle fid, CONSTCHAR *name, int datatype, int rank, - int64_t dimensions[],int compress_type, int64_t chunk_size[]) - { - pNexusFile pFile; - int32 iNew, iRet, type; - char pBuffer[256]; - int i, compress_level; - int32 myDim[H4_MAX_VAR_DIMS]; - comp_info compstruct; - - pFile = NXIassert (fid); - - if (dimensions[0] == NX_UNLIMITED) - { - dimensions[0] = SD_UNLIMITED; - } - - if ((iNew = NXIFindSDS (fid, name))>=0) { - sprintf (pBuffer, "ERROR: SDS %s already exists at this level", name); - NXReportError( pBuffer); - return NX_ERROR; - } - - if (datatype == NX_CHAR) - { - type=DFNT_CHAR8; - } - else if (datatype == NX_INT8) - { - type=DFNT_INT8; - } - else if (datatype == NX_UINT8) - { - type=DFNT_UINT8; - } - else if (datatype == NX_INT16) - { - type=DFNT_INT16; - } - else if (datatype == NX_UINT16) - { - type=DFNT_UINT16; - } - else if (datatype == NX_INT32) - { - type=DFNT_INT32; - } - else if (datatype == NX_UINT32) - { - type=DFNT_UINT32; - } - else if (datatype == NX_FLOAT32) - { - type=DFNT_FLOAT32; - } - else if (datatype == NX_FLOAT64) - { - type=DFNT_FLOAT64; - } - else - { - NXReportError( "ERROR: invalid datatype in NX4compmakedata"); - return NX_ERROR; - } - - if (rank <= 0) { - sprintf (pBuffer, "ERROR: invalid rank specified for SDS %s", - name); - NXReportError( pBuffer); - return NX_ERROR; - } - - /* - Check dimensions for consistency. The first dimension may be 0 - thus denoting an unlimited dimension. - */ - for (i = 1; i < rank; i++) { - if (dimensions[i] <= 0) { - sprintf (pBuffer, - "ERROR: invalid dimension %d, value %lld given for SDS %s", - i, (long long)dimensions[i], name); - NXReportError( pBuffer); - return NX_ERROR; - } - } - - /* cast the dimensions array properly for non 32-bit ints */ - for(i = 0; i < rank; i++) - { - myDim[i] = (int32)dimensions[i]; - } - - - /* behave nicely, if there is still an SDS open */ - if (pFile->iCurrentSDS != 0) { - SDendaccess (pFile->iCurrentSDS); - pFile->iCurrentSDS = 0; - } - - /* Do not allow creation of SDS's at the root level */ - if (pFile->iCurrentVG == 0) { - sprintf(pBuffer, "ERROR: SDS creation at root level is not permitted"); - NXReportError( pBuffer); - return NX_ERROR; - } - - /* dataset creation */ - iNew = SDcreate (pFile->iSID, (char*)name, (int32)type, - (int32)rank, myDim); - if (iNew < 0) { - sprintf (pBuffer, "ERROR: cannot create SDS %s, check arguments", - name); - NXReportError( pBuffer); - return NX_ERROR; - } - - /* compress SD data set */ - compress_level = 6; - if( (compress_type / 100) == NX_COMP_LZW ) - { - compress_level = compress_type % 100; - compress_type = NX_COMP_LZW; - } - - if(compress_type == NX_COMP_LZW) - { - compstruct.deflate.level = compress_level; - iRet = SDsetcompress(iNew, COMP_CODE_DEFLATE, &compstruct); - if (iRet < 0) - { - NXReportError( "LZW-Compression failure!"); - return NX_ERROR; - } - } - else if (compress_type == NX_COMP_RLE) - { - iRet = SDsetcompress(iNew, COMP_CODE_RLE, &compstruct); - if (iRet < 0) - { - NXReportError( "RLE-Compression failure!"); - return NX_ERROR; - } - } - else if (compress_type == NX_COMP_HUF) - { - compstruct.skphuff.skp_size = DFKNTsize(type); - iRet = SDsetcompress(iNew, COMP_CODE_SKPHUFF, &compstruct); - if (iRet < 0) - { - NXReportError( "HUF-Compression failure!"); - return NX_ERROR; - } - } - else if (compress_type == NX_COMP_NONE) - { - /* */ - } - else - { - NXReportError( "Unknown compression method!"); - return NX_ERROR; - } - /* link into Vgroup, if in one */ - if (pFile->iCurrentVG != 0) { - iRet = Vaddtagref (pFile->iCurrentVG, DFTAG_NDG, SDidtoref (iNew)); - } - iRet = SDendaccess (iNew); - if (iRet < 0) { - NXReportError( "ERROR: HDF cannot end access to SDS"); - return NX_ERROR; - } - - return NX_OK; - } - - /* --------------------------------------------------------------------- */ - - - NXstatus NX4compress (NXhandle fid, int compress_type) - { - pNexusFile pFile; - int32 iRank, iAtt, iType, iRet; - int32 iSize[H4_MAX_VAR_DIMS]; - comp_coder_t compress_typei = COMP_CODE_NONE; - NXname pBuffer; - char pError[512]; - comp_info compstruct; - int compress_level = 6; - - pFile = NXIassert (fid); - - /* check if there is an SDS open */ - if (pFile->iCurrentSDS == 0) { - NXReportError( "ERROR: no SDS open"); - return NX_ERROR; - } - - if (compress_type == NX_COMP_NONE) - { - compress_typei = COMP_CODE_NONE; - } - else if (compress_type == NX_COMP_LZW) - { - compress_typei = COMP_CODE_DEFLATE; - } - else if ( (compress_type / 100) == NX_COMP_LZW ) - { - compress_typei = COMP_CODE_DEFLATE; - compress_level = compress_type % 100; - compress_type = NX_COMP_LZW; - } - else if (compress_type == NX_COMP_RLE) - { - compress_typei = COMP_CODE_RLE; - } - else if - (compress_type == NX_COMP_HUF) - { - compress_typei = COMP_CODE_SKPHUFF; - } - - /* first read dimension information */ - SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, iSize, &iType, &iAtt); - - /* - according to compression type initialize compression - information - */ - if(compress_type == NX_COMP_LZW) - { - compstruct.deflate.level = compress_level; - } - else if(compress_type == NX_COMP_HUF) - { - compstruct.skphuff.skp_size = DFKNTsize(iType); - } - - iRet = SDsetcompress(pFile->iCurrentSDS, compress_typei, &compstruct); - if (iRet < 0) { - sprintf (pError, "ERROR: failure to compress data to %s", pBuffer); - NXReportError( pError); - return NX_ERROR; - } - return NX_OK; - } - - /* --------------------------------------------------------------------- */ - - - NXstatus NX4opendata (NXhandle fid, CONSTCHAR *name) - { - pNexusFile pFile; - int32 iNew, attID, tags[2]; - char pBuffer[256]; - int iRet; - - pFile = NXIassert (fid); - - /* First find the reference number of the SDS */ - iNew = NXIFindSDS (fid, name); - if (iNew < 0) { - sprintf (pBuffer, "ERROR: SDS \"%s\" not found at this level", name); - NXReportError( pBuffer); - return NX_ERROR; - } - /* Be nice: properly close the old open SDS silently if there is - * still an SDS open. - */ - if (pFile->iCurrentSDS) { - iRet = SDendaccess (pFile->iCurrentSDS); - if (iRet < 0) { - NXReportError( "ERROR: HDF cannot end access to SDS"); - } - } - /* clear pending attribute directories first */ - NXIKillAttDir (pFile); - - /* 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) { - NXReportError( "ERROR: HDF error opening SDS"); - pFile->iCurrentSDS = 0; - return NX_ERROR; - } - return NX_OK; - } - - /* ----------------------------------------------------------------- */ - - - NXstatus NX4closedata (NXhandle fid) - { - pNexusFile pFile; - int iRet; - - pFile = NXIassert (fid); - - if (pFile->iCurrentSDS != 0) { - iRet = SDendaccess (pFile->iCurrentSDS); - pFile->iCurrentSDS = 0; - if (iRet < 0) { - NXReportError( "ERROR: HDF cannot end access to SDS"); - return NX_ERROR; - } - } else { - NXReportError( "ERROR: no SDS open --> nothing to do"); - return NX_ERROR; - } - NXIKillAttDir (pFile); /* for attribute data */ - return NX_OK; - } - - - /* ------------------------------------------------------------------- */ - - NXstatus NX4putdata (NXhandle fid, const void *data) - { - pNexusFile pFile; - int32 iStart[H4_MAX_VAR_DIMS], iSize[H4_MAX_VAR_DIMS], iStride[H4_MAX_VAR_DIMS]; - NXname pBuffer; - int32 iRank, iAtt, iType, iRet, i; - char pError[512]; - - pFile = NXIassert (fid); - - /* check if there is an SDS open */ - if (pFile->iCurrentSDS == 0) { - NXReportError( "ERROR: no SDS open"); - return NX_ERROR; - } - /* first read dimension information */ - memset (iStart, 0, H4_MAX_VAR_DIMS * sizeof (int32)); - SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, iSize, &iType, &iAtt); - - /* initialise stride to 1 */ - for (i = 0; i < iRank; i++) { - iStride[i] = 1; - } - - /* actually write */ - iRet = SDwritedata (pFile->iCurrentSDS, iStart, iStride, iSize, (void*)data); - if (iRet < 0) { - /* HEprint(stdout,0); */ - sprintf (pError, "ERROR: failure to write data to %s", pBuffer); - NXReportError( pError); - return NX_ERROR; - } - return NX_OK; - } - - /* ------------------------------------------------------------------- */ - - NXstatus - NX4putattr (NXhandle fid, CONSTCHAR *name, const void *data, int datalen, int iType) - { - pNexusFile pFile; - int iRet, type; - - pFile = NXIassert (fid); - if (iType == NX_CHAR) - { - type=DFNT_CHAR8; - } - else if (iType == NX_INT8) - { - type=DFNT_INT8; - } - else if (iType == NX_UINT8) - { - type=DFNT_UINT8; - } - else if (iType == NX_INT16) - { - type=DFNT_INT16; - } - else if (iType == NX_UINT16) - { - type=DFNT_UINT16; - } - else if (iType == NX_INT32) - { - type=DFNT_INT32; - } - else if (iType == NX_UINT32) - { - type=DFNT_UINT32; - } - else if (iType == NX_FLOAT32) - { - type=DFNT_FLOAT32; - } - else if (iType == NX_FLOAT64) - { - type=DFNT_FLOAT64; - } - else - { - NXReportError( "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 { - 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) { - NXReportError( "ERROR: HDF failed to store attribute "); - return NX_ERROR; - } - return NX_OK; - } - - /* ------------------------------------------------------------------- */ - - - NXstatus NX4putslab64 (NXhandle fid, const void *data, const int64_t iStart[], const int64_t iSize[]) - { - pNexusFile pFile; - int iRet; - int32 iStride[H4_MAX_VAR_DIMS]; - int32 myStart[H4_MAX_VAR_DIMS], mySize[H4_MAX_VAR_DIMS]; - int32 i, iRank, iType, iAtt; - NXname pBuffer; - - - pFile = NXIassert (fid); - - /* check if there is an SDS open */ - if (pFile->iCurrentSDS == 0) { - NXReportError( "ERROR: no SDS open"); - return NX_ERROR; - } - /* initialise stride to 1 */ - for (i = 0; i < H4_MAX_VAR_DIMS; i++) { - iStride[i] = 1; - } - - SDgetinfo (pFile->iCurrentSDS, pBuffer, - &iRank, myStart, &iType, &iAtt); - for(i = 0; i < iRank; i++) - { - myStart[i] = (int32)iStart[i]; - mySize[i] = (int32)iSize[i]; - } - /* finally write */ - iRet = SDwritedata (pFile->iCurrentSDS, myStart, - iStride, mySize, (void*)data); - - - /* deal with HDF errors */ - if (iRet < 0) { - NXReportError( "ERROR: writing slab failed"); - return NX_ERROR; - } - return NX_OK; - } - - - /* ------------------------------------------------------------------- */ - - NXstatus NX4getdataID (NXhandle fid, NXlink* sRes) - { - pNexusFile pFile; - int datalen, type = NX_CHAR; - - pFile = NXIassert (fid); - - if (pFile->iCurrentSDS == 0) { - sRes->iTag = NX_ERROR; - return NX_ERROR; - } else { - sRes->iTag = DFTAG_NDG; - sRes->iRef = SDidtoref (pFile->iCurrentSDS); - NXMDisableErrorReporting(); - datalen = 1024; - memset(&sRes->targetPath,0,1024); - if(NX4getattr(fid,"target",&sRes->targetPath,&datalen,&type) != NX_OK) - { - NXIbuildPath(pFile,sRes->targetPath,1024); - } - NXMEnableErrorReporting(); - return NX_OK; - } - sRes->iTag = NX_ERROR; - return NX_ERROR; /* not reached */ - } - - - /* ------------------------------------------------------------------- */ - - - NXstatus NX4makelink (NXhandle fid, NXlink* sLink) - { - pNexusFile pFile; - int32 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); - 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); - 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 dataID, type = DFNT_CHAR8, length, dataType = NX_CHAR, - rank = 1, attType = NX_INT32; - int64_t 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; - NX4makedata64(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; - } - - /*----------------------------------------------------------------------*/ - - NXstatus NX4printlink (NXhandle fid, NXlink* sLink) - { - NXIassert (fid); - printf("HDF4 link: iTag = %ld, iRef = %ld, target=\"%s\"\n", sLink->iTag, sLink->iRef, sLink->targetPath); - return NX_OK; - } - - /*----------------------------------------------------------------------*/ - - NXstatus NX4flush(NXhandle *pHandle) - { - char *pFileName, *pCopy = NULL; - int access, dummy, iRet, i, iStack; - pNexusFile pFile = NULL; - NXaccess ac; - int *iRefs = NULL; - - pFile = NXIassert(*pHandle); - - /* - The HDF4-API does not support a flush. We help ourselves with - inquiring the name and access type of the file, closing it and - opening it again. This is also the reason why this needs a pointer - to the handle structure as the handle changes. The other thing we - do is to store the refs of all open vGroups in a temporary array - in order to recover the position in the vGroup hierarchy before the - flush. - */ - iRet = Hfidinquire(pFile->iVID,&pFileName,&access,&dummy); - if (iRet < 0) { - NXReportError( - "ERROR: Failed to inquire file name for HDF file"); - return NX_ERROR; - } - if(pFile->iAccess[0] == 'r') { - ac = NXACC_READ; - }else if(pFile->iAccess[0] == 'w') { - ac = NXACC_RDWR; - } else { - NXReportError( - "ERROR: NX4flush failed to determine file access mode"); - return NX_ERROR; - } - pCopy = (char *)malloc((strlen(pFileName)+10)*sizeof(char)); - if(!pCopy) { - NXReportError( - "ERROR: Failed to allocate data for filename copy"); - return NX_ERROR; - } - memset(pCopy,0,strlen(pFileName)+10); - strcpy(pCopy,pFileName); - - /* get refs for recovering vGroup position */ - iStack = 0; - if(pFile->iStackPtr > 0) { - iStack = pFile->iStackPtr + 1; - iRefs = (int *)malloc(iStack*sizeof(int)); - if(!iRefs){ - NXReportError( - "ERROR: Failed to allocate data for hierarchy copy"); - return NX_ERROR; - } - for(i = 0; i < iStack; i++){ - iRefs[i] = pFile->iStack[i].iVref; - } - } - - iRet = NX4close(pHandle); - if(iRet != NX_OK) { - return iRet; - } - - iRet = NX4open(pCopy, ac, pHandle); - free(pCopy); - - /* return to position in vGroup hierarchy */ - pFile = NXIassert(*pHandle); - if(iStack > 0){ - pFile->iStackPtr = iStack - 1; - for(i = 0; i < iStack; i++){ - pFile->iStack[i].iVref = iRefs[i]; - } - free(iRefs); - pFile->iCurrentVG = Vattach(pFile->iVID, - pFile->iStack[pFile->iStackPtr].iVref, - pFile->iAccess); - } - - return iRet; - } - - /*-------------------------------------------------------------------------*/ - - - NXstatus NX4getnextentry (NXhandle fid, NXname name, NXname nxclass, int *datatype) - { - pNexusFile pFile; - int iRet, iStackPtr, iCurDir; - int32 iTemp, iD1, iD2, iA; - int32 iDim[H4_MAX_VAR_DIMS]; - - pFile = NXIassert (fid); - - iStackPtr = pFile->iStackPtr; - iCurDir = pFile->iStack[pFile->iStackPtr].iCurDir; - - /* first case to check for: no directory entry */ - if (pFile->iStack[pFile->iStackPtr].iRefDir == NULL) { - iRet = NXIInitDir (pFile); - if (iRet < 0) { - NXReportError( - "ERROR: no memory to store directory info"); - 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, - pFile->iStack[iStackPtr].iRefDir[iCurDir], "r"); - if (iTemp < 0) { - NXReportError( "ERROR: HDF cannot attach to Vgroup"); - return NX_ERROR; - } - Vgetname (iTemp, name); - Vdetach (iTemp); - findNapiClass(pFile, pFile->iStack[pFile->iStackPtr].iRefDir[iCurDir], nxclass); - *datatype = DFTAG_VG; - pFile->iStack[pFile->iStackPtr].iCurDir++; - return NX_OK; - } else { /* in Vgroup */ - if (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_VG) {/* Vgroup */ - iTemp = Vattach (pFile->iVID, - pFile->iStack[iStackPtr].iRefDir[iCurDir], "r"); - if (iTemp < 0) { - NXReportError( "ERROR: HDF cannot attach to Vgroup"); - return NX_ERROR; - } - Vgetname (iTemp, name); - Vdetach(iTemp); - findNapiClass(pFile, pFile->iStack[pFile->iStackPtr].iRefDir[iCurDir], nxclass); - *datatype = DFTAG_VG; - pFile->iStack[pFile->iStackPtr].iCurDir++; - Vdetach (iTemp); - return NX_OK; - /* we are now writing using DFTAG_NDG, but need others for backward compatability */ - } else if ((pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_SDG) || - (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_NDG) || - (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_SDS)) { - iTemp = SDreftoindex (pFile->iSID, - pFile->iStack[iStackPtr].iRefDir[iCurDir]); - iTemp = SDselect (pFile->iSID, iTemp); - SDgetinfo (iTemp, name, &iA, iDim, &iD1, &iD2); - strcpy (nxclass, "SDS"); - *datatype = iD1; - SDendaccess (iTemp); - pFile->iStack[pFile->iStackPtr].iCurDir++; - return NX_OK; - } else { /* unidentified */ - strcpy (name, "UNKNOWN"); - strcpy (nxclass, "UNKNOWN"); - *datatype = pFile->iStack[iStackPtr].iTagDir[iCurDir]; - pFile->iStack[pFile->iStackPtr].iCurDir++; - return NX_OK; - } - } - return NX_ERROR; /* not reached */ - } - - - /*-------------------------------------------------------------------------*/ - - - NXstatus NX4getdata (NXhandle fid, void *data) - { - pNexusFile pFile; - int32 iStart[H4_MAX_VAR_DIMS], iSize[H4_MAX_VAR_DIMS]; - NXname pBuffer; - int32 iRank, iAtt, iType; - - pFile = NXIassert (fid); - - /* check if there is an SDS open */ - if (pFile->iCurrentSDS == 0) { - NXReportError( "ERROR: no SDS open"); - return NX_ERROR; - } - /* first read dimension information */ - memset (iStart, 0, H4_MAX_VAR_DIMS * sizeof (int32)); - SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, iSize, &iType, &iAtt); - /* actually read */ - SDreaddata (pFile->iCurrentSDS, iStart, NULL, iSize, data); - return NX_OK; - } - - /*-------------------------------------------------------------------------*/ - - NXstatus - NX4getinfo64 (NXhandle fid, int *rank, int64_t dimension[], - int *iType) - { - pNexusFile pFile; - NXname pBuffer; - int32 iAtt, myDim[H4_MAX_VAR_DIMS], i, iRank, mType; - - pFile = NXIassert (fid); - - /* check if there is an SDS open */ - if (pFile->iCurrentSDS == 0) { - NXReportError( "ERROR: no SDS open"); - return NX_ERROR; - } - /* read information */ - SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, myDim, - &mType, &iAtt); - - /* conversion to proper ints for the platform */ - *iType = (int)mType; - *rank = (int)iRank; - for(i = 0; i < iRank; i++) - { - dimension[i] = (int)myDim[i]; - } - return NX_OK; - } - - - /*-------------------------------------------------------------------------*/ - - - NXstatus NX4getslab64 (NXhandle fid, void *data, const int64_t iStart[], const int64_t iSize[]) - { - pNexusFile pFile; - int32 myStart[H4_MAX_VAR_DIMS], mySize[H4_MAX_VAR_DIMS]; - int32 i, iRank, iType, iAtt; - NXname pBuffer; - - pFile = NXIassert (fid); - - /* check if there is an SDS open */ - if (pFile->iCurrentSDS == 0) { - NXReportError( "ERROR: no SDS open"); - return NX_ERROR; - } - - SDgetinfo (pFile->iCurrentSDS, pBuffer, - &iRank, myStart, &iType, &iAtt); - for(i = 0; i < iRank; i++) - { - myStart[i] = (int32)iStart[i]; - mySize[i] = (int32)iSize[i]; - } - /* finally read */ - SDreaddata (pFile->iCurrentSDS, myStart, NULL, - mySize, data); - return NX_OK; - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NX4getnextattr (NXhandle fileid, NXname pName, - int *iLength, int *iType) - { - pNexusFile pFile; - int iRet; - int32 iPType, iCount, count; - - pFile = NXIassert (fileid); - - /* first check if we have to start a new attribute search */ - if (pFile->iAtt.iNDir == 0) { - iRet = NXIInitAttDir (pFile); - if (iRet == NX_ERROR) { - return NX_ERROR; - } - } - /* are we done ? */ - if (pFile->iAtt.iCurDir >= pFile->iAtt.iNDir) { - NXIKillAttDir (pFile); - return NX_EOD; - } - /* well, there must be data to copy */ - 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); - } - if (iRet < 0) { - NXReportError( "ERROR: HDF cannot read attribute info"); - return NX_ERROR; - } - *iLength = iCount; - *iType = iPType; - pFile->iAtt.iCurDir++; - return NX_OK; - } - - - /*-------------------------------------------------------------------------*/ - - - NXstatus NX4getattr (NXhandle fid, char *name, void *data, int* datalen, int* iType) - { - pNexusFile pFile; - int32 iNew, iType32, count; - void *pData = NULL; - int32 iLen, iRet; - int type; - char pBuffer[256]; - NXname pNam; - - type = *iType; - if (type == NX_CHAR) - { - type=DFNT_CHAR8; - } - else if (type == NX_INT8) - { - type=DFNT_INT8; - } - else if (type == NX_UINT8) - { - type=DFNT_UINT8; - } - else if (type == NX_INT16) - { - type=DFNT_INT16; - } - else if (type == NX_UINT16) - { - type=DFNT_UINT16; - } - else if (type == NX_INT32) - { - type=DFNT_INT32; - } - else if (type == NX_UINT32) - { - type=DFNT_UINT32; - } - else if (type == NX_FLOAT32) - { - type=DFNT_FLOAT32; - } - else if (type == NX_FLOAT64) - { - type=DFNT_FLOAT64; - } - *datalen = (*datalen) * DFKNTsize(type); - pFile = NXIassert (fid); - - /* find attribute */ - if (pFile->iCurrentSDS != 0) { - /* SDS attribute */ - iNew = SDfindattr (pFile->iCurrentSDS, name); - } else { - 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); - NXReportError( pBuffer); - return NX_ERROR; - } - /* get more info, allocate temporary data space */ - iType32 = (int32)type; - if (pFile->iCurrentSDS != 0) { - iRet = SDattrinfo (pFile->iCurrentSDS, iNew, pNam, &iType32, &iLen); - } else { - 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"); - NXReportError( pBuffer); - return NX_ERROR; - } - *iType = (int)iType32; - iLen = iLen * DFKNTsize (*iType); - if(*iType == NX_CHAR){ - iLen += 1; - } - pData = (void *) malloc (iLen); - if (!pData) { - NXReportError( "ERROR: allocating memory in NXgetattr"); - return NX_ERROR; - } - memset (pData, 0, iLen); - - /* finally read the data */ - if (pFile->iCurrentSDS != 0) { - iRet = SDreadattr (pFile->iCurrentSDS, iNew, pData); - } else { - 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"); - NXReportError( pBuffer); - return NX_ERROR; - } - /* copy data to caller */ - memset (data, 0, *datalen); - if ((*datalen <= iLen) && - (*iType == DFNT_UINT8 || *iType == DFNT_CHAR8 || *iType == DFNT_UCHAR8)) { - iLen = *datalen - 1; /* this enforces NULL termination regardless of size of datalen */ - } - memcpy (data, pData, iLen); - *datalen = iLen / DFKNTsize(*iType); - free (pData); - return NX_OK; - } - - /*-------------------------------------------------------------------------*/ - - - NXstatus NX4getattrinfo (NXhandle fid, int *iN) - { - pNexusFile pFile; - int iRet; - int32 iData, iAtt, iRank, iType; - int32 iDim[H4_MAX_VAR_DIMS]; - NXname pNam; - - pFile = NXIassert (fid); - if (pFile->iCurrentSDS != 0) { /* SDS level */ - iRet = SDgetinfo (pFile->iCurrentSDS, pNam, &iRank, iDim, &iType, - &iAtt); - } else { - if(pFile->iCurrentVG == 0){ - /* global level */ - iRet = SDfileinfo (pFile->iSID, &iData, &iAtt); - } else { - iRet = Vnattrs(pFile->iCurrentVG); - iAtt = iRet; - } - } - if (iRet < 0) { - NXReportError( "NX_ERROR: HDF cannot read attribute numbers"); - *iN = 0; - return NX_ERROR; - } - *iN = iAtt; - return NX_OK; - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NX4getgroupID (NXhandle fileid, NXlink* sRes) - { - pNexusFile pFile; - - pFile = NXIassert (fileid); - - if (pFile->iCurrentVG == 0) { - sRes->iTag = NX_ERROR; - return NX_ERROR; - } else { - sRes->iTag = DFTAG_VG; - sRes->iRef = VQueryref(pFile->iCurrentVG); - NXIbuildPath(pFile,sRes->targetPath,1024); - return NX_OK; - } - /* not reached */ - sRes->iTag = NX_ERROR; - return NX_ERROR; - } - - /*-------------------------------------------------------------------------*/ - - NXstatus - NX4getgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass) - { - pNexusFile pFile; - - pFile = NXIassert (fid); - /* check if there is a group open */ - if (pFile->iCurrentVG == 0) { - *iN = Vlone (pFile->iVID, NULL, 0); - strcpy (pName, "root"); - strcpy (pClass, "NXroot"); - } - else { - *iN = Vntagrefs (pFile->iCurrentVG); - Vgetname (pFile->iCurrentVG, pName); - Vgetclass (pFile->iCurrentVG, pClass); - } - return NX_OK; - } - - /* ------------------------------------------------------------------- */ - - NXstatus NX4sameID (NXhandle fileid, NXlink* pFirstID, NXlink* pSecondID) - { - NXIassert (fileid); - if ((pFirstID->iTag == pSecondID->iTag) & (pFirstID->iRef == pSecondID->iRef)) { - return NX_OK; - } else { - return NX_ERROR; - } - } - - /*-------------------------------------------------------------------------*/ - - - NXstatus NX4initattrdir (NXhandle fid) - { - pNexusFile pFile; - int iRet; - - pFile = NXIassert (fid); - NXIKillAttDir (pFile); - iRet = NXIInitAttDir (pFile); - if (iRet == NX_ERROR) - return NX_ERROR; - return NX_OK; - } - - - /*-------------------------------------------------------------------------*/ - - - NXstatus NX4initgroupdir (NXhandle fid) - { - pNexusFile pFile; - int iRet; - - pFile = NXIassert (fid); - NXIKillDir (pFile); - iRet = NXIInitDir (pFile); - if (iRet < 0) { - NXReportError("NX_ERROR: no memory to store directory info"); - return NX_EOD; - } - return NX_OK; - } - -/*--------------------------------------------------------------------*/ -void NX4assignFunctions(pNexusFunction fHandle) -{ - fHandle->nxclose=NX4close; - fHandle->nxreopen=NULL; - fHandle->nxflush=NX4flush; - fHandle->nxmakegroup=NX4makegroup; - fHandle->nxopengroup=NX4opengroup; - fHandle->nxclosegroup=NX4closegroup; - fHandle->nxmakedata64=NX4makedata64; - fHandle->nxcompmakedata64=NX4compmakedata64; - fHandle->nxcompress=NX4compress; - fHandle->nxopendata=NX4opendata; - fHandle->nxclosedata=NX4closedata; - fHandle->nxputdata=NX4putdata; - fHandle->nxputattr=NX4putattr; - fHandle->nxputslab64=NX4putslab64; - fHandle->nxgetdataID=NX4getdataID; - fHandle->nxmakelink=NX4makelink; - fHandle->nxmakenamedlink=NX4makenamedlink; - fHandle->nxgetdata=NX4getdata; - fHandle->nxgetinfo64=NX4getinfo64; - fHandle->nxgetnextentry=NX4getnextentry; - fHandle->nxgetslab64=NX4getslab64; - fHandle->nxgetnextattr=NX4getnextattr; - fHandle->nxgetattr=NX4getattr; - fHandle->nxgetattrinfo=NX4getattrinfo; - fHandle->nxgetgroupID=NX4getgroupID; - fHandle->nxgetgroupinfo=NX4getgroupinfo; - fHandle->nxsameID=NX4sameID; - fHandle->nxinitgroupdir=NX4initgroupdir; - fHandle->nxinitattrdir=NX4initattrdir; - fHandle->nxprintlink=NX4printlink; - fHandle->nxnativeexternallink=NULL; -} - -#endif /*HDF4*/ diff --git a/napi4.h b/napi4.h deleted file mode 100644 index af354a57..00000000 --- a/napi4.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef NAPI4_H -#define NAPI4_H - -#define NXSIGNATURE 959697 - -#include "mfhdf.h" -/* #include "napi4.c" */ - -/* - * HDF4 interface - */ - -extern NXstatus NX4open(CONSTCHAR *filename, NXaccess access_method, NXhandle* pHandle); -extern NXstatus NX4close(NXhandle* pHandle); -extern NXstatus NX4flush(NXhandle* pHandle); - -extern NXstatus NX4makegroup (NXhandle handle, CONSTCHAR* Vgroup, CONSTCHAR* NXclass); -extern NXstatus NX4opengroup (NXhandle handle, CONSTCHAR* Vgroup, CONSTCHAR* NXclass); -extern NXstatus NX4closegroup(NXhandle handle); - -extern NXstatus NX4makedata64 (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[]); -extern NXstatus NX4compmakedata64 (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[], int comp_typ, int64_t bufsize[]); -extern NXstatus NX4compress (NXhandle handle, int compr_type); -extern NXstatus NX4opendata (NXhandle handle, CONSTCHAR* label); - -extern NXstatus NX4closedata(NXhandle handle); - -extern NXstatus NX4getdata(NXhandle handle, void* data); -extern NXstatus NX4getslab64(NXhandle handle, void* data, const int64_t start[], const int64_t size[]); -extern NXstatus NX4getattr(NXhandle handle, char* name, void* data, int* iDataLen, int* iType); - -extern NXstatus NX4putdata(NXhandle handle, const void* data); -extern NXstatus NX4putslab64(NXhandle handle, const void* data, const int64_t start[], const int64_t size[]); -extern NXstatus NX4putattr(NXhandle handle, CONSTCHAR* name, const void* data, int iDataLen, int iType); - -extern NXstatus NX4getinfo64(NXhandle handle, int* rank, int64_t dimension[], int* datatype); -extern NXstatus NX4getgroupinfo(NXhandle handle, int* no_items, NXname name, NXname nxclass); -extern NXstatus NX4initgroupdir(NXhandle handle); -extern NXstatus NX4getnextentry(NXhandle handle, NXname name, NXname nxclass, int* datatype); -extern NXstatus NX4getattrinfo(NXhandle handle, int* no_items); -extern NXstatus NX4initattrdir(NXhandle handle); -extern NXstatus NX4getnextattr(NXhandle handle, NXname pName, int *iLength, int *iType); - -extern NXstatus NX4getgroupID(NXhandle handle, NXlink* pLink); -extern NXstatus NX4getdataID(NXhandle handle, NXlink* pLink); -extern NXstatus NX4makelink(NXhandle handle, NXlink* pLink); -extern NXstatus NX4printlink(NXhandle handle, NXlink* pLink); - -void NX4assignFunctions(pNexusFunction fHandle); - - -/* - * HDF changed from MAX_VAR_DIMS to H4_MAX_VAR_DIMS aronud 9/5/2007 - * to avoid potential conflicts with NetCDF-3 library - */ -#ifndef H4_MAX_VAR_DIMS -#define H4_MAX_VAR_DIMS MAX_VAR_DIMS -#endif - -#endif /* NAPI4_H */ diff --git a/napi5.c b/napi5.c deleted file mode 100644 index 810e1113..00000000 --- a/napi5.c +++ /dev/null @@ -1,2301 +0,0 @@ -/*--------------------------------------------------------------------------- - NeXus - Neutron & X-ray Common Data Format - - Application Program Interface (HDF5) Routines - - Copyright (C) 1997-2011 Mark Koennecke, Przemek Klosowski - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - For further information, see - -----------------------------------------------------------------------------*/ - -#ifdef HDF5 - -#include -#include -#include -#include - -#include "napi.h" -#include "napi5.h" - -#ifdef H5_VERSION_GE -#if !H5_VERSION_GE(1,8,0) -#error HDF5 Version must be 1.8.0 or higher -#endif -#endif - -#ifdef _MSC_VER -#define snprintf _snprintf -#endif /* _MSC_VER */ - -#define NX_UNKNOWN_GROUP "" /* for when no NX_class attr */ - -extern void *NXpData; - - typedef struct __NexusFile5 { - struct iStack5 { - char irefn[1024]; - int iVref; - hsize_t iCurrentIDX; - } iStack5[NXMAXSTACK]; - struct iStack5 iAtt5; - int iFID; - int iCurrentG; - int iCurrentD; - int iCurrentS; - int iCurrentT; - int iCurrentA; - int iNX; - int iNXID; - int iStackPtr; - char *iCurrentLGG; - char *iCurrentLD; - char name_ref[1024]; - char name_tmp[1024]; - char iAccess[2]; - } NexusFile5, *pNexusFile5; - -/* - forward declaration of NX5closegroup in order to get rid of a nasty - warning -*/ -NXstatus NX5closegroup (NXhandle fid); -/*-------------------------------------------------------------------*/ - - static pNexusFile5 NXI5assert(NXhandle fid) - { - pNexusFile5 pRes; - - assert(fid != NULL); - pRes = (pNexusFile5)fid; - assert(pRes->iNXID == NX5SIGNATURE); - return pRes; - } - - /*--------------------------------------------------------------------*/ - - static void NXI5KillDir (pNexusFile5 self) - { - self->iStack5[self->iStackPtr].iCurrentIDX = 0; - } - - /*--------------------------------------------------------------------*/ - - static void NXI5KillAttDir (pNexusFile5 self) - { - self->iAtt5.iCurrentIDX = 0; - } -/*---------------------------------------------------------------------*/ -static void buildCurrentPath(pNexusFile5 self, char *pathBuffer, - int pathBufferLen){ - - memset(pathBuffer,0,pathBufferLen); - if(self->iCurrentG != 0) { - strcpy(pathBuffer,"/"); - if(strlen(self->name_ref) + 1 < pathBufferLen){ - strcat(pathBuffer, self->name_ref); - } - } - if(self->iCurrentD != 0){ - strcat(pathBuffer,"/"); - if(strlen(self->iCurrentLD) + strlen(pathBuffer) < pathBufferLen){ - strcat(pathBuffer,self->iCurrentLD); - } - } -} - /* ---------------------------------------------------------------------- - - Definition of NeXus API - - ---------------------------------------------------------------------*/ - - NXstatus NX5reopen(NXhandle pOrigHandle, NXhandle* pNewHandle) -{ - pNexusFile5 pNew = NULL, pOrig = NULL; - *pNewHandle = NULL; - pOrig = (pNexusFile5)pOrigHandle; - pNew = (pNexusFile5) malloc (sizeof (NexusFile5)); - if (!pNew) { - NXReportError ("ERROR: no memory to create File datastructure"); - return NX_ERROR; - } - memset (pNew, 0, sizeof (NexusFile5)); - pNew->iFID = H5Freopen (pOrig->iFID); - if (pNew->iFID <= 0) { - NXReportError ("cannot clone file"); - free (pNew); - return NX_ERROR; - } - strcpy(pNew->iAccess, pOrig->iAccess); - pNew->iNXID = NX5SIGNATURE; - pNew->iStack5[0].iVref = 0; /* root! */ - *pNewHandle = (NXhandle)pNew; - return NX_OK; -} - -NXstatus NX5open(CONSTCHAR *filename, NXaccess am, - NXhandle* pHandle) - { - hid_t attr1,aid1, aid2, iVID; - pNexusFile5 pNew = NULL; - char pBuffer[512]; - char *time_buffer = NULL; - char version_nr[10]; - unsigned int vers_major, vers_minor, vers_release, am1 ; - hid_t fapl = -1; - int mdc_nelmts; - size_t rdcc_nelmts; - size_t rdcc_nbytes; - double rdcc_w0; - unsigned hdf5_majnum, hdf5_minnum, hdf5_relnum; - - *pHandle = NULL; - - if (H5get_libversion(&hdf5_majnum, &hdf5_minnum, &hdf5_relnum) < 0) - { - NXReportError("ERROR: cannot determine HDF5 library version"); - return NX_ERROR; - } - if (hdf5_majnum == 1 && hdf5_minnum < 8) - { - NXReportError("ERROR: HDF5 library 1.8.0 or higher required"); - return NX_ERROR; - } - - /* mask of any options for now */ - am = (NXaccess)(am & NXACCMASK_REMOVEFLAGS); - - /* turn off the automatic HDF error handling */ - H5Eset_auto(H5E_DEFAULT, NULL, NULL); -#ifdef USE_FTIME - struct timeb timeb_struct; -#endif - - - pNew = (pNexusFile5) malloc (sizeof (NexusFile5)); - if (!pNew) { - NXReportError("ERROR: not enough memory to create file structure"); - return NX_ERROR; - } - memset (pNew, 0, sizeof (NexusFile5)); - - - /* start HDF5 interface */ - if (am == NXACC_CREATE5) { - fapl = H5Pcreate(H5P_FILE_ACCESS); - H5Pget_cache(fapl,&mdc_nelmts,&rdcc_nelmts,&rdcc_nbytes,&rdcc_w0); - rdcc_nbytes=(size_t)nx_cacheSize; - H5Pset_cache(fapl,mdc_nelmts,rdcc_nelmts,rdcc_nbytes,rdcc_w0); - H5Pset_fclose_degree(fapl,H5F_CLOSE_STRONG); - am1 = H5F_ACC_TRUNC; - pNew->iFID = H5Fcreate (filename, am1, H5P_DEFAULT, fapl); - } else { - if (am == NXACC_READ) { - am1 = H5F_ACC_RDONLY; - } else { - am1 = H5F_ACC_RDWR; - } - fapl = H5Pcreate(H5P_FILE_ACCESS); - H5Pset_fclose_degree(fapl,H5F_CLOSE_STRONG); - pNew->iFID = H5Fopen (filename, am1, fapl); - } - if(fapl != -1) { - H5Pclose(fapl); - } - if (pNew->iFID <= 0) { - sprintf (pBuffer, "ERROR: cannot open file: %s", filename); - NXReportError( pBuffer); - free (pNew); - return NX_ERROR; - } - -/* - * need to create global attributes file_name file_time NeXus_version - * at some point for new files - */ - if (am1 != H5F_ACC_RDONLY) - { - iVID = H5Gopen(pNew->iFID,"/", H5P_DEFAULT); - aid2 = H5Screate(H5S_SCALAR); - aid1 = H5Tcopy(H5T_C_S1); - H5Tset_size(aid1, strlen(NEXUS_VERSION)); - if (am1 == H5F_ACC_RDWR) - { - H5Adelete(iVID, "NeXus_version"); - } - attr1= H5Acreate(iVID, "NeXus_version", aid1, aid2, H5P_DEFAULT, H5P_DEFAULT); - if (attr1<0) - { - NXReportError( - "ERROR: failed to store NeXus_version attribute "); - return NX_ERROR; - } - if (H5Awrite(attr1, aid1,NEXUS_VERSION)<0) - { - NXReportError( - "ERROR: failed to store NeXus_version attribute "); - return NX_ERROR; - } - /* Close attribute dataspace */ - H5Tclose(aid1); - H5Sclose(aid2); - /* Close attribute */ - H5Aclose(attr1); - H5Gclose(iVID); - } - if (am1 == H5F_ACC_TRUNC) - { - iVID = H5Gopen(pNew->iFID,"/", H5P_DEFAULT); - aid2 = H5Screate(H5S_SCALAR); - aid1 = H5Tcopy(H5T_C_S1); - H5Tset_size(aid1, strlen(filename)); - attr1= H5Acreate(iVID, "file_name", aid1, aid2, H5P_DEFAULT, H5P_DEFAULT); - if (attr1 < 0) - { - NXReportError( - "ERROR: failed to store file_name attribute "); - return NX_ERROR; - } - if (H5Awrite(attr1, aid1, (char*)filename) < 0) - { - NXReportError( - "ERROR: failed to store file_name attribute "); - return NX_ERROR; - } - H5Tclose(aid1); - H5Sclose(aid2); - H5Aclose(attr1); - /* ------- library version ------*/ - H5get_libversion(&vers_major, &vers_minor, &vers_release); - sprintf (version_nr, "%d.%d.%d", vers_major,vers_minor,vers_release); - aid2=H5Screate(H5S_SCALAR); - aid1 = H5Tcopy(H5T_C_S1); - H5Tset_size(aid1, strlen(version_nr)); - attr1= H5Acreate(iVID, "HDF5_Version", aid1, aid2, H5P_DEFAULT, H5P_DEFAULT); - if (attr1 < 0) - { - NXReportError( - "ERROR: failed to store file_name attribute "); - return NX_ERROR; - } - if (H5Awrite(attr1, aid1, (char*)version_nr) < 0) - { - NXReportError( - "ERROR: failed to store file_name attribute "); - return NX_ERROR; - } - H5Tclose(aid1); - H5Sclose(aid2); - H5Aclose(attr1); - /*----------- file time */ - time_buffer = NXIformatNeXusTime(); - if(time_buffer != NULL){ - aid2=H5Screate(H5S_SCALAR); - aid1 = H5Tcopy(H5T_C_S1); - H5Tset_size(aid1, strlen(time_buffer)); - attr1=H5Acreate(iVID, "file_time", aid1, aid2, H5P_DEFAULT, H5P_DEFAULT); - if (attr1 < 0) - { - NXReportError( - "ERROR: failed to store file_time attribute "); - free(time_buffer); - return NX_ERROR; - } - if (H5Awrite(attr1, aid1, time_buffer) < 0) - { - NXReportError( - "ERROR: failed to store file_time attribute "); - free(time_buffer); - return NX_ERROR; - } - /* Close attribute dataspace */ - H5Tclose(aid1); - H5Sclose(aid2); - /* Close attribute */ - H5Aclose(attr1); - free(time_buffer); - } - H5Gclose(iVID); - } - /* Set HDFgroup access mode */ - if (am1 == H5F_ACC_RDONLY) { - strcpy(pNew->iAccess,"r"); - } else { - strcpy(pNew->iAccess,"w"); - } - pNew->iNXID = NX5SIGNATURE; - pNew->iStack5[0].iVref = 0; /* root! */ - *pHandle = (NXhandle)pNew; - return NX_OK; - } - - /* ------------------------------------------------------------------------- */ - - NXstatus NX5close (NXhandle* fid) - { - pNexusFile5 pFile = NULL; - herr_t iRet; - - pFile=NXI5assert(*fid); - - iRet=0; - /* - printf("HDF5 object count before close: %d\n", - H5Fget_obj_count(pFile->iFID,H5F_OBJ_ALL)); - */ - iRet = H5Fclose(pFile->iFID); - - /* - leave this here: it helps in debugging leakage problems - printf("HDF5 object count after close: %d\n", - H5Fget_obj_count(H5F_OBJ_ALL,H5F_OBJ_ALL)); - printf("HDF5 dataset count after close: %d\n", - H5Fget_obj_count(H5F_OBJ_ALL,H5F_OBJ_DATASET)); - printf("HDF5 group count after close: %d\n", - H5Fget_obj_count(H5F_OBJ_ALL,H5F_OBJ_GROUP)); - printf("HDF5 datatype count after close: %d\n", - H5Fget_obj_count(H5F_OBJ_ALL,H5F_OBJ_DATATYPE)); - printf("HDF5 attribute count after close: %d\n", - H5Fget_obj_count(H5F_OBJ_ALL,H5F_OBJ_ATTR)); - */ - - if (iRet < 0) { - NXReportError( "ERROR: cannot close HDF file"); - } - /* release memory */ - NXI5KillDir (pFile); - if(pFile->iCurrentLGG != NULL){ - free(pFile->iCurrentLGG); - } - if(pFile->iCurrentLD != NULL){ - free(pFile->iCurrentLD); - } - free (pFile); - *fid = NULL; - H5garbage_collect(); - return NX_OK; - } - - /*-----------------------------------------------------------------------*/ - - NXstatus NX5makegroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) - { - pNexusFile5 pFile; - herr_t iRet; - hid_t iVID; - hid_t attr1,aid1, aid2; - char pBuffer[1024] = ""; - - pFile = NXI5assert (fid); - /* create and configure the group */ - if (pFile->iCurrentG==0) { - snprintf(pBuffer,1023,"/%s",name); - } else { - snprintf(pBuffer,1023,"/%s/%s",pFile->name_ref,name); - } - iRet = H5Gcreate(pFile->iFID,(const char*)pBuffer, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - if (iRet < 0) { - NXReportError( "ERROR: could not create Group"); - return NX_ERROR; - } - iVID = iRet; - aid2 = H5Screate(H5S_SCALAR); - aid1 = H5Tcopy(H5T_C_S1); - H5Tset_size(aid1, strlen(nxclass)); - attr1= H5Acreate(iVID, "NX_class", aid1, aid2, H5P_DEFAULT, H5P_DEFAULT); - if (attr1 < 0) { - NXReportError( "ERROR: failed to store class name"); - return NX_ERROR; - } - if (H5Awrite(attr1, aid1, (char*)nxclass) < 0) { - NXReportError( "ERROR: failed to store class name"); - return NX_ERROR; - } - /* close group */ - iRet=H5Sclose(aid2); - iRet=H5Tclose(aid1); - iRet=H5Aclose(attr1); - iRet=H5Gclose(iVID); - return NX_OK; - } - - /*------------------------------------------------------------------------*/ - - herr_t attr_check (hid_t loc_id, const char *member_name, const H5A_info_t *unused, void *opdata) - { - char attr_name[8+1]; /* need to leave space for \0 as well */ - - strcpy(attr_name,"NX_class"); - return strstr(member_name, attr_name) ? 1 : 0; - } - /*------------------------------------------------------------------------*/ - NXstatus NX5opengroup(NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass) - { - - pNexusFile5 pFile; - hid_t attr1, atype; - herr_t iRet; - char pBuffer[1024]; - char data[128]; - - pFile = NXI5assert (fid); - if (pFile->iCurrentG == 0) { - strcpy(pBuffer,name); - } else { - sprintf(pBuffer,"%s/%s",pFile->name_tmp,name); - } - iRet = H5Gopen(pFile->iFID, (const char *)pBuffer, H5P_DEFAULT); - if (iRet < 0) { - sprintf (pBuffer, "ERROR: group %s does not exist", pFile->name_tmp); - NXReportError( pBuffer); - return NX_ERROR; - } - pFile->iCurrentG = iRet; - strcpy(pFile->name_tmp,pBuffer); - strcpy(pFile->name_ref,pBuffer); - - if ((nxclass != NULL) && (strcmp(nxclass, NX_UNKNOWN_GROUP) != 0)) { - /* check group attribute */ - iRet=H5Aiterate(pFile->iCurrentG,H5_INDEX_CRT_ORDER,H5_ITER_INC,0,attr_check,NULL); - if (iRet < 0) { - NXReportError( "ERROR: iterating through attribute list"); - return NX_ERROR; - } else if (iRet == 1) { - /* group attribute was found */ - } else { - /* no group attribute available */ - NXReportError( "ERROR: no group attribute available"); - return NX_ERROR; - } - /* check contents of group attribute */ - attr1 = H5Aopen_by_name(pFile->iCurrentG, ".", "NX_class", H5P_DEFAULT, H5P_DEFAULT); - if (attr1 < 0) { - NXReportError( "ERROR: opening NX_class group attribute"); - return NX_ERROR; - } - atype=H5Tcopy(H5T_C_S1); - H5Tset_size(atype,sizeof(data)); - iRet = H5Aread(attr1, atype, data); - if (strcmp(data, nxclass) == 0) { - /* test OK */ - } else { - NXReportError( "ERROR: group class is not identical"); - iRet = H5Tclose(atype); - iRet = H5Aclose(attr1); - return NX_ERROR; - } - iRet = H5Tclose(atype); - iRet = H5Aclose(attr1); - } - - /* maintain stack */ - pFile->iStackPtr++; - pFile->iStack5[pFile->iStackPtr].iVref=pFile->iCurrentG; - strcpy(pFile->iStack5[pFile->iStackPtr].irefn,name); - pFile->iAtt5.iCurrentIDX=0; - pFile->iCurrentD = 0; - if(pFile->iCurrentLGG != NULL){ - free(pFile->iCurrentLGG); - } - pFile->iCurrentLGG = strdup(name); - NXI5KillDir (pFile); - return NX_OK; - } - - /* ------------------------------------------------------------------- */ - - NXstatus NX5closegroup (NXhandle fid) - { - pNexusFile5 pFile; - int i,ii; - char *uname = NULL; - char *u1name = NULL; - - pFile = NXI5assert (fid); - /* first catch the trivial case: we are at root and cannot get - deeper into a negative directory hierarchy (anti-directory) - */ - if (pFile->iCurrentG == 0) { - NXI5KillDir (pFile); - return NX_OK; - } else { - /* close the current group and decrement name_ref */ - H5Gclose (pFile->iCurrentG); - i = 0; - i = strlen(pFile->iStack5[pFile->iStackPtr].irefn); - ii = strlen(pFile->name_ref); - if (pFile->iStackPtr>1) { - ii=ii-i-1; - } else { - ii=ii-i; - } - if (ii>0) { - uname = strdup(pFile->name_ref); - u1name = (char*) malloc((ii+1)*sizeof(char)); - memset(u1name,0,ii); - for (i=0; iname_ref,u1name); - strcpy(pFile->name_tmp,u1name); - free(uname); - free(u1name); - } else { - strcpy(pFile->name_ref,""); - strcpy(pFile->name_tmp,""); - } - NXI5KillDir (pFile); - pFile->iStackPtr--; - if (pFile->iStackPtr>0) { - pFile->iCurrentG=pFile->iStack5[pFile->iStackPtr].iVref; - } else { - pFile->iCurrentG=0; - } - } - return NX_OK; - } -/*-----------------------------------------------------------------------*/ -static hid_t nxToHDF5Type(int datatype) -{ - hid_t type; - if (datatype == NX_CHAR) { - type=H5T_C_S1; - } else if (datatype == NX_INT8) { - type=H5T_NATIVE_CHAR; - } else if (datatype == NX_UINT8) { - type=H5T_NATIVE_UCHAR; - } else if (datatype == NX_INT16) { - type=H5T_NATIVE_SHORT; - } else if (datatype == NX_UINT16) { - type=H5T_NATIVE_USHORT; - } else if (datatype == NX_INT32) { - type=H5T_NATIVE_INT; - } else if (datatype == NX_UINT32) { - 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; - } else if (datatype == NX_FLOAT64) { - type=H5T_NATIVE_DOUBLE; - } else { - NXReportError( "ERROR: nxToHDF5Type: unknown type"); - type = -1; - } - return type; -} - - /* --------------------------------------------------------------------- */ - - NXstatus NX5compmakedata64 (NXhandle fid, CONSTCHAR *name, - int datatype, - int rank, int64_t dimensions[], - int compress_type, int64_t chunk_size[]) - { - hid_t datatype1, dataspace, iNew; - herr_t iRet; - hid_t type, cparms = -1; - pNexusFile5 pFile; - char pBuffer[256]; - int i, byte_zahl = 0; - hsize_t chunkdims[H5S_MAX_RANK]; - hsize_t mydim[H5S_MAX_RANK], mydim1[H5S_MAX_RANK]; - hsize_t size[H5S_MAX_RANK]; - hsize_t maxdims[H5S_MAX_RANK]; - int compress_level; - int unlimiteddim = 0; - - pFile = NXI5assert (fid); - if (pFile->iCurrentG <= 0) { - sprintf(pBuffer, "ERROR: no group open for makedata on %s", name); - NXReportError( pBuffer); - return NX_ERROR; - } - - if (rank <= 0) { - sprintf (pBuffer, "ERROR: invalid rank specified %s", name); - NXReportError( pBuffer); - return NX_ERROR; - } - - type = nxToHDF5Type(datatype); - - /* - Check dimensions for consistency. Dimension may be -1 - thus denoting an unlimited dimension. - */ - for (i = 0; i < rank; i++) - { - chunkdims[i] = chunk_size[i]; - mydim[i] = dimensions[i]; - maxdims[i] = dimensions[i]; - size[i] = dimensions[i]; - if (dimensions[i] <= 0) - { - mydim[i] = 1; - maxdims[i] = H5S_UNLIMITED; - size[i] = 1; - unlimiteddim = 1; - } else { - mydim[i] = dimensions[i]; - maxdims[i] = dimensions[i]; - size[i] = dimensions[i]; - } - } - - if (datatype == NX_CHAR) - { - /* - * This assumes string lenght is in the last dimensions and - * the logic must be the same as used in NX5getslab and NX5getinfo - * - * search for tests on H5T_STRING - */ - byte_zahl=mydim[rank-1]; - for(i = 0; i < rank; i++) - { - mydim1[i] = mydim[i]; - if (dimensions[i] <= 0) - { - mydim1[0] = 1; - maxdims[0] = H5S_UNLIMITED; - } - - } - mydim1[rank-1] = 1; - if (mydim[rank-1] > 1) - { - mydim[rank-1] = maxdims[rank-1] = size[rank-1] = 1; - } - if (chunkdims[rank-1] > 1) - { - chunkdims[rank-1] = 1; - } - dataspace=H5Screate_simple(rank,mydim1,maxdims); - } - else - { - if (unlimiteddim) - { - dataspace=H5Screate_simple(rank, mydim, maxdims); - } - else - { - /* dataset creation */ - dataspace=H5Screate_simple(rank, mydim, NULL); - } - } - datatype1=H5Tcopy(type); - if (datatype == NX_CHAR) - { - H5Tset_size(datatype1, byte_zahl); - /* H5Tset_strpad(H5T_STR_SPACEPAD); */ - } - compress_level = 6; - if ( (compress_type / 100) == NX_COMP_LZW ) - { - compress_level = compress_type % 100; - compress_type = NX_COMP_LZW; - } - if(compress_type == NX_COMP_LZW) - { - cparms = H5Pcreate(H5P_DATASET_CREATE); - iNew = H5Pset_chunk(cparms,rank,chunkdims); - if (iNew < 0) - { - NXReportError( "ERROR: size of chunks could not be set"); - return NX_ERROR; - } - H5Pset_deflate(cparms,compress_level); - iRet = H5Dcreate(pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT, cparms, H5P_DEFAULT); - } - else if (compress_type == NX_COMP_NONE) - { - if (unlimiteddim) - { - cparms = H5Pcreate(H5P_DATASET_CREATE); - iNew = H5Pset_chunk(cparms,rank,chunkdims); - if (iNew < 0) - { - NXReportError( "ERROR: size of chunks could not be set"); - return NX_ERROR; - } - iRet = H5Dcreate(pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT, cparms, H5P_DEFAULT); - } - else - { - iRet = H5Dcreate(pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - } - } - else if (compress_type == NX_CHUNK) - { - cparms = H5Pcreate(H5P_DATASET_CREATE); - iNew = H5Pset_chunk(cparms,rank,chunkdims); - if (iNew < 0) - { - NXReportError("ERROR: size of chunks could not be set"); - return NX_ERROR; - } - iRet = H5Dcreate(pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT, cparms, H5P_DEFAULT); - - } - else - { - NXReportError( - "HDF5 doesn't support selected compression method! Dataset was saved without compression"); - iRet = H5Dcreate (pFile->iCurrentG, (char*)name, datatype1, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); - } - if (iRet < 0) - { - NXReportError( "ERROR: creating chunked dataset failed"); - return NX_ERROR; - } - else - { - pFile->iCurrentD = iRet; - } - if (unlimiteddim) - { - iNew = H5Dset_extent (pFile->iCurrentD, size); - if (iNew < 0) - { - sprintf (pBuffer, "ERROR: cannot create dataset %s", - name); - NXReportError( pBuffer); - return NX_ERROR; - } - } - if (cparms != -1) - { - iRet = H5Pclose(cparms); - } - iRet = H5Sclose(dataspace); - iRet = H5Tclose(datatype1); - iRet = H5Dclose(pFile->iCurrentD); - pFile->iCurrentD = 0; - if (iRet < 0) - { - NXReportError( "ERROR: HDF cannot close dataset"); - return NX_ERROR; - } - return NX_OK; - } - - - /* --------------------------------------------------------------------- */ - - NXstatus NX5makedata64 (NXhandle fid, CONSTCHAR *name, int datatype, - int rank, int64_t dimensions[]) - { - int64_t chunk_size[H5S_MAX_RANK]; - int i; - - NXI5assert(fid); - - memset(chunk_size,0,H5S_MAX_RANK*sizeof(int64_t)); - memcpy(chunk_size,dimensions,rank*sizeof(int64_t)); - for(i = 0; i< rank; i++) { - if (dimensions[i] == NX_UNLIMITED || dimensions[i] <= 0){ - chunk_size[i]= 1; - } - } - return NX5compmakedata64 (fid, name, datatype, rank, dimensions, NX_COMP_NONE, chunk_size); - } - - - /* --------------------------------------------------------------------- */ - - NXstatus NX5compress (NXhandle fid, int compress_type) - { - printf(" NXcompress ERROR: NeXus API based on HDF5 doesn't support\n"); - printf(" NXcompress function! Using HDF5 library,\n"); - printf(" the NXcompmakedata function can be applied\n"); - printf(" for compression of data!\n"); - return NX_ERROR; - } - - /* --------------------------------------------------------------------- */ - - NXstatus NX5opendata (NXhandle fid, CONSTCHAR *name) - { - pNexusFile5 pFile; - char pBuffer[256]; - - pFile = NXI5assert (fid); - /* clear pending attribute directories first */ - NXI5KillAttDir (pFile); - - - /* find the ID number and open the dataset */ - pFile->iCurrentD = H5Dopen(pFile->iCurrentG, name, H5P_DEFAULT); - if (pFile->iCurrentD < 0) { - sprintf (pBuffer, "ERROR: dataset \"%s\" not found at this level", name); - NXReportError( pBuffer); - return NX_ERROR; - } - /* find the ID number of datatype */ - pFile->iCurrentT = H5Dget_type(pFile->iCurrentD); - if (pFile->iCurrentT < 0) { - NXReportError( "ERROR: error opening dataset"); - pFile->iCurrentT=0; - return NX_ERROR; - } - /* find the ID number of dataspace */ - pFile->iCurrentS = H5Dget_space(pFile->iCurrentD); - if (pFile->iCurrentS < 0) { - NXReportError( "ERROR:HDF error opening dataset"); - pFile->iCurrentS=0; - return NX_ERROR; - } - if(pFile->iCurrentLD != NULL){ - free(pFile->iCurrentLD); - } - pFile->iCurrentLD = strdup(name); - return NX_OK; - } - - /* ----------------------------------------------------------------- */ - - NXstatus NX5closedata (NXhandle fid) - { - pNexusFile5 pFile; - herr_t iRet; - - pFile = NXI5assert (fid); - iRet = H5Sclose(pFile->iCurrentS); - iRet = H5Tclose(pFile->iCurrentT); - iRet = H5Dclose(pFile->iCurrentD); - if (iRet < 0) { - NXReportError( "ERROR: cannot end access to dataset"); - return NX_ERROR; - } - pFile->iCurrentD=0; - return NX_OK; - } - - /* ------------------------------------------------------------------- */ - - - - NXstatus NX5putdata (NXhandle fid, const void *data) - { - pNexusFile5 pFile; - herr_t iRet; - int64_t myStart[H5S_MAX_RANK]; - int64_t mySize[H5S_MAX_RANK]; - hsize_t thedims[H5S_MAX_RANK],maxdims[H5S_MAX_RANK]; - int i, rank, unlimiteddim = 0; - - char pError[512] = ""; - - pFile = NXI5assert (fid); - rank = H5Sget_simple_extent_ndims(pFile->iCurrentS); - if (rank < 0) - { - NXReportError("ERROR: Cannot determine dataset rank"); - return NX_ERROR; - } - iRet = H5Sget_simple_extent_dims(pFile->iCurrentS, thedims, maxdims); - if (iRet < 0) - { - NXReportError("ERROR: Cannot determine dataset dimensions"); - return NX_ERROR; - } - for(i=0; iiCurrentD, pFile->iCurrentT, H5S_ALL, H5S_ALL, - H5P_DEFAULT, data); - if (iRet < 0) { - snprintf (pError,sizeof(pError)-1, "ERROR: failure to write data"); - NXReportError( pError); - return NX_ERROR; - } - } - return NX_OK; - } -/*------------------------------------------------------------------*/ -static int getAttVID(pNexusFile5 pFile){ - int vid; - if(pFile->iCurrentG == 0 && pFile->iCurrentD == 0){ - /* global attribute */ - vid = H5Gopen(pFile->iFID,"/", H5P_DEFAULT); - } else if(pFile->iCurrentD != 0) { - /* dataset attribute */ - vid = pFile->iCurrentD; - } else { - /* group attribute */; - vid = pFile->iCurrentG; - } - return vid; -} -/*---------------------------------------------------------------*/ -static void killAttVID(pNexusFile5 pFile, int vid){ - if(pFile->iCurrentG == 0 && pFile->iCurrentD == 0){ - H5Gclose(vid); - } -} - /* ------------------------------------------------------------------- */ - - NXstatus NX5putattr (NXhandle fid, CONSTCHAR *name, const void *data, - - int datalen, int iType) - { - pNexusFile5 pFile; - hid_t attr1, aid1, aid2; - hid_t type; - herr_t iRet; - int vid; - - pFile = NXI5assert (fid); - - type = nxToHDF5Type(iType); - - /* determine vid */ - vid = getAttVID(pFile); - aid2=H5Screate(H5S_SCALAR); - aid1=H5Tcopy(type); - if (iType == NX_CHAR){ - H5Tset_size(aid1,datalen); - } - iRet = H5Aopen_by_name(vid, ".", name, H5P_DEFAULT, H5P_DEFAULT); - if (iRet>0) { - H5Aclose(iRet); - iRet=H5Adelete(vid,name); - if (iRet<0) { - NXReportError( "ERROR: old attribute cannot be removed! "); - killAttVID(pFile,vid); - return NX_ERROR; - } - } - attr1 = H5Acreate(vid, name, aid1, aid2, H5P_DEFAULT, H5P_DEFAULT); - if (attr1 < 0) { - NXReportError( "ERROR: attribute cannot created! "); - killAttVID(pFile,vid); - return NX_ERROR; - } - if (H5Awrite(attr1,aid1,data) < 0) { - NXReportError( "ERROR: failed to store attribute "); - killAttVID(pFile,vid); - return NX_ERROR; - } - /* Close attribute dataspace */ - iRet=H5Tclose(aid1); - iRet=H5Sclose(aid2); - /* Close attribute */ - iRet=H5Aclose(attr1); - killAttVID(pFile,vid); - return NX_OK; - } - - /* ------------------------------------------------------------------- */ - - NXstatus NX5putslab64 (NXhandle fid, const void *data, const int64_t iStart[], const int64_t iSize[]) - { - pNexusFile5 pFile; - int iRet, rank, i; - hsize_t myStart[H5S_MAX_RANK]; - hsize_t mySize[H5S_MAX_RANK]; - hsize_t size[H5S_MAX_RANK],thedims[H5S_MAX_RANK],maxdims[H5S_MAX_RANK]; - hid_t filespace,dataspace; - int unlimiteddim = 0; - - pFile = NXI5assert (fid); - /* check if there is an Dataset open */ - if (pFile->iCurrentD == 0) { - NXReportError( "ERROR: no dataset open"); - return NX_ERROR; - } - rank = H5Sget_simple_extent_ndims(pFile->iCurrentS); - if (rank < 0) { - NXReportError( "ERROR: cannot get rank"); - return NX_ERROR; - } - iRet = H5Sget_simple_extent_dims(pFile->iCurrentS, thedims, maxdims); - if (iRet < 0) { - NXReportError( "ERROR: cannot get dimensions"); - return NX_ERROR; - } - - for(i = 0; i < rank; i++) - { - myStart[i] = iStart[i]; - mySize[i] = iSize[i]; - size[i] = iStart[i] + iSize[i]; - if (maxdims[i] == H5S_UNLIMITED) { - unlimiteddim = 1; - } - } - if (H5Tget_class(pFile->iCurrentT) == H5T_STRING) - { - mySize[rank - 1] = 1; - myStart[rank - 1] = 0; - size[rank - 1] = 1; - } - dataspace = H5Screate_simple(rank, mySize, NULL); - if (unlimiteddim) - { - for(i = 0; i < rank; i++) - { - if (size[i] < thedims[i]) { - size[i] = thedims[i]; - } - } - iRet = H5Dset_extent(pFile->iCurrentD, size); - if (iRet < 0) - { - NXReportError( "ERROR: extend slab failed"); - return NX_ERROR; - } - - filespace = H5Dget_space(pFile->iCurrentD); - - /* define slab */ - iRet = H5Sselect_hyperslab(filespace, H5S_SELECT_SET, myStart, - NULL, mySize, NULL); - /* deal with HDF errors */ - if (iRet < 0) - { - NXReportError( "ERROR: selecting slab failed"); - return NX_ERROR; - } - /* write slab */ - iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace, - filespace, H5P_DEFAULT, data); - if (iRet < 0) - { - NXReportError( "ERROR: writing slab failed"); - } - /* update with new size */ - iRet = H5Sclose(pFile->iCurrentS); - pFile->iCurrentS = filespace; - } else { - /* define slab */ - iRet = H5Sselect_hyperslab(pFile->iCurrentS, H5S_SELECT_SET, myStart, - NULL, mySize, NULL); - /* deal with HDF errors */ - if (iRet < 0) - { - NXReportError( "ERROR: selecting slab failed"); - return NX_ERROR; - } - /* write slab */ - iRet = H5Dwrite(pFile->iCurrentD, pFile->iCurrentT, dataspace, - pFile->iCurrentS, H5P_DEFAULT, data); - if (iRet < 0) - { - NXReportError( "ERROR: writing slab failed"); - } - } - /* deal with HDF errors */ - iRet = H5Sclose(dataspace); - if (iRet < 0) - { - NXReportError( "ERROR: closing slab failed"); - return NX_ERROR; - } - return NX_OK; - } - - /* ------------------------------------------------------------------- */ - - NXstatus NX5getdataID (NXhandle fid, NXlink* sRes) - { - pNexusFile5 pFile; - int datalen, type = NX_CHAR; - - pFile = NXI5assert (fid); - - /* - we cannot return ID's when no datset is open - */ - if(pFile->iCurrentD <= 0){ - return NX_ERROR; - } - - /* - this means: if the item is already linked: use the target attribute else, - the path to the current node - */ - NXMDisableErrorReporting(); - datalen = 1024; - memset(&sRes->targetPath,0,datalen*sizeof(char)); - if(NX5getattr(fid,"target",&sRes->targetPath,&datalen,&type) != NX_OK) - { - buildCurrentPath(pFile, sRes->targetPath, 1024); - } - NXMEnableErrorReporting(); - sRes->linkType = 1; - return NX_OK; - } - - /* ------------------------------------------------------------------- */ - - NXstatus NX5printlink (NXhandle fid, NXlink* sLink) - { - NXI5assert(fid); - printf("HDF5 link: targetPath = \"%s\", linkType = \"%d\"\n", sLink->targetPath, sLink->linkType); - return NX_OK; - } -/*--------------------------------------------------------------------*/ -static NXstatus NX5settargetattribute(pNexusFile5 pFile, NXlink *sLink) -{ - hid_t dataID, aid2, aid1, attID; - herr_t status; - char name[] = "target"; - - /* - set the target attribute - */ - if(sLink->linkType > 0) - { - dataID = H5Dopen(pFile->iFID,sLink->targetPath, H5P_DEFAULT); - } else { - dataID = H5Gopen(pFile->iFID,sLink->targetPath, H5P_DEFAULT); - } - if(dataID < 0) - { - NXReportError("Internal error, path to link does not exist"); - return NX_ERROR; - } - status = H5Aopen_by_name(dataID,".", name, H5P_DEFAULT, H5P_DEFAULT); - 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->targetPath)); - attID = H5Acreate(dataID,name,aid1,aid2,H5P_DEFAULT, H5P_DEFAULT); - if(attID < 0) - { - return NX_OK; - } - status = H5Awrite(attID,aid1,sLink->targetPath); - H5Tclose(aid1); - H5Sclose(aid2); - H5Aclose(attID); - if(sLink->linkType > 0){ - H5Dclose(dataID); - } else { - H5Gclose(dataID); - } - return NX_OK; -} -/*---------------------------------------------------------------------*/ -NXstatus NX5makenamedlink(NXhandle fid, CONSTCHAR *name, NXlink *sLink) -{ - pNexusFile5 pFile; - char linkTarget[1024]; - - pFile = NXI5assert (fid); - if (pFile->iCurrentG == 0) { /* root level, can not link here */ - return NX_ERROR; - } - - /* - build pathname to link from our current group and the name - of the thing to link - */ - if(strlen(pFile->name_ref) + strlen(name) + 2 < 1024) - { - strcpy(linkTarget,"/"); - strcat(linkTarget,pFile->name_ref); - strcat(linkTarget,"/"); - strcat(linkTarget,name); - } - else - { - NXReportError("ERROR: path string to long"); - return NX_ERROR; - } - - //targetid = H5Oopen(pFile->iFID, sLink->targetPath, H5P_DEFAULT); - H5Lcreate_hard(pFile->iFID, sLink->targetPath, H5L_SAME_LOC, linkTarget, H5P_DEFAULT, H5P_DEFAULT); - //H5Oclose(targetid); - - return NX5settargetattribute(pFile,sLink); -} - /* ------------------------------------------------------------------- */ - - NXstatus NX5makelink (NXhandle fid, NXlink* sLink) - { - pNexusFile5 pFile; - char linkTarget[1024]; - char *itemName = NULL; - - pFile = NXI5assert (fid); - if (pFile->iCurrentG == 0) { /* root level, can not link here */ - return NX_ERROR; - } - - /* - locate name of the element to link - */ - itemName = strrchr(sLink->targetPath,'/'); - if(itemName == NULL){ - NXReportError("ERROR: bad link structure"); - return NX_ERROR; - } - itemName++; - - /* - build pathname to link from our current group and the name - of the thing to link - */ - if(strlen(pFile->name_ref) + strlen(itemName) + 2 < 1024) - { - strcpy(linkTarget,"/"); - strcat(linkTarget,pFile->name_ref); - strcat(linkTarget,"/"); - strcat(linkTarget,itemName); - } - else - { - NXReportError("ERROR: path string to long"); - return NX_ERROR; - } - - //targetid = H5Oopen(pFile->iFID, sLink->targetPath, H5P_DEFAULT); - H5Lcreate_hard(pFile->iFID, sLink->targetPath, H5L_SAME_LOC, linkTarget, H5P_DEFAULT, H5P_DEFAULT); - //H5Oclose(targetid); - - return NX5settargetattribute(pFile,sLink); - } - - /*----------------------------------------------------------------------*/ - - NXstatus NX5flush(NXhandle *pHandle) - { - pNexusFile5 pFile = NULL; - herr_t iRet; - - pFile = NXI5assert (*pHandle); - if (pFile->iCurrentD != 0) - { - iRet=H5Fflush(pFile->iCurrentD,H5F_SCOPE_LOCAL); - } - else if (pFile->iCurrentG != 0) - { - iRet=H5Fflush(pFile->iCurrentG,H5F_SCOPE_LOCAL); - } - else - { - iRet=H5Fflush(pFile->iFID,H5F_SCOPE_LOCAL); - } - if (iRet < 0){ - NXReportError( "ERROR: The object cannot be flushed"); - return NX_ERROR; - } - return NX_OK; - } - - /*-------------------------------------------------------------------------*/ - - /* Operator function. */ - - herr_t nxgroup_info(hid_t loc_id, const char *name, const H5L_info_t *statbuf, void *op_data) - { - pinfo self = (pinfo) op_data; - H5O_info_t object_info; - H5Oget_info_by_name(loc_id, name, &object_info, H5P_DEFAULT); - switch ((object_info).type) { - case H5O_TYPE_GROUP: - self->iname = strdup(name); - self->type = H5O_TYPE_GROUP; - break; - case H5O_TYPE_DATASET: - self->iname = strdup(name); - self->type = H5O_TYPE_DATASET; - break; - default: - // TODO defaults to group. not what we would want? - self->type=0; - break; - } - return 1; - } - /* --------------------------------------------------------------------- */ - - /* Operator function. */ - - herr_t group_info1(hid_t loc_id, const char *name, const H5L_info_t *statbuf, void *opdata) - { - int iNX = *((int*)opdata); - H5O_info_t object_info; - H5Oget_info_by_name(loc_id, name, &object_info, H5P_DEFAULT); - switch ((object_info).type) { - case H5O_TYPE_GROUP: - iNX++; - *((int*)opdata)=iNX; - break; - case H5O_TYPE_DATASET: - iNX++; - *((int*)opdata)=iNX; - break; - default: - break; - } - return 0; - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NX5getgroupinfo_recurse(NXhandle fid, int *iN, NXname pName, NXname pClass) - { - pNexusFile5 pFile; - hid_t atype, attr_id, grp; - char data[64]; - - pFile = NXI5assert (fid); - /* check if there is a group open */ - if (pFile->iCurrentG == 0) { - strcpy (pName, "root"); - strcpy (pClass, "NXroot"); - pFile->iNX=0; - grp = H5Gopen(pFile->iFID,"/",H5P_DEFAULT); - H5Literate(grp, H5_INDEX_NAME, H5_ITER_INC, 0, group_info1, &pFile->iNX); - H5Gclose(grp); - *iN=pFile->iNX; - } - else { - strcpy (pName,pFile->name_ref); - attr_id = H5Aopen_by_name(pFile->iCurrentG,".", "NX_class", H5P_DEFAULT, H5P_DEFAULT); - if (attr_id<0) { - strcpy(pClass, NX_UNKNOWN_GROUP); - } else { - atype=H5Tcopy(H5T_C_S1); - H5Tset_size(atype,sizeof(data)); - H5Aread(attr_id, atype, data); - strcpy(pClass,data); - pFile->iNX=0; - grp = H5Gopen(pFile->iFID,pFile->name_ref,H5P_DEFAULT); - H5Literate(grp, H5_INDEX_NAME, H5_ITER_INC, 0, group_info1, &pFile->iNX); - H5Gclose(grp); - *iN=pFile->iNX; - H5Aclose(attr_id); - } - } - return NX_OK; - } -/*---------------------------------------------------------------------------*/ -static int countObjectsInGroup(hid_t loc_id) -{ - int count = 0; - H5G_info_t numobj; - - herr_t status; - - status = H5Gget_info(loc_id, &numobj); - if(status < 0) { - NXReportError("Internal error, failed to retrive no of objects"); - return 0; - } - - count = numobj.nlinks; - return count; -} -/*----------------------------------------------------------------------------*/ - NXstatus NX5getgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass) - { - pNexusFile5 pFile; - hid_t atype, attr_id, gid; - char data[64]; - - pFile = NXI5assert (fid); - /* check if there is a group open */ - if (pFile->iCurrentG == 0) { - strcpy (pName, "root"); - strcpy (pClass, "NXroot"); - gid = H5Gopen(pFile->iFID,"/", H5P_DEFAULT); - *iN = countObjectsInGroup(gid); - H5Gclose(gid); - } - else { - strcpy (pName,pFile->name_ref); - attr_id = H5Aopen_by_name(pFile->iCurrentG,".", "NX_class", H5P_DEFAULT, H5P_DEFAULT); - if (attr_id<0) { - strcpy(pClass, NX_UNKNOWN_GROUP); - } else { - atype=H5Tcopy(H5T_C_S1); - H5Tset_size(atype,sizeof(data)); - H5Aread(attr_id, atype, data); - strcpy(pClass,data); - pFile->iNX=0; - *iN = countObjectsInGroup(pFile->iCurrentG); - H5Aclose(attr_id); - } - } - return NX_OK; - } - - -/*------------------------------------------------------------------------- - * Function: hdf5ToNXType - * - * Purpose: Convert a HDF5 class to a NeXus type; it handles the following HDF5 classes - * H5T_STRING - * H5T_INTEGER - * H5T_FLOAT - * - * Return: the NeXus type - * - *------------------------------------------------------------------------- - */ - static int hdf5ToNXType(H5T_class_t tclass, hid_t atype) - { - int iPtype = -1; - size_t size; - H5T_sign_t sign; - - if (tclass==H5T_STRING) - { - iPtype=NX_CHAR; - } - else if (tclass==H5T_INTEGER) - { - size=H5Tget_size(atype); - sign=H5Tget_sign(atype); - if (size==1) - { - if (sign==H5T_SGN_2) - { - iPtype=NX_INT8; - } else { - iPtype=NX_UINT8; - } - } - else if (size==2) - { - if (sign==H5T_SGN_2) - { - iPtype=NX_INT16; - } else { - iPtype=NX_UINT16; - } - } - else if (size==4) - { - if (sign==H5T_SGN_2) - { - iPtype=NX_INT32; - } else { - iPtype=NX_UINT32; - } - } - else if(size == 8) - { - if (sign==H5T_SGN_2) - { - iPtype=NX_INT64; - } else { - iPtype=NX_UINT64; - } - } - } - else if (tclass==H5T_FLOAT) - { - size=H5Tget_size(atype); - if (size==4) - { - iPtype=NX_FLOAT32; - } - else if (size==8) - { - iPtype=NX_FLOAT64; - } - } - if (iPtype == -1) - { - NXReportError( "ERROR: hdf5ToNXtype: invalid type"); - } - - return iPtype; - } -/*--------------------------------------------------------------------------*/ - static hid_t h5MemType(hid_t atype) - { - hid_t memtype_id = -1; - size_t size; - H5T_sign_t sign; - H5T_class_t tclass; - - tclass = H5Tget_class(atype); - - if (tclass==H5T_INTEGER) - { - size=H5Tget_size(atype); - sign=H5Tget_sign(atype); - if (size==1) - { - if (sign==H5T_SGN_2) - { - memtype_id = H5T_NATIVE_INT8; - } else { - memtype_id = H5T_NATIVE_UINT8; - } - } - else if (size==2) - { - if (sign==H5T_SGN_2) - { - memtype_id = H5T_NATIVE_INT16; - } else { - memtype_id = H5T_NATIVE_UINT16; - } - } - else if (size==4) - { - if (sign==H5T_SGN_2) - { - memtype_id = H5T_NATIVE_INT32; - } else { - memtype_id = H5T_NATIVE_UINT32; - } - } - else if (size==8) - { - if (sign==H5T_SGN_2) - { - memtype_id = H5T_NATIVE_INT64; - } else { - memtype_id = H5T_NATIVE_UINT64; - } - } - } else if (tclass==H5T_FLOAT) - { - size=H5Tget_size(atype); - if (size==4) - { - memtype_id = H5T_NATIVE_FLOAT; - } else if (size==8) { - memtype_id = H5T_NATIVE_DOUBLE; - } - } - if (memtype_id == -1) - { - NXReportError( "ERROR: h5MemType: invalid type"); - } - return memtype_id; - } - /*-------------------------------------------------------------------------*/ - - NXstatus NX5getnextentry(NXhandle fid, NXname name, NXname nxclass, int *datatype) - { - pNexusFile5 pFile; - hid_t grp, attr1,type,atype; - herr_t iRet; - int iPtype, i; - hsize_t idx; - H5T_class_t tclass; - char data[128]; - char ph_name[1024]; - info_type op_data; - herr_t iRet_iNX=-1; - char pBuffer[256]; - - pFile = NXI5assert (fid); - op_data.iname = NULL; - - /* - iterate to next entry in group list - */ - idx=pFile->iStack5[pFile->iStackPtr].iCurrentIDX; - if (strlen(pFile->name_ref) == 0) { - /* root group */ - strcpy(pFile->name_ref,"/"); - } - grp = H5Gopen(pFile->iFID, pFile->name_ref, H5P_DEFAULT); - // index can be wrong here - iRet=H5Literate(grp, H5_INDEX_NAME, H5_ITER_INC, &idx, nxgroup_info, &op_data); - H5Gclose(grp); - strcpy(nxclass, NX_UNKNOWN_GROUP); - - /* - figure out the number of items in the current group. We need this in order to - find out if we are at the end of the search. - */ - if (pFile->iCurrentG == 0) { - // if pFile->iCurrentG == 0 would not pFile->name_ref be "/" already, so we could skip that if statement ? - pFile->iNX=0; - grp = H5Gopen(pFile->iFID, "/", H5P_DEFAULT); - iRet_iNX=H5Literate(grp, H5_INDEX_NAME, H5_ITER_INC, 0, group_info1, &pFile->iNX); - H5Gclose(grp); - } else { - pFile->iNX=0; - grp = H5Gopen(pFile->iFID, pFile->name_ref, H5P_DEFAULT); - // index can be wrong here - iRet_iNX=H5Literate(grp, H5_INDEX_NAME, H5_ITER_INC, 0, group_info1, &pFile->iNX); - H5Gclose(grp); - } - if (idx == pFile->iNX) { - // why 2? - iRet_iNX = 2; - } - - if (iRet > 0) - { - pFile->iStack5[pFile->iStackPtr].iCurrentIDX++; - if (op_data.iname != NULL) { - strcpy(name,op_data.iname); - free(op_data.iname); - } else { - pFile->iStack5[pFile->iStackPtr].iCurrentIDX = 0; - return NX_EOD; - } - if (op_data.type == H5O_TYPE_GROUP) { - /* - open group and find class name attribute - */ - strcpy(ph_name,""); - for(i = 1; i < (pFile->iStackPtr + 1); i++) - { - strcat(ph_name,pFile->iStack5[i].irefn); - strcat(ph_name,"/"); - } - strcat(ph_name,name); - grp = H5Gopen(pFile->iFID,ph_name, H5P_DEFAULT); - if (grp < 0) { - sprintf(pBuffer, "ERROR: group %s does not exist", ph_name); - NXReportError(pBuffer); - return NX_ERROR; - } - attr1 = H5Aopen_by_name(grp,".", "NX_class", H5P_DEFAULT, H5P_DEFAULT); - if (attr1 < 0) { - strcpy(nxclass, NX_UNKNOWN_GROUP); - } else { - type=H5T_C_S1; - atype=H5Tcopy(type); - H5Tset_size(atype,sizeof(data)); - iRet = H5Aread(attr1, atype, data); - strcpy(nxclass,data); - H5Tclose(atype); - H5Aclose(attr1); - } - H5Gclose(grp); - } else if (op_data.type==H5O_TYPE_DATASET) { - /* - open dataset and find type - */ - grp=H5Dopen(pFile->iCurrentG,name, H5P_DEFAULT); - type=H5Dget_type(grp); - atype=H5Tcopy(type); - tclass = H5Tget_class(atype); - iPtype = hdf5ToNXType(tclass, atype); - *datatype=iPtype; - strcpy(nxclass, "SDS"); - H5Tclose(atype); - H5Tclose(type); - H5Dclose(grp); - } - return NX_OK; - } else { - /* - we are at the end of the search: clear the data structure and reset - iCurrentIDX to 0 - */ - if (iRet_iNX == 2) { - if (op_data.iname != NULL) { - free(op_data.iname); - } - pFile->iStack5[pFile->iStackPtr].iCurrentIDX = 0; - return NX_EOD; - } - if (op_data.iname != NULL) { - free(op_data.iname); - } - NXReportError("ERROR: iterating through group not successful"); - return NX_ERROR; - } - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NX5getdata (NXhandle fid, void *data) - { - pNexusFile5 pFile; - int iStart[H5S_MAX_RANK], status; - hid_t memtype_id; - H5T_class_t tclass; - int dims; - - pFile = NXI5assert (fid); - /* check if there is an Dataset open */ - if (pFile->iCurrentD == 0) - { - NXReportError( "ERROR: no dataset open"); - return NX_ERROR; - } - memset (iStart, 0, H5S_MAX_RANK * sizeof(int)); - /* map datatypes of other plateforms */ - tclass = H5Tget_class(pFile->iCurrentT); - if (tclass==H5T_STRING) - { - dims = H5Tget_size(pFile->iCurrentT); - memtype_id = H5Tcopy(H5T_C_S1); - H5Tset_size(memtype_id, dims); - } - else - { - memtype_id = h5MemType(pFile->iCurrentT); - } - - /* actually read */ - status = H5Dread (pFile->iCurrentD, memtype_id, - H5S_ALL, H5S_ALL,H5P_DEFAULT, data); - if(tclass == H5T_STRING) - { - H5Tclose(memtype_id); - } - if(status < 0) - { - NXReportError( "ERROR: failed to transfer dataset"); - return NX_ERROR; - - } - return NX_OK; - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NX5getinfo64 (NXhandle fid, int *rank, int64_t dimension[], int *iType) - { - pNexusFile5 pFile; - int i, iRank, mType; - hsize_t myDim[H5S_MAX_RANK]; - H5T_class_t tclass; - - pFile = NXI5assert (fid); - /* check if there is an Dataset open */ - if (pFile->iCurrentD == 0) { - NXReportError( "ERROR: no dataset open"); - return NX_ERROR; - } - - /* read information */ - tclass = H5Tget_class(pFile->iCurrentT); - mType = hdf5ToNXType(tclass,pFile->iCurrentT); - iRank = H5Sget_simple_extent_ndims(pFile->iCurrentS); - H5Sget_simple_extent_dims(pFile->iCurrentS, myDim, NULL); - /* conversion to proper ints for the platform */ - *iType = (int)mType; - if (tclass==H5T_STRING && myDim[iRank-1] == 1) { - myDim[iRank-1] = H5Tget_size(pFile->iCurrentT); - } - *rank = (int)iRank; - for (i = 0; i < iRank; i++) - { - dimension[i] = (int)myDim[i]; - } - return NX_OK; - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NX5getslab64 (NXhandle fid, void *data, const int64_t iStart[], const int64_t iSize[]) - { - pNexusFile5 pFile; - hsize_t myStart[H5S_MAX_RANK]; - hsize_t mySize[H5S_MAX_RANK]; - hsize_t mStart[H5S_MAX_RANK]; - hid_t memspace, iRet; - H5T_class_t tclass; - hid_t memtype_id; - char *tmp_data = NULL; - char *data1; - int i, dims, iRank, mtype = 0; - - pFile = NXI5assert (fid); - /* check if there is an Dataset open */ - if (pFile->iCurrentD == 0) - { - NXReportError( "ERROR: no dataset open"); - return NX_ERROR; - } - iRank = H5Sget_simple_extent_ndims(pFile->iCurrentS); - for (i = 0; i < iRank; i++) - { - myStart[i] = (hssize_t)iStart[i]; - mySize[i] = (hsize_t)iSize[i]; - mStart[i] = (hsize_t)0; - } - tclass = H5Tget_class(pFile->iCurrentT); - if (tclass == H5T_STRING) { -/* - * 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) { - mySize[0] = H5Tget_size(pFile->iCurrentT); - } - tmp_data = (char*) malloc(mySize[0]); - memset(tmp_data,0,sizeof(mySize[0])); - iRet = H5Sselect_hyperslab(pFile->iCurrentS, H5S_SELECT_SET, mStart, - NULL, mySize, NULL); - } else { - iRet = H5Sselect_hyperslab(pFile->iCurrentS, H5S_SELECT_SET, myStart, - NULL, mySize, NULL); - } - /* define slab */ - /* deal with HDF errors */ - if (iRet < 0) - { - NXReportError( "ERROR: selecting slab failed"); - return NX_ERROR; - } - - memspace=H5Screate_simple(iRank, mySize, NULL); - iRet = H5Sselect_hyperslab(memspace, H5S_SELECT_SET, mStart, - NULL, mySize, NULL); - if (iRet < 0) - { - NXReportError( "ERROR: selecting memspace failed"); - return NX_ERROR; - } - /* map datatypes of other plateforms */ - if (tclass == H5T_STRING) - { - dims = H5Tget_size(pFile->iCurrentT); - memtype_id = H5Tcopy(H5T_C_S1); - H5Tset_size(memtype_id, dims); - } - else - { - memtype_id = h5MemType(pFile->iCurrentT); - } - - /* read slab */ - if (mtype == NX_CHAR) { - iRet = H5Dread(pFile->iCurrentD, memtype_id, H5S_ALL, - H5S_ALL, H5P_DEFAULT,tmp_data); - data1 = tmp_data + myStart[0]; - strncpy((char*)data,data1,(hsize_t)iSize[0]); - free(tmp_data); - } else { - iRet = H5Dread(pFile->iCurrentD, memtype_id, memspace, - pFile->iCurrentS, H5P_DEFAULT,data); - } - /* cleanup */ - if (tclass == H5T_STRING) { /* we used H5Tcopy */ - H5Tclose(memtype_id); - } - H5Sclose(memspace); - - if (iRet < 0) - - { - NXReportError( "ERROR: reading slab failed"); - return NX_ERROR; - } - return NX_OK; - } - - /*-------------------------------------------------------------------------*/ - - /* Operator function. */ - - herr_t attr_info(hid_t loc_id, const char *name, const H5A_info_t *unused, void *opdata) - { - *((char**)opdata)=strdup(name); - return 1; - } - - NXstatus NX5getnextattr (NXhandle fileid, NXname pName, int *iLength, int *iType) - { - pNexusFile5 pFile; - hid_t attr_id; - hid_t atype, aspace; - herr_t iRet; - int iPType,rank; - char *iname = NULL; - hsize_t idx, intern_idx=-1; - int vid; - H5O_info_t oinfo; - - pFile = NXI5assert (fileid); - - vid = getAttVID(pFile); - - pName[0] = '\0'; - idx=pFile->iAtt5.iCurrentIDX; - iRet=0; - - H5Oget_info(vid, &oinfo); - intern_idx=oinfo.num_attrs; - if(intern_idx == idx) { - killAttVID(pFile,vid); - return NX_EOD; - } - - if (intern_idx > idx) { - iRet=H5Aiterate(vid,H5_INDEX_CRT_ORDER,H5_ITER_INC,&idx,attr_info,&iname); - } else { - iRet=0; - } - intern_idx=-1; - if (iRet < 0) { - NXReportError( "ERROR: iterating through attribute list"); - killAttVID(pFile,vid); - return NX_ERROR; - } - pFile->iAtt5.iCurrentIDX++; - if (iname != NULL) { - if(strcmp(iname, "NX_class") == 0 && pFile->iCurrentG != 0) { - /* - skip NXclass attribute which is internal - */ - killAttVID(pFile, vid); - return NX5getnextattr(fileid, pName, iLength, iType); - } - strcpy(pName, iname); - free(iname); - iname = NULL; - } else { - strcpy(pName,"What is this?"); - } - pFile->iCurrentA = H5Aopen_by_name(vid, ".", pName, H5P_DEFAULT, H5P_DEFAULT); - atype = H5Aget_type(pFile->iCurrentA); - aspace = H5Aget_space(pFile->iCurrentA); - rank = H5Sget_simple_extent_ndims(aspace); - attr_id = H5Tget_class(atype); - if (attr_id==H5T_STRING) { - iPType=NX_CHAR; - rank = H5Tget_size(atype); - } - if (rank == 0) { - rank++; - } - iPType = hdf5ToNXType(attr_id,atype); - *iType=iPType; - *iLength=rank; - H5Tclose(atype); - H5Sclose(aspace); - H5Aclose(pFile->iCurrentA); - - H5Oget_info(vid, &oinfo); - intern_idx=oinfo.num_attrs; - - killAttVID(pFile,vid); - return NX_OK; - } - /*-------------------------------------------------------------------------*/ - - NXstatus NX5getattr (NXhandle fid, char *name, - void *data, int* datalen, int* iType) - { - pNexusFile5 pFile; - int iNew, vid; - herr_t iRet; - hid_t type, atype = -1; - char pBuffer[256]; - - pFile = NXI5assert (fid); - - type = nxToHDF5Type(*iType); - - vid = getAttVID(pFile); - iNew = H5Aopen_by_name(vid, ".", name, H5P_DEFAULT, H5P_DEFAULT); - if (iNew < 0) { - sprintf (pBuffer, "ERROR: attribute \"%s\" not found", name); - killAttVID(pFile,vid); - NXReportError( pBuffer); - return NX_ERROR; - } - pFile->iCurrentA = iNew; - /* finally read the data */ - if (type==H5T_C_S1) - { - atype = H5Aget_type(pFile->iCurrentA); - H5Tclose(atype); - atype=H5Tcopy(type); - H5Tset_size(atype,*datalen); - iRet = H5Aread(pFile->iCurrentA, atype, data); - *datalen = strlen((char*)data); - } else { - iRet = H5Aread(pFile->iCurrentA, type, data); - *datalen=1; - } - - if (iRet < 0) { - sprintf (pBuffer, "ERROR: could not read attribute data"); - NXReportError( pBuffer); - killAttVID(pFile,vid); - return NX_ERROR; - } - - H5Aclose(pFile->iCurrentA); - - killAttVID(pFile,vid); - if (type==H5T_C_S1) - { - H5Tclose(atype); - } - return NX_OK; - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NX5getattrinfo (NXhandle fid, int *iN) - { - pNexusFile5 pFile; - hid_t idx; - int vid; - H5O_info_t oinfo; - - pFile = NXI5assert (fid); - idx=0; - *iN = idx; - - vid = getAttVID(pFile); - - H5Oget_info(vid, &oinfo); - idx=oinfo.num_attrs; - if (idx > 0) { - if(pFile->iCurrentG > 0 && pFile->iCurrentD == 0){ - *iN = idx -1; - } else { - *iN = idx; - } - } else { - *iN = 0; - } - killAttVID(pFile,vid); - return NX_OK; - } - - - /*-------------------------------------------------------------------------*/ - NXstatus NX5getgroupID (NXhandle fileid, NXlink* sRes) - { - pNexusFile5 pFile; - int datalen, type = NX_CHAR; - - pFile = NXI5assert (fileid); - if (pFile->iCurrentG == 0) { - return NX_ERROR; - } - else { - /* - this means: if the item is already linked: use the target attribute, else - the path to the current node - */ - NXMDisableErrorReporting(); - datalen = 1024; - memset(sRes->targetPath,0,datalen*sizeof(char)); - if(NX5getattr(fileid,"target",sRes->targetPath,&datalen,&type) != NX_OK){ - buildCurrentPath(pFile,sRes->targetPath,1024); - } - NXMEnableErrorReporting(); - sRes->linkType = 0; - return NX_OK; - } - /* not reached */ - return NX_ERROR; - } - - /* ------------------------------------------------------------------- */ - - NXstatus NX5nativeexternallink(NXhandle fileid, const char* name, const char* externalfile, const char* remotetarget) - { - herr_t iRet; - pNexusFile5 pFile; - hid_t openwhere; - - pFile = NXI5assert(fileid); - - if (pFile->iCurrentG <= 0) { - openwhere = pFile->iFID; - } else { - openwhere = pFile->iCurrentG; - } - - iRet = H5Lcreate_external(externalfile, remotetarget, openwhere, name, H5P_DEFAULT, H5P_DEFAULT); - if (iRet < 0) { - NXReportError("ERROR: making external link failed"); - return NX_ERROR; - } - return NX_OK; - } - /* ------------------------------------------------------------------- */ - - NXstatus NX5nativeinquirefile(NXhandle fileid, char* externalfile, const int filenamelen) - { - pNexusFile5 pFile; - ssize_t name_size; - hid_t openthing; - - pFile = NXI5assert(fileid); - if (pFile->iCurrentD > 0) { - openthing = pFile->iCurrentD; - } else if (pFile->iCurrentG > 0) { - openthing = pFile->iCurrentG; - } else { - openthing = pFile->iFID; - } - - name_size = H5Fget_name(openthing, externalfile, filenamelen); - - // Check for failure again - if( name_size < 0 ) { - NXReportError("ERROR: retrieving file name"); - return NX_ERROR; - } - return NX_OK; - } - /* ------------------------------------------------------------------- */ - - NXstatus NX5nativeisexternallink(NXhandle fileid, const char* name, char* url, const int urllen) - { - pNexusFile5 pFile; - herr_t ret; - H5L_info_t link_buff; - char linkval_buff[1024]; - const char *filepath = NULL, *objpath = NULL; - size_t val_size; - - pFile = NXI5assert(fileid); - memset(url, 0, urllen); - - ret = H5Lget_info(pFile->iFID, name, &link_buff, H5P_DEFAULT); - if (ret < 0 || link_buff.type != H5L_TYPE_EXTERNAL) { - return NX_ERROR; - } - - val_size = link_buff.u.val_size; - if (val_size > sizeof(linkval_buff)) { - NXReportError("ERROR: linkval_buff too small"); - return NX_ERROR; - } - - ret = H5Lget_val(pFile->iFID, name, linkval_buff, val_size, H5P_DEFAULT); - if (ret < 0) { - NXReportError("ERROR: H5Lget_val failed"); - return NX_ERROR; - } - - ret = H5Lunpack_elink_val(linkval_buff, val_size, NULL, &filepath, &objpath); - if (ret < 0) { - NXReportError("ERROR: H5Lunpack_elink_val failed"); - return NX_ERROR; - } - - snprintf(url, urllen-1, "nxfile://%s#%s", filepath, objpath); - return NX_OK; - - } - /* ------------------------------------------------------------------- */ - - NXstatus NX5sameID (NXhandle fileid, NXlink* pFirstID, NXlink* pSecondID) - { - NXI5assert(fileid); - if ((strcmp(pFirstID->targetPath,pSecondID->targetPath) == 0)){ - return NX_OK; - } else { - return NX_ERROR; - } - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NX5initattrdir (NXhandle fid) - { - pNexusFile5 pFile; - - pFile = NXI5assert (fid); - NXI5KillAttDir (pFile); - return NX_OK; - } - - /*-------------------------------------------------------------------------*/ - - NXstatus NX5initgroupdir (NXhandle fid) - { - pNexusFile5 pFile; - - pFile = NXI5assert (fid); - NXI5KillDir (pFile); - return NX_OK; - } -/*------------------------------------------------------------------------*/ -void NX5assignFunctions(pNexusFunction fHandle) -{ - - fHandle->nxclose=NX5close; - fHandle->nxreopen=NX5reopen; - fHandle->nxflush=NX5flush; - fHandle->nxmakegroup=NX5makegroup; - fHandle->nxopengroup=NX5opengroup; - fHandle->nxclosegroup=NX5closegroup; - fHandle->nxmakedata64=NX5makedata64; - fHandle->nxcompmakedata64=NX5compmakedata64; - fHandle->nxcompress=NX5compress; - fHandle->nxopendata=NX5opendata; - fHandle->nxclosedata=NX5closedata; - fHandle->nxputdata=NX5putdata; - fHandle->nxputattr=NX5putattr; - fHandle->nxputslab64=NX5putslab64; - fHandle->nxgetdataID=NX5getdataID; - fHandle->nxmakelink=NX5makelink; - fHandle->nxmakenamedlink=NX5makenamedlink; - fHandle->nxgetdata=NX5getdata; - fHandle->nxgetinfo64=NX5getinfo64; - fHandle->nxgetnextentry=NX5getnextentry; - fHandle->nxgetslab64=NX5getslab64; - fHandle->nxgetnextattr=NX5getnextattr; - fHandle->nxgetattr=NX5getattr; - fHandle->nxgetattrinfo=NX5getattrinfo; - fHandle->nxgetgroupID=NX5getgroupID; - fHandle->nxgetgroupinfo=NX5getgroupinfo; - fHandle->nxsameID=NX5sameID; - fHandle->nxinitgroupdir=NX5initgroupdir; - fHandle->nxinitattrdir=NX5initattrdir; - fHandle->nxprintlink=NX5printlink; - fHandle->nxnativeexternallink=NX5nativeexternallink; - fHandle->nxnativeinquirefile=NX5nativeinquirefile; - fHandle->nxnativeisexternallink=NX5nativeisexternallink; -} - -#endif /* HDF5 */ diff --git a/napi5.h b/napi5.h deleted file mode 100644 index 79490782..00000000 --- a/napi5.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef NAPI5_H -#define NAPI5_H - -#define NX5SIGNATURE 959695 - -#include - -/* HDF5 interface */ - -extern NXstatus NX5open(CONSTCHAR *filename, NXaccess access_method, NXhandle* pHandle); -extern NXstatus NX5reopen(NXhandle pOrigHandle, NXhandle* pNewHandle); - -extern NXstatus NX5close(NXhandle* pHandle); -extern NXstatus NX5flush(NXhandle* pHandle); - -extern NXstatus NX5makegroup (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass); -extern NXstatus NX5opengroup (NXhandle handle, CONSTCHAR *name, CONSTCHAR* NXclass); -extern NXstatus NX5closegroup(NXhandle handle); - -extern NXstatus NX5makedata64 (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[]); -extern NXstatus NX5compmakedata64 (NXhandle handle, CONSTCHAR* label, int datatype, int rank, int64_t dim[], int comp_typ, int64_t bufsize[]); -extern NXstatus NX5compress (NXhandle handle, int compr_type); -extern NXstatus NX5opendata (NXhandle handle, CONSTCHAR* label); -extern NXstatus NX5closedata(NXhandle handle); -extern NXstatus NX5putdata(NXhandle handle, const void* data); - -extern NXstatus NX5putattr(NXhandle handle, CONSTCHAR* name, const void* data, int iDataLen, int iType); -extern NXstatus NX5putslab64(NXhandle handle, const void* data, const int64_t start[], const int64_t size[]); - -extern NXstatus NX5getdataID(NXhandle handle, NXlink* pLink); -extern NXstatus NX5makelink(NXhandle handle, NXlink* pLink); -extern NXstatus NX5printlink(NXhandle handle, NXlink* pLink); - -extern NXstatus NX5getdata(NXhandle handle, void* data); -extern NXstatus NX5getinfo64(NXhandle handle, int* rank, int64_t dimension[], int* datatype); -extern NXstatus NX5getnextentry(NXhandle handle, NXname name, NXname nxclass, int* datatype); - -extern NXstatus NX5getslab64(NXhandle handle, void* data, const int64_t start[], const int64_t size[]); -extern NXstatus NX5getnextattr(NXhandle handle, NXname pName, int *iLength, int *iType); -extern NXstatus NX5getattr(NXhandle handle, char* name, void* data, int* iDataLen, int* iType); -extern NXstatus NX5getattrinfo(NXhandle handle, int* no_items); -extern NXstatus NX5getgroupID(NXhandle handle, NXlink* pLink); -extern NXstatus NX5getgroupinfo(NXhandle handle, int* no_items, NXname name, NXname nxclass); - -extern NXstatus NX5initgroupdir(NXhandle handle); -extern NXstatus NX5initattrdir(NXhandle handle); - -void NX5assignFunctions(pNexusFunction fHandle); - -herr_t attr_info(hid_t loc_id, const char *name, const H5A_info_t *unused, void *opdata); -herr_t group_info(hid_t loc_id, const char *name, const H5L_info_t *unused, void *opdata); -herr_t nxgroup_info(hid_t loc_id, const char *name, const H5L_info_t *unused, void *op_data); - -#endif /* NAPI5_H */ diff --git a/nxio.c b/nxio.c deleted file mode 100644 index eed88b54..00000000 --- a/nxio.c +++ /dev/null @@ -1,747 +0,0 @@ -/** - * 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 - */ - -#ifdef NXXML - -#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 - -#ifdef _MSC_VER -#define snprintf _snprintf -#endif /* _MSC_VER */ - -/* #define TESTMAIN 1 */ -/*=================== type code handling ================================= */ -typedef struct { - char name[30]; - char format[30]; - int nx_type; -}type_code; - -#define NTYPECODE 11 -static type_code typecode[NTYPECODE]; -/*-----------------------------------------------------------------------*/ -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_UINT32"); - strcpy(myCode.format,"%12d"); - myCode.nx_type = NX_UINT32; - typecode[7] = myCode; - - strcpy(myCode.name,"NX_INT64"); - strcpy(myCode.format,"%24lld"); - myCode.nx_type = NX_INT64; - typecode[8] = myCode; - - strcpy(myCode.name,"NX_UINT64"); - strcpy(myCode.format,"%24llu"); - myCode.nx_type = NX_UINT64; - typecode[9] = myCode; - - strcpy(myCode.name,"NX_CHAR"); - strcpy(myCode.format,"%c"); - myCode.nx_type = NX_CHAR; - typecode[10] = myCode; -} -/*----------------------------------------------------------------------*/ -void setNumberFormat(int nx_type, char *format){ - int i; - - for(i = 0; i < NTYPECODE; 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 < NTYPECODE; 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 < NTYPECODE; 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 */ - size_t *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) *= 3; - (*bufsize) /= 2; - } - - 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 - =====================================================================*/ - -/* - * if passed NX_CHAR, then returns dimension of -1 and the caller - * needs to do a strlen() or equivalent - */ -void analyzeDim(const char *typeString, int *rank, - int64_t *iDim, int *type){ - char dimString[132]; - char dim[20]; - const char *dimStart, *dimEnd; - char* dimTemp; - int myRank; - - if(strchr(typeString,(int)'[') == NULL){ - *rank = 1; - switch(*type){ - case NX_INT8: - case NX_UINT8: - case NX_INT16: - case NX_UINT16: - case NX_INT32: - case NX_UINT32: - case NX_INT64: - case NX_UINT64: - case NX_FLOAT32: - case NX_FLOAT64: - iDim[0] = 1; - break; - case NX_CHAR: - iDim[0] = -1; /* length unknown, caller needs to determine later */ - break; - default: - mxml_error("ERROR: (analyzeDim) unknown type code %d for typeString %s", *type, typeString); - 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)); - dimTemp = stptok(dimString,dim,19,","); - myRank = 0; - while(dimTemp != NULL){ - iDim[myRank] = atoi(dim); - dimTemp = stptok(dimTemp,dim,19,","); - myRank++; - } - *rank = myRank; - } -} -/*--------------------------------------------------------------------*/ -int translateTypeCode(const char *code){ - int i, result = -1; - - for(i = 0; i < NTYPECODE; i++){ - if(strstr(code,typecode[i].name) != NULL){ - result = typecode[i].nx_type; - break; - } - } - return result; -} - -/* - * This is used to locate an Idims node from the new style table data layout - */ -static mxml_node_t* findDimsNode(mxml_node_t *node) -{ - mxml_node_t *tnode = NULL; - const char* name = node->value.element.name; - if ( (node->parent != NULL) && !strcmp(node->parent->value.element.name, DATA_NODE_NAME) ) - { - tnode = mxmlFindElement(node->parent->parent, node->parent->parent, DIMS_NODE_NAME, NULL, NULL, MXML_DESCEND_FIRST); - if (tnode != NULL) - { - tnode = mxmlFindElement(tnode,tnode,name,NULL,NULL,MXML_DESCEND_FIRST); - } - } - return tnode; -} - -/*---------------------------------------------------------------------*/ -/*return 1 if in table mode , 0 if not */ -static void analyzeDataType(mxml_node_t *parent, int *rank, int *type, - int64_t *iDim){ - const char *typeString; - mxml_node_t* tnode; - int nx_type = -1; - int table_mode = 0; - - *rank = 1; - *type = NX_CHAR; - iDim[0] = -1; - - /* - get the type attribute. No attribute means: plain text - */ - tnode = findDimsNode(parent); - if (tnode != NULL) - { - table_mode = 1; - parent = tnode; - } - 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); - if (table_mode) - { - *rank = 1; - iDim[0] = 1; - } - return; -} -/*-------------------------------------------------------------------*/ -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 || - !strncmp(parent->value.element.name,"NX",2) || - !strcmp(parent->value.element.name,DATA_NODE_NAME) || - !strcmp(parent->value.element.name,DIMS_NODE_NAME)){ - return MXML_ELEMENT; - } else { - /* data nodes do not habe TYPENAME in table style but are always CUSTOM */ - if (parent->parent != NULL && !strcmp(parent->parent->value.element.name, DATA_NODE_NAME)) - { - return MXML_CUSTOM; - } - if (parent->parent != NULL && !strcmp(parent->parent->value.element.name, DIMS_NODE_NAME)) - { - return MXML_OPAQUE; - } - 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 wants. - */ - return MXML_OPAQUE; - } else{ - if(strstr(typeString,"NX_CHAR") != NULL){ - return MXML_OPAQUE; - } else { - return MXML_CUSTOM; - } - } - } -} -/*----------------------------------------------------------------------*/ -int nexusLoadCallback(mxml_node_t *node, const char *buffer){ - mxml_node_t *parent = NULL; - int rank, type; - int64_t iDim[NX_MAXRANK]; - char pNumber[80], *pStart; - long address, maxAddress; - pNXDS dataset = NULL; - - parent = node->parent; - analyzeDataType(parent,&rank,&type,iDim); - if(iDim[0] == -1 || !strcmp(parent->parent->value.element.name, DIMS_NODE_NAME)){ - 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, size_t *bufSize, - char *string){ - size_t 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_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 */ - printf("Problem\n"); - 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 currentLen, table_style = 0; - size_t i, bufsize, length; - int is_definition = 0; - /* this is set by nxconvert when making a definiton */ - is_definition = (getenv("NX_IS_DEFINITION") != NULL); - - if (!strcmp(node->parent->parent->value.element.name, DATA_NODE_NAME)) - { - table_style = 1; - } - /* - 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); - if (is_definition) { - length = 1; - } else { - length = getNXDatasetLength(dataset); - } - if(dataset->format != NULL){ - strcpy(format,dataset->format); - } else { - getNumberFormat(type,format); - } - - /* - actually get the data out - */ - if (table_style) - { - for(i = 0; i < length; i++){ - formatNumber(getNXDatasetValueAt(dataset,i),pNumber,79,format,type); - stringIntoBuffer(&buffer,&bufPtr,&bufsize,pNumber); - } - } - else - { - 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; -} -/*------------------------------------------------------------------*/ -int isDataNode(mxml_node_t *node){ - if(mxmlElementGetAttr(node,"name") != NULL){ - return 0; - } - if(strcmp(node->value.element.name,"NXroot") == 0){ - return 0; - } - if(strcmp(node->value.element.name,DIMS_NODE_NAME) == 0){ - return 0; - } - if(strcmp(node->value.element.name,DATA_NODE_NAME) == 0){ - return 0; - } - if(strcmp(node->value.element.name,"NAPIlink") == 0){ - return 0; - } - return 1; -} -/*--------------------------------------------------------------------*/ -static int isTextData(mxml_node_t *node){ - const char *attr = NULL; - - if(!isDataNode(node)){ - return 0; - } - /* - test datasets - */ - attr = mxmlElementGetAttr(node,TYPENAME); - if(attr == NULL){ - return 1; - } - if(strstr(attr,"NX_CHAR") != NULL){ - return 1; - } else { - return 0; - } -} -/*---------------------------------------------------------------------*/ - -/* - * note: not reentrant or thead safe; returns pointer to static storage - */ -const char *NXwhitespaceCallback(mxml_node_t *node, int where){ - static char *indent = NULL; - int len; - - if(strstr(node->value.element.name,"?xml") != NULL){ - return NULL; - } - if (node->parent != NULL && !strcmp(node->parent->value.element.name, DATA_NODE_NAME)) - { - return NULL; - } - if (where == MXML_WS_BEFORE_CLOSE && !strcmp(node->value.element.name, DATA_NODE_NAME)) - { - return NULL; - } - - 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); - indent[0]= '\n'; - indent[len-1] = '\0'; - return (const char*)indent; - } - } - return NULL; - } - - 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); - 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 - - -#endif /*NXXML*/ diff --git a/nxio.h b/nxio.h deleted file mode 100644 index 1788762a..00000000 --- a/nxio.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * 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" - -#define DIMS_NODE_NAME "columns" -#define DATA_NODE_NAME "row" - -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(const char *code); -int isDataNode(mxml_node_t *node); -void analyzeDim(const char *typeString, int *rank, - int64_t *iDim, int *type); - - -#endif diff --git a/nxscript.c b/nxscript.c index fc6277b1..5b68d660 100644 --- a/nxscript.c +++ b/nxscript.c @@ -926,6 +926,7 @@ static void putSlab(SConnection * pCon, SicsInterp * pSics, pNXScript self, pSICSData data = NULL; pCounter memsec = NULL; pHdb node = NULL; + double dVal; if (argc < 6) { SCWrite(pCon, "ERROR: insufficient number of arguments to putslab", @@ -991,6 +992,24 @@ static void putSlab(SConnection * pCon, SicsInterp * pSics, pNXScript self, written = 1; } } + + /** + * try to look for a single double. This is a hack to make absolute_time + * work at BOA. A cleaner solution should be devised in a later stage. + * MK, June 2013 + */ + if(written == 0) { + status = Tcl_GetDouble(InterpGetTcl(pSics), argv[5], &dVal); + if (status != TCL_OK) { + written = 0; + } else { + status = NXputslab(self->fileHandle, &dVal, start, size); + if (status == NX_OK) { + written = 1; + } + } + } + /* * drop out of hierarchy */ diff --git a/nxstack.c b/nxstack.c deleted file mode 100644 index a5ba2bd7..00000000 --- a/nxstack.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - This is some code to handle a stack of NeXus files. This is used to implement - external linking within the NeXus-API - - Copyright (C) 1997-2006 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 - - Added code to support the path stack for NXgetpath, - Mark Koennecke, October 2009 -*/ -#include -#include -#include -#include "nxstack.h" - -/*----------------------------------------------------------------------- - Data definitions ----------------------------------------------------------------------*/ - -typedef struct { - pNexusFunction pDriver; - NXlink closeID; - char filename[1024]; -}fileStackEntry; - - -typedef struct __fileStack { - int fileStackPointer; - fileStackEntry fileStack[MAXEXTERNALDEPTH]; - int pathPointer; - char pathStack[NXMAXSTACK][NX_MAXNAMELEN]; -}fileStack; -/*---------------------------------------------------------------------*/ -pFileStack makeFileStack(){ - pFileStack pNew = NULL; - - pNew = (pFileStack)malloc(sizeof(fileStack)); - if(pNew == NULL){ - return NULL; - } - memset(pNew,0,sizeof(fileStack)); - pNew->fileStackPointer = -1; - pNew->pathPointer = -1; - return pNew; -} -/*---------------------------------------------------------------------*/ -void killFileStack(pFileStack self){ - if(self != NULL){ - free(self); - } -} -/*---------------------------------------------------------------------*/ -int getFileStackSize(){ - return sizeof(fileStack); -} -/*----------------------------------------------------------------------*/ -void pushFileStack(pFileStack self, pNexusFunction pDriv, char *file){ - size_t length; - - self->fileStackPointer++; - self->fileStack[self->fileStackPointer].pDriver = pDriv; - memset(&self->fileStack[self->fileStackPointer].closeID,0,sizeof(NXlink)); - length = strlen(file); - if(length >= 1024){ - length = 1023; - } - memcpy(&self->fileStack[self->fileStackPointer].filename,file,length); -} -/*----------------------------------------------------------------------*/ -void popFileStack(pFileStack self){ - self->fileStackPointer--; - if(self->fileStackPointer < -1){ - self->fileStackPointer = -1; - } -} -/*----------------------------------------------------------------------*/ -pNexusFunction peekFileOnStack(pFileStack self){ - return self->fileStack[self->fileStackPointer].pDriver; -} -/*---------------------------------------------------------------------*/ -char *peekFilenameOnStack(pFileStack self){ - return self->fileStack[self->fileStackPointer].filename; -} -/*----------------------------------------------------------------------*/ -void peekIDOnStack(pFileStack self, NXlink *id){ - memcpy(id, &self->fileStack[self->fileStackPointer].closeID, sizeof(NXlink)); -} -/*---------------------------------------------------------------------*/ -void setCloseID(pFileStack self, NXlink id){ - memcpy(&self->fileStack[self->fileStackPointer].closeID, &id, sizeof(NXlink)); -} -/*----------------------------------------------------------------------*/ -int fileStackDepth(pFileStack self){ - return self->fileStackPointer; -} -/*----------------------------------------------------------------------*/ -void pushPath(pFileStack self, const char *name){ - self->pathPointer++; - strncpy(self->pathStack[self->pathPointer],name,NX_MAXNAMELEN-1); -} -/*-----------------------------------------------------------------------*/ -void popPath(pFileStack self){ - self->pathPointer--; - if(self->pathPointer < -1){ - self->pathPointer = -1; - } -} -/*-----------------------------------------------------------------------*/ -int buildPath(pFileStack self, char *path, int pathlen){ - int i; - size_t totalPathLength; - char *totalPath; - - for(i = 0, totalPathLength = 5; i <= self->pathPointer; i++){ - totalPathLength += strlen(self->pathStack[i]) + 1; - } - totalPath = (char*)malloc(totalPathLength*sizeof(char)); - if(totalPath == NULL){ - return 0; - } - memset(totalPath,0,totalPathLength*sizeof(char)); - for(i = 0; i <= self->pathPointer; i++){ - strcat(totalPath,"/"); - strcat(totalPath,self->pathStack[i]); - } - - strncpy(path,totalPath,pathlen-1); - free(totalPath); - return 1; -} diff --git a/nxstack.h b/nxstack.h deleted file mode 100755 index 2faaf041..00000000 --- a/nxstack.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - This is some code to handle a stack of NeXus files. This is used to implement - external linking within the NeXus-API - - Copyright (C) 1997-2006 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 - - Added functions to deal with the path stack for NXgetpath - Mark Koennecke, October 2009 - -*/ -#ifndef NEXUSFILESTACK -#define NEXUSFILESTACK - -typedef struct __fileStack *pFileStack; -#define MAXEXTERNALDEPTH 16 - -pFileStack makeFileStack(); -void killFileStack(pFileStack self); -int getFileStackSize(); - -void pushFileStack(pFileStack self, pNexusFunction pDriv, char *filename); -void popFileStack(pFileStack self); - -pNexusFunction peekFileOnStack(pFileStack self); -char *peekFilenameOnStack(pFileStack self); -void peekIDOnStack(pFileStack self, NXlink *id); -void setCloseID(pFileStack self, NXlink id); - -int fileStackDepth(pFileStack self); - -void pushPath(pFileStack self, const char *name); -void popPath(pFileStack self); -int buildPath(pFileStack self, char *path, int pathlen); - -#endif - diff --git a/nxxml.c b/nxxml.c deleted file mode 100644 index 12f4de16..00000000 --- a/nxxml.c +++ /dev/null @@ -1,1992 +0,0 @@ -/* - * This is the implementation file for the XML file driver - * for NeXus - * - * Copyright (C) 2006 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 - */ - - -#ifdef NXXML - -#include -#include -#include -#include -#include -#include -#include "nxio.h" -#include "nxdataset.h" - -#ifdef _MSC_VER -#define snprintf _snprintf -#endif /* _MSC_VER */ - -extern void *NXpData; -extern int validNXName(const char* name, int allow_colon); /* from napi.c */ -char *nxitrim(char *str); /* from napi.c */ - -/*----------------------- our data structures -------------------------- - One might wonder why a node stack is still needed even if this API - operates on top of a tree API. The reason for this are the links. - Following a link on any NXopenpath, data means a jump through the - whole tree. In order to correctly return from such adventures, - a stack is needed. Moreover we need it in order to keep track of the - state of search operations. - - The true NXroot node is always at stack[0]. The root in the data - structure is the ?xml element. The latter one is needed to store - the tree. ------------------------------------------------------------------------*/ -typedef struct { - mxml_node_t *current; - mxml_node_t *currentChild; - int currentAttribute; - int options; /**< additional information about the node */ -}xmlStack; - -/* - * Freddie Akeroyd, 19/03/2008 - * - * Add in support for table style data writing - this is - * indicated internally via the XMLSTACK_OPTION_TABLE flag - * and separates the dimensions and data into separate nodes contained - * in DIMS_NODE_NAME and DATA_NODE_NAME. This is a first commit and - * involves some code duplication that will need to be cleaned up later. - * Also writing in table style is only enabled for 1D arrays as - * I haven't done slab writing yet which the nexus test program uses - * for writing 2D arrays. - * - * Table output is enabled by opening a file with (NXACC_CREATEXML | NXACC_TABLE) - * - * See http://trac.nexusformat.org/code/ticket/111 for further details - */ -#define XMLSTACK_OPTION_TABLE 0x1 /**< indicates table option in xmlStack */ - - -/*---------------------------------------------------------------------*/ -typedef struct { - mxml_node_t *root; /* root node */ - int readOnly; /* read only flag */ - int tableStyle; /**< whether to output data in XML table style */ - int stackPointer; /* stack pointer */ - char filename[1024]; /* file name, for NXflush, NXclose */ - xmlStack stack[NXMAXSTACK]; /* stack */ -}XMLNexus, *pXMLNexus; -/*===================== support functions ===============================*/ -extern char *stptok(char *s, char *tok, size_t toklen, char *brk); -/*----------------------------------------------------------------------*/ -static mxml_node_t *getLinkTarget(pXMLNexus xmlHandle, const char *target){ - mxml_node_t *node = NULL; - mxml_node_t *testNode = NULL; - char path[132], *pPtr; - - pPtr = (char *)target + 1; - node = xmlHandle->stack[0].current; - while((pPtr = stptok(pPtr,path,131,"/")) != NULL){ - /* - search for group node - */ - testNode = mxmlFindElement(node,node,NULL,"name",path,MXML_DESCEND_FIRST); - if(testNode == NULL){ - /* - it can still be a data node - */ - testNode = mxmlFindElement(node,node,path,NULL,NULL,MXML_DESCEND_FIRST); - } - if(testNode == NULL){ - NXReportError("Cannot follow broken link"); - return NULL; - } else { - node = testNode; - } - } - return node; -} -/*==================== file functions ===================================*/ -static void errorCallbackForMxml(const char *txt){ - NXReportError((char *)txt); -} -/*-----------------------------------------------------------------------*/ -NXstatus NXXopen(CONSTCHAR *filename, NXaccess am, - NXhandle* pHandle) { - pXMLNexus xmlHandle = NULL; - FILE *fp = NULL; - char *time_buffer = NULL; - mxml_node_t *current; - - /* - allocate data - */ - xmlHandle = (pXMLNexus)malloc(sizeof(XMLNexus)); - if(!xmlHandle){ - NXReportError( "Out of memory allocating XML file handle"); - return NX_ERROR; - } - memset(xmlHandle,0,sizeof(XMLNexus)); - - /* - initialize mxml XML parser - */ - mxmlSetCustomHandlers(nexusLoadCallback, nexusWriteCallback); - initializeNumberFormats(); - mxmlSetErrorCallback(errorCallbackForMxml); - - xmlHandle->tableStyle = ((am & NXACC_TABLE) ? 1 : 0); - /* - open file - */ - strncpy(xmlHandle->filename,filename,1023); - switch(am & NXACCMASK_REMOVEFLAGS){ - case NXACC_READ: - xmlHandle->readOnly = 1; - case NXACC_RDWR: - fp = fopen(filename,"r"); - if(fp == NULL){ - NXReportError("Failed to open file:"); - NXReportError((char *)filename); - free(xmlHandle); - return NX_ERROR; - } - xmlHandle->root = mxmlLoadFile(NULL,fp,nexusTypeCallback); - xmlHandle->stack[0].current = mxmlFindElement(xmlHandle->root, - xmlHandle->root, - "NXroot", - NULL,NULL, - MXML_DESCEND); - xmlHandle->stack[0].currentChild = NULL; - xmlHandle->stack[0].currentAttribute = 0; - xmlHandle->stack[0].options = 0; - fclose(fp); - break; - case NXACC_CREATEXML: - xmlHandle->root = mxmlNewElement(NULL, - "?xml version=\"1.0\" encoding=\"UTF-8\"?"); - current = mxmlNewElement(xmlHandle->root,"NXroot"); - mxmlElementSetAttr(current,"NeXus_version",NEXUS_VERSION); - mxmlElementSetAttr(current,"XML_version","mxml"); - mxmlElementSetAttr(current,"file_name",filename); - mxmlElementSetAttr(current,"xmlns", NEXUS_SCHEMA_NAMESPACE); - mxmlElementSetAttr(current,"xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance"); - mxmlElementSetAttr(current,"xsi:schemaLocation", - NEXUS_SCHEMA_NAMESPACE " " NEXUS_SCHEMA_URL); - time_buffer = NXIformatNeXusTime(); - if(time_buffer != NULL){ - mxmlElementSetAttr(current,"file_time",time_buffer); - free(time_buffer); - } - xmlHandle->stack[0].current = current; - xmlHandle->stack[0].currentChild = NULL; - xmlHandle->stack[0].currentAttribute = 0; - xmlHandle->stack[0].options = 0; - break; - default: - NXReportError("Bad access parameter specified in NXXopen"); - return NX_ERROR; - } - if(xmlHandle->stack[0].current == NULL){ - NXReportError( - "No NXroot element in XML-file, no NeXus-XML file"); - return NX_ERROR; - } - - *pHandle = xmlHandle; - return NX_OK; -} -/*----------------------------------------------------------------------*/ -NXstatus NXXclose (NXhandle* fid){ - pXMLNexus xmlHandle = NULL; - FILE *fp = NULL; - - xmlHandle = (pXMLNexus)*fid; - assert(xmlHandle); - - if(xmlHandle->readOnly == 0) { - fp = fopen(xmlHandle->filename,"w"); - if(fp == NULL){ - NXReportError("Failed to open NeXus XML file for writing"); - return NX_ERROR; - } - mxmlSaveFile(xmlHandle->root,fp,NXwhitespaceCallback); - fclose(fp); - } - mxmlDelete(xmlHandle->root); - free(xmlHandle); - *fid = NULL; - return NX_OK; -} -/*----------------------------------------------------------------------*/ -NXstatus NXXflush(NXhandle *fid){ - pXMLNexus xmlHandle = NULL; - FILE *fp = NULL; - - xmlHandle = (pXMLNexus)*fid; - assert(xmlHandle); - - if(xmlHandle->readOnly == 0) { - fp = fopen(xmlHandle->filename,"w"); - if(fp == NULL){ - NXReportError("Failed to open NeXus XML file for writing"); - return NX_ERROR; - } - mxmlSaveFile(xmlHandle->root,fp,NXwhitespaceCallback); - fclose(fp); - } - return NX_OK; -} -/*======================================================================= - Group functions -=========================================================================*/ -NXstatus NXXmakegroup (NXhandle fid, CONSTCHAR *name, - CONSTCHAR *nxclass){ - char buffer[256]; - pXMLNexus xmlHandle = NULL; - mxml_node_t *newGroup = NULL; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if (!validNXName(name, 0)) - { - sprintf(buffer, "ERROR: invalid characters in group name \"%s\"", name); - NXReportError(buffer); - return NX_ERROR; - } - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("Close dataset before trying to create a group"); - return NX_ERROR; - } - - newGroup = mxmlNewElement(xmlHandle->stack[xmlHandle->stackPointer].current, - nxclass); - if(!newGroup){ - NXReportError("failed to allocate new group"); - return NX_ERROR; - } - mxmlElementSetAttr(newGroup,"name",name); - return NX_OK; -} -/*----------------------------------------------------------------------*/ -static mxml_node_t *searchGroupLinks(pXMLNexus xmlHandle, CONSTCHAR *name, - CONSTCHAR *nxclass){ - mxml_node_t *linkNode = NULL; - mxml_node_t *current; - mxml_node_t *test = NULL; - const char *linkTarget; - const char *linkName = NULL; - - current = xmlHandle->stack[xmlHandle->stackPointer].current; - linkNode = current; - while((linkNode = mxmlFindElement(linkNode,current,"NAPIlink",NULL,NULL, - MXML_DESCEND_FIRST)) != NULL){ - linkTarget = mxmlElementGetAttr(linkNode,"target"); - test = getLinkTarget(xmlHandle,linkTarget); - if(test != NULL){ - if(strcmp(test->value.element.name,nxclass) == 0){ - if(strcmp(mxmlElementGetAttr(test,"name"),name) == 0){ - return test; - } - } - } - /* - test for named links - */ - linkName = mxmlElementGetAttr(linkNode,"name"); - if(test != NULL && linkName != NULL){ - if(strcmp(test->value.element.name,nxclass) == 0){ - if(strcmp(linkName, name) == 0){ - return test; - } - } - } - } - return NULL; -} -/*------------------------------------------------------------------------*/ -NXstatus NXXopengroup (NXhandle fid, CONSTCHAR *name, - CONSTCHAR *nxclass){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *newGroup = NULL; - char error[1024]; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("Close dataset before trying to open a group"); - return NX_ERROR; - } - newGroup = mxmlFindElement(xmlHandle->stack[xmlHandle->stackPointer].current, - xmlHandle->stack[xmlHandle->stackPointer].current, - nxclass, - "name", - name, - MXML_DESCEND_FIRST); - if(newGroup == NULL){ - newGroup = searchGroupLinks(xmlHandle,name,nxclass); - } - if(!newGroup){ - snprintf(error,1023,"Failed to open %s, %s",name,nxclass); - NXReportError(error); - return NX_ERROR; - } - xmlHandle->stackPointer++; - xmlHandle->stack[xmlHandle->stackPointer].current = newGroup; - xmlHandle->stack[xmlHandle->stackPointer].currentChild = NULL; - xmlHandle->stack[xmlHandle->stackPointer].currentAttribute = 0; - xmlHandle->stack[xmlHandle->stackPointer].options = 0; - return NX_OK; -} -/*----------------------------------------------------------------------*/ -NXstatus NXXclosegroup (NXhandle fid){ - pXMLNexus xmlHandle = NULL; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - /* - silently fix this - */ - NXXclosedata(fid); - } - if(xmlHandle->stackPointer > 0){ - xmlHandle->stackPointer--; - } - return NX_OK; -} -/*========================================================================= - dataset functions -=========================================================================*/ -NXstatus NXXcompmakedata64 (NXhandle fid, CONSTCHAR *name, - int datatype, - int rank, - int64_t dimensions[], - int compress_type, int64_t chunk_size[]){ - /* - compression does not relly make sense with XML - */ - return NXXmakedata64(fid,name,datatype,rank,dimensions); -} -/*-----------------------------------------------------------------------*/ -static char *buildTypeString(int datatype, int rank, int64_t dimensions[]){ - char *typestring = NULL; - char pNumber[20]; - int i; - - /* - allocate data - */ - typestring = (char *)malloc(132*sizeof(char)); - if(!typestring){ - NXReportError("Failed to allocate typestring"); - return NULL; - } - memset(typestring,0,132*sizeof(char)); - - getNumberText(datatype,typestring,130); - if(rank > 1 || datatype == NX_CHAR || dimensions[0] > 1) { - strcat(typestring,"["); - snprintf(pNumber,19,"%lld", (long long)dimensions[0]); - strncat(typestring,pNumber,130-strlen(typestring)); - for(i = 1; i < rank; i++){ - snprintf(pNumber,19,",%lld", (long long)dimensions[i]); - strncat(typestring,pNumber,130-strlen(typestring)); - } - strcat(typestring,"]"); - } - return typestring; -} - -/*------------------------------------------------------------------------*/ -NXstatus NXXmakedatatable64 (NXhandle fid, - CONSTCHAR *name, int datatype, - int rank, int64_t dimensions[]){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *dataNode = NULL, *dataNodeRoot = NULL, *dimsNode = NULL, *dimsNodeRoot = NULL; - mxml_node_t *newData = NULL; - mxml_node_t *current; - char *typestring; - int i, ndata; - char buffer[256]; - static int64_t one = 1; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - if (!validNXName(name, 0)) - { - sprintf(buffer, "ERROR: invalid characters in dataset name \"%s\"", name); - NXReportError(buffer); - return NX_ERROR; - } - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("Close dataset before trying to create a dataset"); - return NX_ERROR; - } - if(dimensions[0] < 0){ - dimensions[0] = 1; - } - - current = xmlHandle->stack[xmlHandle->stackPointer].current; - - dimsNodeRoot = mxmlFindElement(current, current, DIMS_NODE_NAME, NULL, NULL, MXML_DESCEND_FIRST); - if (dimsNodeRoot == NULL) - { - dimsNodeRoot = mxmlNewElement(current, DIMS_NODE_NAME); - } - dimsNode = mxmlNewElement(dimsNodeRoot, name); - mxmlNewOpaque(dimsNode, ""); - typestring = buildTypeString(datatype,rank,dimensions); - if(typestring != NULL){ - mxmlElementSetAttr(dimsNode,TYPENAME,typestring); - free(typestring); - } else { - NXReportError("Failed to allocate typestring"); - return NX_ERROR; - } - ndata = 1; - for(i=0; itype = MXML_CUSTOM; -/* newData->value.custom.data = createNXDataset(rank,datatype,dimensions); */ - newData->value.custom.data = createNXDataset(1,datatype,&one); - if(!newData->value.custom.data){ - NXReportError("Failed to allocate space for dataset"); - return NX_ERROR; - } - newData->value.custom.destroy = destroyDataset; - } - return NX_OK; -} - -NXstatus NXXmakedata64 (NXhandle fid, - CONSTCHAR *name, int datatype, - int rank, int64_t dimensions[]){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *dataNode = NULL; - mxml_node_t *newData = NULL; - mxml_node_t *current; - char *typestring; - char buffer[256]; - - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - if (!validNXName(name, 0)) - { - sprintf(buffer, "ERROR: invalid characters in dataset name \"%s\"", name); - NXReportError(buffer); - return NX_ERROR; - } - - if (xmlHandle->tableStyle && datatype != NX_CHAR && dimensions[0] != NX_UNLIMITED && rank == 1) - { - return NXXmakedatatable64(fid,name,datatype,rank,dimensions); - } - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("Close dataset before trying to create a dataset"); - return NX_ERROR; - } - if(dimensions[0] < 0){ - dimensions[0] = 1; - } - - 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 { - NXReportError("Failed to allocate typestring"); - return NX_ERROR; - } - /* - NX_CHAR maps to MXML_OPAQUE datasets - */ - if(datatype == NX_CHAR){ - newData = mxmlNewOpaque(dataNode,""); - return NX_OK; - } else { - newData = (mxml_node_t *)malloc(sizeof(mxml_node_t)); - if(!newData){ - NXReportError("Failed to allocate space for dataset"); - return NX_ERROR; - } - memset(newData,0,sizeof(mxml_node_t)); - mxmlAdd(dataNode, MXML_ADD_AFTER, MXML_ADD_TO_PARENT, newData); - newData->type = MXML_CUSTOM; - newData->value.custom.data = createNXDataset(rank,datatype,dimensions); - if(!newData->value.custom.data){ - NXReportError("Failed to allocate space for dataset"); - return NX_ERROR; - } - newData->value.custom.destroy = destroyDataset; - } - return NX_OK; -} -/*----------------------------------------------------------------------*/ -static mxml_node_t *searchSDSLinks(pXMLNexus xmlHandle, CONSTCHAR *name){ - mxml_node_t *linkNode = NULL; - mxml_node_t *current; - mxml_node_t *test = NULL; - const char *linkTarget; - const char *linkName = NULL; - - current = xmlHandle->stack[xmlHandle->stackPointer].current; - linkNode = current; - while((linkNode = mxmlFindElement(linkNode,current,"NAPIlink",NULL,NULL, - MXML_DESCEND_FIRST)) != NULL){ - linkTarget = mxmlElementGetAttr(linkNode,"target"); - test = getLinkTarget(xmlHandle,linkTarget); - if(test != NULL){ - if(strcmp(test->value.element.name,name) == 0){ - return test; - } - } - /* - test for named links - */ - linkName = mxmlElementGetAttr(linkNode,"name"); - if(test != NULL && linkName != NULL){ - if(strcmp(linkName,name) == 0){ - return test; - } - } - } - return NULL; -} -/*-----------------------------------------------------------------------*/ -NXstatus NXXopendatatable (NXhandle fid, CONSTCHAR *name){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *dataNode = NULL, *dimsNode = NULL; - char error[1024]; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - /* - silently fix this - */ - xmlHandle->stackPointer--; - if(xmlHandle->stackPointer < 0){ - xmlHandle->stackPointer = 0; - } - } - - dimsNode = mxmlFindElement(xmlHandle->stack[xmlHandle->stackPointer].current, - xmlHandle->stack[xmlHandle->stackPointer].current, - DIMS_NODE_NAME, - NULL, - NULL, - MXML_DESCEND_FIRST); - - if(!dimsNode){ - snprintf(error,1023,"Failed to open dataset %s",name); - NXReportError(error); - return NX_ERROR; - } - - dataNode = mxmlFindElement(dimsNode, - dimsNode, - name, - NULL, - NULL, - MXML_DESCEND_FIRST); - if(dataNode == NULL){ - dataNode = searchSDSLinks(xmlHandle,name); - } - if(!dataNode){ - snprintf(error,1023,"Failed to open dataset %s",name); - NXReportError(error); - return NX_ERROR; - } - xmlHandle->stackPointer++; - xmlHandle->stack[xmlHandle->stackPointer].current = dataNode; - xmlHandle->stack[xmlHandle->stackPointer].currentChild = NULL; - xmlHandle->stack[xmlHandle->stackPointer].currentAttribute = 0; - xmlHandle->stack[xmlHandle->stackPointer].options = XMLSTACK_OPTION_TABLE; - return NX_OK; -} - - -NXstatus NXXopendata (NXhandle fid, CONSTCHAR *name){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *dataNode = NULL, *current = NULL; - char error[1024]; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - /* is this a table style node ? */ - current = xmlHandle->stack[xmlHandle->stackPointer].current; - dataNode = mxmlFindElement(current, - current, - DATA_NODE_NAME, - NULL, - NULL, - MXML_DESCEND_FIRST); - if (dataNode != NULL) - { - dataNode = mxmlFindElement(dataNode, - dataNode, - name, - NULL, - NULL, - MXML_DESCEND_FIRST); - } - if (dataNode != NULL) - { - return NXXopendatatable(fid, name); - } - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - /* - silently fix this - */ - xmlHandle->stackPointer--; - if(xmlHandle->stackPointer < 0){ - xmlHandle->stackPointer = 0; - } - } - - dataNode = mxmlFindElement(xmlHandle->stack[xmlHandle->stackPointer].current, - xmlHandle->stack[xmlHandle->stackPointer].current, - name, - NULL, - NULL, - MXML_DESCEND_FIRST); - if(dataNode == NULL){ - dataNode = searchSDSLinks(xmlHandle,name); - } - if(!dataNode){ - snprintf(error,1023,"Failed to open dataset %s",name); - NXReportError(error); - return NX_ERROR; - } - xmlHandle->stackPointer++; - xmlHandle->stack[xmlHandle->stackPointer].current = dataNode; - xmlHandle->stack[xmlHandle->stackPointer].currentChild = NULL; - xmlHandle->stack[xmlHandle->stackPointer].currentAttribute = 0; - xmlHandle->stack[xmlHandle->stackPointer].options = 0; - return NX_OK; -} -/*----------------------------------------------------------------------*/ - -NXstatus NXXclosedata (NXhandle fid){ - pXMLNexus xmlHandle = NULL; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - if(xmlHandle->stackPointer > 0){ - xmlHandle->stackPointer--; - } - return NX_OK; - } - return NX_OK; -} -/*----------------------------------------------------------------------*/ -static mxml_node_t *findData(mxml_node_t *node){ - mxml_node_t *baby = node; - - while( (baby = mxmlWalkNext(baby,node,MXML_DESCEND_FIRST)) != NULL){ - if(baby->type == MXML_OPAQUE || baby->type == MXML_CUSTOM){ - return baby; - } - } - return NULL; -} - -/* we only havv to deal with non-character data here */ -NXstatus NXXputdatatable (NXhandle fid, const void *data){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *userData = NULL; - mxml_node_t *current = NULL; - mxml_node_t *nodeRoot = NULL; - mxml_node_t *dataNodeRoot = NULL; - mxml_node_t *dataNode = NULL; - const char* name; - pNXDS dataset; - int i, offset, length; - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - /* current points at the Idims node as done in NXXopendatatable */ - current = xmlHandle->stack[xmlHandle->stackPointer].current; - name = current->value.element.name; - /* we want to walk all Idata nodes and set name */ - nodeRoot = current->parent->parent; - dataNodeRoot = nodeRoot; - offset = 0; - for(i=0; dataNodeRoot != NULL; i++) - { - dataNodeRoot = mxmlFindElement(dataNodeRoot, nodeRoot, DATA_NODE_NAME, NULL, NULL, (i == 0 ? MXML_DESCEND_FIRST : MXML_NO_DESCEND) ); - if (dataNodeRoot != NULL) - { - dataNode = mxmlFindElement(dataNodeRoot,dataNodeRoot,name,NULL,NULL,MXML_DESCEND_FIRST); - if (dataNode != NULL) - { - userData = findData(dataNode); - assert(userData != NULL); - dataset = (pNXDS)userData->value.custom.data; - assert(dataset); - length = getNXDatasetByteLength(dataset); - memcpy(dataset->u.ptr,(char*)data + offset,length); - offset += length; - } - } - } - return NX_OK; -} - -/*------------------------------------------------------------------------*/ -NXstatus NXXputdata (NXhandle fid, void *data){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *userData = NULL; - mxml_node_t *current = NULL; - pNXDS dataset; - int i, length, type, rank; - int64_t dim[NX_MAXRANK]; - char *pPtr = NULL; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if (xmlHandle->stack[xmlHandle->stackPointer].options & XMLSTACK_OPTION_TABLE) - { - return NXXputdatatable(fid,data); - } - - if(!isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("No dataset open"); - return NX_ERROR; - } - - current = xmlHandle->stack[xmlHandle->stackPointer].current; - userData = findData(current); - assert(userData != NULL); - if(userData->type == MXML_OPAQUE){ - /* - Text data. We have to make sure that the text is \0 terminated. - Some language bindings do not ensure that this is the case. - */ - if(NXXgetinfo64(fid,&rank, dim, &type) == NX_OK){ - length = 1; - for(i=0; ivalue.custom.data; - assert(dataset); - length = getNXDatasetByteLength(dataset); - memcpy(dataset->u.ptr,data,length); - } - return NX_OK; -} - -NXstatus NXXgetdatatable (NXhandle fid, void *data){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *userData = NULL; - mxml_node_t *current = NULL; - mxml_node_t *nodeRoot = NULL; - mxml_node_t *dataNodeRoot = NULL; - mxml_node_t *dataNode = NULL; - const char* name; - pNXDS dataset; - int i, offset, length; - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - /* current points at the Idims node as done in NXXopendatatable */ - current = xmlHandle->stack[xmlHandle->stackPointer].current; - name = current->value.element.name; - /* we want to walk all Idata nodes and set name */ - nodeRoot = current->parent->parent; - dataNodeRoot = nodeRoot; - offset = 0; - for(i=0; dataNodeRoot != NULL; i++) - { - dataNodeRoot = mxmlFindElement(dataNodeRoot, nodeRoot, DATA_NODE_NAME, NULL, NULL, (i == 0 ? MXML_DESCEND_FIRST : MXML_NO_DESCEND) ); - if (dataNodeRoot != NULL) - { - dataNode = mxmlFindElement(dataNodeRoot,dataNodeRoot,name,NULL,NULL,MXML_DESCEND_FIRST); - if (dataNode != NULL) - { - userData = findData(dataNode); - assert(userData != NULL); - dataset = (pNXDS)userData->value.custom.data; - assert(dataset); - length = getNXDatasetByteLength(dataset); - memcpy((char*)data + offset, dataset->u.ptr, length); - offset += length; - } - } - } - return NX_OK; -} - - -/*------------------------------------------------------------------------*/ -NXstatus NXXgetdata (NXhandle fid, void *data){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *userData = NULL; - mxml_node_t *current = NULL; - pNXDS dataset; - int i, length, type, rank; - int64_t dim[NX_MAXRANK]; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if (xmlHandle->stack[xmlHandle->stackPointer].options & XMLSTACK_OPTION_TABLE) - { - return NXXgetdatatable(fid,data); - } - - if(!isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("No dataset open"); - return NX_ERROR; - } - - current = xmlHandle->stack[xmlHandle->stackPointer].current; - userData = findData(current); - assert(userData != NULL); - if(userData->type == MXML_OPAQUE){ - /* - text data - */ - if(NXXgetinfo64(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); - length = getNXDatasetByteLength(dataset); - memcpy(data,dataset->u.ptr,length); - } - return NX_OK; -} -/*------------------------------------------------------------------------*/ -NXstatus NXXgetinfo64 (NXhandle fid, int *rank, - int64_t dimension[], int *iType){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *userData = NULL; - mxml_node_t *current = NULL; - pNXDS dataset; - int myRank, i; - const char *attr = NULL; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if(!isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("No dataset open"); - return NX_ERROR; - } - - current = xmlHandle->stack[xmlHandle->stackPointer].current; - userData = findData(current); - assert(userData != NULL); - if(userData->type == MXML_OPAQUE){ - /* - text data - */ - attr = mxmlElementGetAttr(current, TYPENAME); - if(attr == NULL){ - *rank = 1; - *iType = NX_CHAR; - dimension[0]= strlen(userData->value.opaque); - } else { - *iType = translateTypeCode(attr); - analyzeDim(attr,rank,dimension,iType); - if (dimension[0] == -1) /* 1D strings are NX_CHAR not NX_CHAR[] so length will not be correct */ - { - dimension[0] = strlen(userData->value.opaque); - } - - } - } else { - dataset = (pNXDS)userData->value.custom.data; - assert(dataset); - myRank = getNXDatasetRank(dataset); - *rank = myRank; - *iType = getNXDatasetType(dataset); - for(i = 0; i < myRank; i++){ - dimension[i] = getNXDatasetDim(dataset,i); - } - } - return NX_OK; -} -/*--------------------------------------------------------------------- - clone the dataset and set the data pointer. This in order to use - the addressing and type conversion implemented in nxdataset ----------------------------------------------------------------------*/ -static pNXDS makeSlabData(pNXDS dataset, const void *data, const int64_t size[]){ - pNXDS slabData = NULL; - int rank, i; - - slabData = (pNXDS)malloc(sizeof(NXDS)); - if(slabData == NULL){ - return NULL; - } - - rank = getNXDatasetRank(dataset); - slabData->rank = rank; - slabData->dim = (int64_t *)malloc(rank*sizeof(int64_t)); - for(i = 0; i < rank; i++){ - slabData->dim[i] = size[i]; - } - slabData->type = getNXDatasetType(dataset); - slabData->u.ptr = (void*)data; - slabData->magic = dataset->magic; - return slabData; -} -/*-------------------------------------------------------------------- - This goes by recursion -----------------------------------------------------------------------*/ -static void putSlabData(pNXDS dataset, pNXDS slabData, int dim, - const int64_t start[], - int64_t sourcePos[], int64_t targetPos[]){ - int64_t i, rank, length; - - rank = getNXDatasetRank(slabData); - length = getNXDatasetDim(slabData,dim); - if(dim != rank-1){ - for(i = 0; i < length; i++){ - targetPos[dim] = start[dim] +i; - sourcePos[dim] = i; - putSlabData(dataset,slabData, dim+1,start, - sourcePos,targetPos); - } - } else { - for(i = 0; i < length; i++){ - targetPos[dim] = start[dim] +i; - sourcePos[dim] = i; - putNXDatasetValue(dataset,targetPos, - getNXDatasetValue(slabData,sourcePos)); - } - } -} -/*---------------------------------------------------------------------- - This is in order to support unlimited dimensions along the first axis - -----------------------------------------------------------------------*/ -static int checkAndExtendDataset(mxml_node_t *node, pNXDS dataset, - const int64_t start[], const int64_t size[]){ - int64_t dim0, byteLength; - void *oldData = NULL; - char *typestring = NULL; - - dim0 = start[0] + size[0]; - if(dim0 > dataset->dim[0]){ - byteLength = getNXDatasetByteLength(dataset); - oldData = dataset->u.ptr; - dataset->dim[0] = dim0; - dataset->u.ptr = malloc(getNXDatasetByteLength(dataset)); - if(dataset->u.ptr == NULL){ - return 0; - } - memset(dataset->u.ptr,0,getNXDatasetByteLength(dataset)); - memcpy(dataset->u.ptr,oldData,byteLength); - free(oldData); - typestring = buildTypeString(dataset->type,dataset->rank,dataset->dim); - if(typestring != NULL){ - mxmlElementSetAttr(node,TYPENAME,typestring); - free(typestring); - } else { - NXReportError("Failed to allocate typestring"); - return 0; - } - } - return 1; -} - -NXstatus NXXputslabtable (NXhandle fid, const void *data, - const int64_t iStart[], const int64_t iSize[]){ - return NX_OK; -} -/*----------------------------------------------------------------------*/ -NXstatus NXXputslab64 (NXhandle fid, void *data, - int64_t iStart[], int64_t iSize[]){ - - pXMLNexus xmlHandle = NULL; - mxml_node_t *userData = NULL; - mxml_node_t *current = NULL; - pNXDS dataset, slabData; - int64_t sourcePos[NX_MAXRANK], targetPos[NX_MAXRANK]; - int status; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if (xmlHandle->stack[xmlHandle->stackPointer].options & XMLSTACK_OPTION_TABLE) - { - return NXXputslabtable(fid,data,iStart,iSize); - } - - if(!isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("No dataset open"); - return NX_ERROR; - } - - current = xmlHandle->stack[xmlHandle->stackPointer].current; - userData = findData(current); - assert(userData != NULL); - if(userData->type == MXML_OPAQUE){ - NXReportError("This API does not support slabs on text data"); - return NX_ERROR; - } - dataset = (pNXDS)userData->value.custom.data; - assert(dataset); - - status = checkAndExtendDataset(current,dataset,iStart,iSize); - if(status == 0){ - NXReportError("Out of memory extending dataset"); - return NX_ERROR; - } - - slabData = makeSlabData(dataset, data, iSize); - if(slabData == NULL){ - NXReportError("Failed to allocate slab data"); - return NX_ERROR; - } - - - putSlabData(dataset,slabData,0,iStart,sourcePos,targetPos); - free(slabData->dim); - free(slabData); - - return NX_OK; -} -/*-------------------------------------------------------------------- - This goes by recursion -----------------------------------------------------------------------*/ -static void getSlabData(pNXDS dataset, pNXDS slabData, int dim, - const int64_t start[], - int64_t sourcePos[],int64_t targetPos[]){ - int64_t i, rank, length; - - rank = getNXDatasetRank(slabData); - length = getNXDatasetDim(slabData,dim); - if(dim != rank-1){ - for(i = 0; i < length; i++){ - sourcePos[dim] = start[dim] +i; - targetPos[dim] = i; - getSlabData(dataset,slabData, dim+1,start, - sourcePos,targetPos); - } - } else { - for(i = 0; i < length; i++){ - sourcePos[dim] = start[dim] +i; - targetPos[dim] = i; - putNXDatasetValue(slabData,targetPos, - getNXDatasetValue(dataset,sourcePos)); - } - } -} -/*----------------------------------------------------------------------*/ -NXstatus NXXgetslab64 (NXhandle fid, void *data, - const int64_t iStart[], const int64_t iSize[]){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *userData = NULL; - mxml_node_t *current = NULL; - pNXDS dataset, slabData; - int64_t sourcePos[NX_MAXRANK], targetPos[NX_MAXRANK]; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if(!isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("No dataset open"); - return NX_ERROR; - } - - current = xmlHandle->stack[xmlHandle->stackPointer].current; - userData = findData(current); - assert(userData != NULL); - if(userData->type == MXML_OPAQUE){ - NXReportError("This API does not support slabs on text data"); - return NX_ERROR; - } - dataset = (pNXDS)userData->value.custom.data; - assert(dataset); - slabData = makeSlabData(dataset, data, iSize); - if(slabData == NULL){ - NXReportError("Failed to allocate slab data"); - return NX_ERROR; - } - getSlabData(dataset,slabData,0,iStart,sourcePos,targetPos); - free(slabData->dim); - free(slabData); - - return NX_OK; -} -/*----------------------------------------------------------------------*/ -static NXstatus NXXsetnumberformat(NXhandle fid, - int type, char *format){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *current = NULL; - mxml_node_t *userData = NULL; - pNXDS dataset; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - current = xmlHandle->stack[xmlHandle->stackPointer].current; - userData = findData(current); - assert(userData != NULL); - if(userData->type == MXML_OPAQUE){ - return NX_OK; - } - dataset = (pNXDS)userData->value.custom.data; - assert(dataset); - if(dataset->format != NULL){ - free(dataset->format); - } - dataset->format = strdup(format); - } else { - setNumberFormat(type, format); - } - return NX_OK; -} -/*============================ Attributes ============================*/ -static char *formatAttributeData(const void *data, int datalen, int iType){ - int intData = 0; - long iValue = -99999; - double dValue = -1e38; - char type[20]; - char *number; - - - if(iType == NX_CHAR){ -/* 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)); - if(!number){ - NXReportError("Failed to allocate attribute number buffer"); - return NULL; - } - - if(datalen > 1){ - return NULL; - } - type[0] = '\0'; - switch(iType){ - case NX_INT32: - iValue = ((int *)data)[0]; - intData = 1; - strcpy(type,"NX_INT32:"); - break; - case NX_UINT32: - iValue = ((unsigned int *)data)[0]; - intData = 1; - strcpy(type,"NX_UINT32:"); - break; - case NX_INT16: - iValue = ((short *)data)[0]; - intData = 1; - strcpy(type,"NX_INT16:"); - break; - case NX_UINT16: - iValue = ((unsigned short *)data)[0]; - intData = 1; - strcpy(type,"NX_UINT16:"); - break; - case NX_INT8: - iValue = (int)((char *)data)[0]; - intData = 1; - strcpy(type,"NX_INT8:"); - break; - case NX_UINT8: - intData = 1; - iValue = (int)((unsigned char *)data)[0]; - strcpy(type,"NX_UINT8:"); - break; - case NX_FLOAT32: - dValue = ((float *)data)[0]; - strcpy(type,"NX_FLOAT32:"); - intData = 0; - break; - case NX_FLOAT64: - dValue = ((double *)data)[0]; - strcpy(type,"NX_FLOAT64:"); - intData = 0; - break; - } - if(intData){ - snprintf(number,79,"%s%ld",type,iValue); - } else { - snprintf(number,79,"%s%f",type,dValue); - } - return number; -} -/*---------------------------------------------------------------------*/ -NXstatus NXXputattr (NXhandle fid, CONSTCHAR *name, void *data, - int datalen, int iType){ - char buffer[256]; - pXMLNexus xmlHandle = NULL; - mxml_node_t *current = NULL; - char *numberData = NULL; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - if (!validNXName(name, 1)) - { - sprintf(buffer, "ERROR: invalid characters in attribute name \"%s\"", name); - NXReportError(buffer); - return NX_ERROR; - } - - current = xmlHandle->stack[xmlHandle->stackPointer].current; - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - if(strcmp(name,TYPENAME) == 0){ - NXReportError("type is a reserved attribute name, rejected"); - return NX_ERROR; - } - } - - numberData = formatAttributeData(data,datalen,iType); - if(numberData == NULL){ - NXReportError("This API does not support non number arrays"); - return NX_ERROR; - } else { - mxmlElementSetAttr(current,name,numberData); - free(numberData); - } - return NX_OK; -} -/*--------------------------------------------------------------------------*/ -NXstatus NXXgetattr (NXhandle fid, char *name, - void *data, int* datalen, int* iType){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *current = NULL; - const char *attribute = NULL; - char error[1024]; - const char *attData = NULL; - int nx_type; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - current = xmlHandle->stack[xmlHandle->stackPointer].current; - - attribute = mxmlElementGetAttr(current,name); - if(!attribute){ - snprintf(error,1023,"Attribute %s not found", name); - NXReportError(error); - return NX_ERROR; - } - nx_type = translateTypeCode((char *)attribute); - if(nx_type < 0) { - /* - no type code == text attribute - */ - nx_type = NX_CHAR; - } else { - /* - We need to find the number after the type code. However, there is - the complication of the datatype type attribute ... - */ - if(strcmp(name,TYPENAME) == 0){ - nx_type = NX_CHAR; - } else { - attData = strchr(attribute,(int)':'); - if(attData == NULL){ - NXReportError("ERROR: bad attribute string, : missing"); - return NX_ERROR; - } - attData++; - } - } - *iType = nx_type; - switch(nx_type){ - case NX_CHAR: - /* enforce NULL termination regardless of length of datalen */ - strncpy((char *)data, attribute, *datalen-1); - ((char*)data)[*datalen-1] = '\0'; - /* *datalen = strlen(attribute); */ - *datalen = strlen((char*)data); - *iType = NX_CHAR; - break; - case NX_INT32: - ((int *)data)[0] = atoi(attData); - *datalen = 1; - break; - case NX_UINT32: - ((unsigned int *)data)[0] = atoi(attData); - *datalen = 1; - break; - case NX_INT16: - ((short *)data)[0] = atoi(attData); - *datalen = 1; - break; - case NX_UINT16: - ((unsigned short *)data)[0] = atoi(attData); - *datalen = 1; - break; - case NX_INT8: - ((char *)data)[0] = atoi(attData); - *datalen = 1; - break; - case NX_UINT8: - ((unsigned char *)data)[0] = atoi(attData); - *datalen = 1; - break; - case NX_FLOAT32: - ((float *)data)[0] = atof(attData); - *datalen = 1; - break; - case NX_FLOAT64: - ((double *)data)[0] = atof(attData); - *datalen = 1; - break; - } - - return NX_OK; -} - -/* find the next node, ignoring Idata */ -static mxml_node_t* find_node(mxml_node_t* node, int next) -{ - int done = 0; - mxml_node_t* parent_next = NULL; /* parent to use if we are in an Idims search */ - if (node == NULL) - { - return NULL; - } - if ( (node->parent != NULL) && !strcmp(node->parent->value.element.name, DIMS_NODE_NAME) ) - { - parent_next = node->parent->next; - } - else - { - parent_next = NULL; - } - if (next) - { - if (node->next != NULL) - { - node = node->next; - } - else - { - node = parent_next; - } - } - while(node != NULL && !done) - { - if ( (node->parent != NULL) && !strcmp(node->parent->value.element.name, DIMS_NODE_NAME) ) - { - parent_next = node->parent->next; - } - else - { - parent_next = NULL; - } - if ( (node->type != MXML_ELEMENT) || !strcmp(node->value.element.name, DATA_NODE_NAME) ) - { - if (node->next != NULL) - { - node = node->next; - } - else - { - node = parent_next; - } - continue; - } - if (!strcmp(node->value.element.name, DIMS_NODE_NAME)) - { - node = node->child; - continue; - } - done = 1; - } - return node; -} - -/*====================== search functions =================================*/ -NXstatus NXXgetnextentry (NXhandle fid,NXname name, - NXname nxclass, int *datatype){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *next = NULL, *userData, *node = NULL; - int stackPtr; - const char *target = NULL, *attname = NULL; - pNXDS dataset; - char pBueffel[256]; - const char *linkName = NULL; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - /* - be nice to user: silently fix this problem - */ - NXXclosedata(fid); - } - - stackPtr = xmlHandle->stackPointer; - if(xmlHandle->stack[stackPtr].currentChild == NULL){ - /* - initialization of search - */ - node = find_node(xmlHandle->stack[stackPtr].current->child, 0); - } else { - /* - proceed - */ - node = find_node(xmlHandle->stack[stackPtr].currentChild, 1); - } - xmlHandle->stack[stackPtr].currentChild = node; - next = node; - if(next == NULL){ - return NX_EOD; - } - if(strcmp(next->value.element.name,"NAPIlink") == 0){ - target = mxmlElementGetAttr(next,"target"); - linkName = mxmlElementGetAttr(next,"name"); - if(target == NULL){ - NXReportError("Corrupted file, NAPIlink without target"); - return NX_ERROR; - } - next = getLinkTarget(xmlHandle,target); - if(next == NULL){ - NXReportError("Corrupted file, broken link"); - return NX_ERROR; - } - } - - if(isDataNode(next)){ - strcpy(name,next->value.element.name); - strcpy(nxclass,"SDS"); - userData = findData(next); - if(userData == NULL){ - snprintf(pBueffel,255,"Corrupted file, userData for %s not found", - name); - NXReportError(pBueffel); - return NX_ERROR; - } - if(userData->type == MXML_OPAQUE){ - *datatype = NX_CHAR; - } else { - dataset = (pNXDS)userData->value.custom.data; - assert(dataset); - *datatype = getNXDatasetType(dataset); - } - } else { - strcpy(nxclass,next->value.element.name); - attname = mxmlElementGetAttr(next,"name"); - strcpy(name,attname); - } - /* - this is for named links - */ - if(linkName != NULL){ - strcpy(name,linkName); - } - return NX_OK; -} -/*----------------------------------------------------------------------*/ -extern NXstatus NXXinitgroupdir(NXhandle fid){ - pXMLNexus xmlHandle = NULL; - int stackPtr; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("Cannot search datasets"); - return NX_ERROR; - } - - stackPtr = xmlHandle->stackPointer; - xmlHandle->stack[stackPtr].currentChild = NULL; - return NX_OK; -} -/*-------------------------------------------------------------------------*/ -NXstatus NXXgetnextattr (NXhandle fid, NXname pName, - int *iLength, int *iType){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *current = NULL; - int stackPtr, currentAtt, nx_type; - char *attVal; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - stackPtr = xmlHandle->stackPointer; - - current = xmlHandle->stack[stackPtr].current; - currentAtt = xmlHandle->stack[stackPtr].currentAttribute; - if(currentAtt >= - current->value.element.num_attrs ){ - xmlHandle->stack[stackPtr].currentAttribute = 0; - return NX_EOD; - } - - /* - hide group name attribute - */ - if(strcmp(current->value.element.attrs[currentAtt].name,"name") == 0 - && !isDataNode(current) ){ - xmlHandle->stack[stackPtr].currentAttribute++; - return NXXgetnextattr(fid,pName,iLength,iType); - } - - /* - hide type attribute - */ - if(strcmp(current->value.element.attrs[currentAtt].name,TYPENAME) == 0 - && isDataNode(current)){ - xmlHandle->stack[stackPtr].currentAttribute++; - return NXXgetnextattr(fid,pName,iLength,iType); - } - - strcpy(pName,current->value.element.attrs[currentAtt].name); - attVal = current->value.element.attrs[currentAtt].value; - nx_type = translateTypeCode((char *)attVal); - if(nx_type < 0 || strcmp(pName,TYPENAME) == 0){ - /* - no type == NX_CHAR - */ - *iLength = strlen(attVal); - *iType = NX_CHAR; - } else { - *iLength = 1; - *iType = nx_type; - } - - xmlHandle->stack[stackPtr].currentAttribute++; - return NX_OK; -} -/*-------------------------------------------------------------------------*/ -extern NXstatus NXXinitattrdir(NXhandle fid){ - pXMLNexus xmlHandle = NULL; - int stackPtr; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - stackPtr = xmlHandle->stackPointer; - xmlHandle->stack[stackPtr].currentAttribute = 0; - return NX_OK; -} -/*-------------------------------------------------------------------------*/ -NXstatus NXXgetgroupinfo (NXhandle fid, int *iN, - NXname pName, NXname pClass){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *node = NULL, *child = NULL; - mxml_node_t *current = NULL; - const char *nameAtt = NULL; - int childCount; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("No group open"); - return NX_ERROR; - } - current = xmlHandle->stack[xmlHandle->stackPointer].current; - - nameAtt = mxmlElementGetAttr(current,"name"); - if(nameAtt != NULL){ - strcpy(pName,nameAtt); - } - strcpy(pClass,current->value.element.name); - -/* count all child nodes, but need to ignore DATA_NODE_NAME and - * descend into DIMS_NODE_NAME - */ - childCount = 0; - node = current->child; - while(node != NULL) - { - if (!strcmp(node->value.element.name, DATA_NODE_NAME)) - { - ; /* names also exist in DIMS_NODE_NAME so do nothing here */ - } - else if (!strcmp(node->value.element.name, DIMS_NODE_NAME)) - { - child = node->child; - while(child != NULL) - { - /* not sure why this check is needed, but you double count otherwise */ - if (child->type == MXML_ELEMENT) - { - childCount++; - } - child = child->next; - } - } - else - { - childCount++; - } - node = node->next; - } - *iN = childCount; - return NX_OK; -} -/*----------------------------------------------------------------------*/ -NXstatus NXXgetattrinfo (NXhandle fid, int *iN){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *current = NULL; - int stackPtr, skip; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - stackPtr = xmlHandle->stackPointer; - - current = xmlHandle->stack[stackPtr].current; - - /* - hide type and group name attributes - */ - skip=0; - if(isDataNode(current)) { - /* data nodes may have type */ - if(mxmlElementGetAttr(current,TYPENAME) != NULL) skip=1; - } else { - /* group nodes (except root) have name */ - if(mxmlElementGetAttr(current,"name") != NULL) skip=1; - } - *iN = current->value.element.num_attrs - skip; - return NX_OK; -} -/*================= Linking functions =================================*/ -static int countPathChars(mxml_node_t *path[], int stackPtr){ - int count = 1; - const char *name = NULL; - - while(stackPtr >= 0) { - if(isDataNode(path[stackPtr])){ - count += strlen(path[stackPtr]->value.element.name); - } else { - name = mxmlElementGetAttr(path[stackPtr],"name"); - if(name != NULL){ - count += strlen(name); - } - } - stackPtr--; - count += 1; - } - return count; -} -/*-------------------------------------------------------------------*/ -static char *buildPathString(mxml_node_t *path[], int stackPtr){ - int count = 0; - const char *name = NULL; - char *pathString = NULL; - - count = countPathChars(path,stackPtr); - pathString = (char *)malloc((count+10)*sizeof(char)); - if(pathString == NULL){ - return NULL; - } - memset(pathString,0,(count+10)*sizeof(char)); - - while(stackPtr >= 0) { - if(isDataNode(path[stackPtr])){ - strcat(pathString,"/"); - strcat(pathString,path[stackPtr]->value.element.name); - } else { - name = mxmlElementGetAttr(path[stackPtr],"name"); - if(name != NULL){ - strcat(pathString,"/"); - strcat(pathString,name); - } - } - stackPtr--; - } - return pathString; -} -/*--------------------------------------------------------------------*/ -static char *findLinkPath(mxml_node_t *node){ - mxml_node_t **path = NULL; - int stackPtr; - mxml_node_t *current = NULL; - char *result = NULL; - - path = (mxml_node_t **)malloc(NXMAXSTACK*sizeof(mxml_node_t *)); - if(path == NULL){ - NXReportError("ERROR: out of memory following link path"); - return NULL; - } - memset(path,0,NXMAXSTACK*sizeof(mxml_node_t *)); - - /* - first path: walk up the tree untill NXroot is found - */ - current = node; - stackPtr = 0; - while(current != NULL && - strcmp(current->value.element.name,"NXroot") != 0){ - path[stackPtr] = current; - stackPtr++; - current = current->parent; - } - stackPtr--; - - /* - path now contains the nodes to the root node in reverse order. - From this build the path string - */ - result = buildPathString(path,stackPtr); - free(path); - return result; -} -/*--------------------------------------------------------------------*/ -NXstatus NXXgetdataID (NXhandle fid, NXlink* sRes){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *current = NULL; - char *linkPath = NULL; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if(!isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - return NX_ERROR; - } - current = xmlHandle->stack[xmlHandle->stackPointer].current; - - linkPath = findLinkPath(current); - if(!linkPath){ - NXReportError("Failed to allocate link path string"); - return NX_ERROR; - } - strncpy(sRes->targetPath,linkPath,1023); - free(linkPath); - return NX_OK; -} -/*--------------------------------------------------------------------*/ -NXstatus NXXgetgroupID (NXhandle fid, NXlink* sRes){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *current = NULL; - char *linkPath = NULL; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("No group open"); - return NX_ERROR; - } - current = xmlHandle->stack[xmlHandle->stackPointer].current; - - if(xmlHandle->stackPointer == 0){ - return NX_ERROR; - } - - linkPath = findLinkPath(current); - if(!linkPath){ - NXReportError("Failed to allocate link path string"); - return NX_ERROR; - } - strncpy(sRes->targetPath,linkPath,1023); - free(linkPath); - return NX_OK; -} - -/*-----------------------------------------------------------------------*/ - NXstatus NXXprintlink (NXhandle fid, NXlink* sLink) - { - pXMLNexus xmlHandle = NULL; - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - printf("XML link: target=\"%s\"\n", sLink->targetPath); - return NX_OK; - } - -/*-----------------------------------------------------------------------*/ -NXstatus NXXmakelink (NXhandle fid, NXlink* sLink){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *current = NULL, *linkNode = NULL; - mxml_node_t *linkedNode = NULL; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("No group to link to open"); - return NX_ERROR; - } - current = xmlHandle->stack[xmlHandle->stackPointer].current; - linkNode = mxmlNewElement(current,"NAPIlink"); - if(!linkNode){ - NXReportError("Failed to allocate new link element"); - return NX_ERROR; - } - mxmlElementSetAttr(linkNode,"target",sLink->targetPath); - linkedNode = getLinkTarget(xmlHandle,sLink->targetPath); - if(linkedNode != NULL){ - mxmlElementSetAttr(linkedNode,"target",sLink->targetPath); - } - return NX_OK; -} - -/*-----------------------------------------------------------------------*/ -NXstatus NXXmakenamedlink (NXhandle fid, CONSTCHAR *name, NXlink* sLink){ - pXMLNexus xmlHandle = NULL; - mxml_node_t *current = NULL, *linkNode = NULL; - mxml_node_t *linkedNode = NULL; - char buffer[256]; - - xmlHandle = (pXMLNexus)fid; - assert(xmlHandle); - if (!validNXName(name, 0)) - { - sprintf(buffer, "ERROR: invalid characters in link name \"%s\"", name); - NXReportError(buffer); - return NX_ERROR; - } - - if(isDataNode(xmlHandle->stack[xmlHandle->stackPointer].current)){ - NXReportError("No group to link to open"); - return NX_ERROR; - } - current = xmlHandle->stack[xmlHandle->stackPointer].current; - linkNode = mxmlNewElement(current,"NAPIlink"); - if(!linkNode){ - NXReportError("Failed to allocate new link element"); - return NX_ERROR; - } - mxmlElementSetAttr(linkNode,"target",sLink->targetPath); - mxmlElementSetAttr(linkNode,"name",name); - linkedNode = getLinkTarget(xmlHandle,sLink->targetPath); - if(linkedNode != NULL){ - mxmlElementSetAttr(linkedNode,"target",sLink->targetPath); - } - return NX_OK; -} -/*----------------------------------------------------------------------*/ -NXstatus NXXsameID (NXhandle fileid, NXlink* pFirstID, - NXlink* pSecondID){ - if(strcmp(pFirstID->targetPath,pSecondID->targetPath) == 0) { - return NX_OK; - } else { - return NX_ERROR; - } -} -/*--------------------------------------------------------------------*/ -int NXXcompress(NXhandle fid, int comp){ - /* that will throw an exception in the Java API, errors have to be fatal */ - /* NXReportError("NXcompress is deprecated, IGNORED"); */ - return NX_OK; -} -/*----------------------------------------------------------------------*/ -void NXXassignFunctions(pNexusFunction fHandle){ - fHandle->nxclose=NXXclose; - fHandle->nxreopen=NULL; - fHandle->nxflush=NXXflush; - fHandle->nxmakegroup=NXXmakegroup; - fHandle->nxopengroup=NXXopengroup; - fHandle->nxclosegroup=NXXclosegroup; - fHandle->nxmakedata64=NXXmakedata64; - fHandle->nxcompmakedata64=NXXcompmakedata64; - fHandle->nxcompress=NXXcompress; - fHandle->nxopendata=NXXopendata; - fHandle->nxclosedata=NXXclosedata; - fHandle->nxputdata=NXXputdata; - fHandle->nxputattr=NXXputattr; - fHandle->nxputslab64=NXXputslab64; - fHandle->nxgetdataID=NXXgetdataID; - fHandle->nxmakelink=NXXmakelink; - fHandle->nxmakenamedlink=NXXmakenamedlink; - fHandle->nxgetdata=NXXgetdata; - fHandle->nxgetinfo64=NXXgetinfo64; - fHandle->nxgetnextentry=NXXgetnextentry; - fHandle->nxgetslab64=NXXgetslab64; - fHandle->nxgetnextattr=NXXgetnextattr; - fHandle->nxgetattr=NXXgetattr; - fHandle->nxgetattrinfo=NXXgetattrinfo; - fHandle->nxgetgroupID=NXXgetgroupID; - fHandle->nxgetgroupinfo=NXXgetgroupinfo; - fHandle->nxsameID=NXXsameID; - fHandle->nxinitgroupdir=NXXinitgroupdir; - fHandle->nxinitattrdir=NXXinitattrdir; - fHandle->nxsetnumberformat=NXXsetnumberformat; - fHandle->nxprintlink=NXXprintlink; - fHandle->nxnativeexternallink=NULL; -} - - - -#endif /*NXXML*/ diff --git a/nxxml.h b/nxxml.h deleted file mode 100644 index ee7e9ece..00000000 --- a/nxxml.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This is the header file for the NeXus XML file driver. - * - * 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 NEXUSXML -#define NEXUSXML - -extern NXstatus NXXopen(CONSTCHAR *filename, - NXaccess access_method, - NXhandle* pHandle); -extern NXstatus NXXclose(NXhandle* pHandle); -extern NXstatus NXXflush(NXhandle* pHandle); - -NXstatus NXXmakegroup (NXhandle fid, CONSTCHAR *name, - CONSTCHAR *nxclass); -NXstatus NXXopengroup (NXhandle fid, CONSTCHAR *name, - CONSTCHAR *nxclass); -NXstatus NXXclosegroup (NXhandle fid); - -NXstatus NXXcompmakedata64 (NXhandle fid, CONSTCHAR *name, - int datatype, - int rank, - int64_t dimensions[], - int compress_type, int64_t chunk_size[]); -NXstatus NXXmakedata64 (NXhandle fid, - CONSTCHAR *name, int datatype, - int rank, int64_t dimensions[]); -NXstatus NXXopendata (NXhandle fid, CONSTCHAR *name); -NXstatus NXXclosedata (NXhandle fid); -NXstatus NXXputdata (NXhandle fid, void *data); -NXstatus NXXgetdata (NXhandle fid, void *data); -NXstatus NXXgetinfo64 (NXhandle fid, int *rank, - int64_t dimension[], int *iType); -NXstatus NXXputslab64 (NXhandle fid, void *data, - int64_t iStart[], int64_t iSize[]); -NXstatus NXXgetslab64 (NXhandle fid, void *data, - const int64_t iStart[], const int64_t iSize[]); -NXstatus NXXputattr (NXhandle fid, CONSTCHAR *name, void *data, - int datalen, int iType); -NXstatus NXXgetattr (NXhandle fid, char *name, - void *data, int* datalen, int* iType); - -NXstatus NXXgetnextentry (NXhandle fid,NXname name, - NXname nxclass, int *datatype); -extern NXstatus NXXgetnextattr(NXhandle handle, - NXname pName, int *iLength, int *iType); -extern NXstatus NXXinitgroupdir(NXhandle handle); -extern NXstatus NXXinitattrdir(NXhandle handle); -extern NXstatus NXXgetattrinfo (NXhandle fid, int *iN); -extern NXstatus NXXgetgroupinfo (NXhandle fid, int *iN, - NXname pName, NXname pClass); - -extern NXstatus NXXgetdataID (NXhandle fid, NXlink* sRes); -extern NXstatus NXXgetgroupID (NXhandle fid, NXlink* sRes); -extern NXstatus NXXmakelink (NXhandle fid, NXlink* sLink); -extern NXstatus NXXprintlink (NXhandle fid, NXlink* sLink); -extern NXstatus NXXsameID (NXhandle fileid, - NXlink* pFirstID, NXlink* pSecondID); - -void NXXassignFunctions(pNexusFunction fHandle); -#endif diff --git a/sctdriveobj.c b/sctdriveobj.c index 894fda32..aae56d47 100644 --- a/sctdriveobj.c +++ b/sctdriveobj.c @@ -148,8 +148,6 @@ static long SCTDRIVSetValue(void *data, SConnection * pCon, float val) } pPriv->pCon = SCCopyConnection(pCon); - /* StopByData(pServ->pExecutor, data); */ - v = MakeHdbFloat(val); SetHdbProperty(self->objectNode, "writestatus", "start"); status = SetHipadabaPar(self->objectNode, v, pCon); diff --git a/sicshipadaba.c b/sicshipadaba.c index 01934a54..8f2ae5ca 100644 --- a/sicshipadaba.c +++ b/sicshipadaba.c @@ -19,6 +19,10 @@ * Refactored to new callback system, Markus Zolliker, Mark Koennecke, March 2008 * * Added start and finished messages to commands. Mark Koennecke, November 2008 + * + * Added SicsValueCheckCallback and implemented first version of haddcheck. + * Mark Koennecke, July 2013 + * */ #include #include @@ -238,6 +242,51 @@ pHdbCallback MakeReadOnlyCallback() { return MakeHipadabaCallback(SICSReadOnlyCallback, NULL, NULL); } +/*------------------------------------------------------------------------------------*/ +static hdbCallbackReturn SICSValueCheckCallback(pHdb node, void *userData, + pHdbMessage message) +{ + SConnection *pCon = NULL; + pHdbDataMessage mm = NULL; + char values[1024], *pPtr, pToken[80]; + int status; + hdbValue v; + + mm = GetHdbSetMessage(message); + if (mm == NULL) { + return hdbContinue; + } + pCon = (SConnection *) mm->callData; + v = *(mm->v); + + status = GetHdbProperty(node,"values",values,sizeof(values)); + if(status != 1 && pCon != NULL){ + SCPrintf(pCon,eLogError,"ERROR: configuration error, no values on node %s", + node->name); + return hdbAbort; + } + + if(v.dataType != HIPTEXT && pCon != NULL){ + SCPrintf(pCon,eLogError,"ERROR: need text data for node %s", + node->name); + return hdbAbort; + } + + pPtr = values; + while((pPtr = stptok(pPtr,pToken,sizeof(pToken),",")) != NULL){ + if(strcmp(pToken,v.v.text) == 0) { + return hdbContinue; + } + } + + if(pCon != NULL){ + SCPrintf(pCon,eLogError,"ERROR: %s not allowed as value for %s, allowed are: %s", + v.v.text, node->name, values); + } + + return hdbAbort; +} + /*-------------------------------------------------------------------------------------*/ static hdbCallbackReturn SICSDriveCallback(pHdb node, void *userData, @@ -3767,7 +3816,38 @@ static int MatchHdbProperty(SConnection * pCon, SicsInterp * pSics, } return 1; } +/*---------------------------------------------------------------------------*/ +static int AddCheck(SConnection * pCon, SicsInterp * pSics, + void *pData, int argc, char *argv[]) +{ + pHdb node = NULL; + if(argc < 3) { + SCPrintf(pCon,eLogError, "ERROR: need at least node and key argument for %s", + argv[0]); + return 0; + } + + node = FindHdbNode(NULL, argv[1],pCon); + if (node == NULL) { + SCPrintf(pCon,eLogError, "ERROR: node %s to add check to not found", argv[1]); + return 0; + } + + strtolower(argv[2]); + if(strcmp(argv[2],"values") == 0) { + PrependHipadabaCallback(node,MakeHipadabaCallback(SICSValueCheckCallback, + NULL,NULL)); + SCSendOK(pCon); + return 1; + } else { + SCPrintf(pCon,eLogError,"ERROR: key %s for %s not recognized", + argv[2], argv[0]); + return 0; + } + + return 1; +} /*======================= Factory Functions =================================*/ void killSICSHipadaba() { @@ -3810,6 +3890,7 @@ int InstallSICSHipadaba(SConnection * pCon, SicsInterp * pSics, AddCommand(pSics, "hmatchprop", MatchHdbProperty, NULL, NULL); AddCommand(pSics, "hlistprop", ListSICSHdbProperty, NULL, NULL); AddCommand(pSics, "hcallnotify",CallNotify, NULL, NULL); + AddCommand(pSics, "haddcheck",AddCheck, NULL, NULL); InstallSICSPoll(pCon, pSics, pData, argc, argv); poller = (pSicsPoll) FindCommandData(pSics, "sicspoll", "SicsPoll"); diff --git a/sicsobj.c b/sicsobj.c index 47660d6c..abe477f6 100644 --- a/sicsobj.c +++ b/sicsobj.c @@ -474,6 +474,12 @@ int InvokeSICSOBJ(SConnection * pCon, SicsInterp * pSics, void *pData, if (argc == 1) { parNode = self->objectNode; if (parNode != NULL && isNodePrintable(parNode)) { + status = GetHdbProperty(parNode,"geterror",buffer,sizeof(buffer)); + if (status == 1 && strstr(buffer,"none") == NULL){ + SCPrintf(pCon,eValue,"ERROR: %s on last read of %s", buffer, argv[0]); + SCPrintf(pCon,eValue,"%s = -99999", argv[0]); + return 0; + } status = GetHipadabaPar(parNode, &data, pCon); if (status != 1) { return 0; diff --git a/sicvar.c b/sicvar.c index 7d2ffc33..8286c0b1 100644 --- a/sicvar.c +++ b/sicvar.c @@ -58,6 +58,11 @@ static int VarSave(void *pData, char *name, FILE * fd) if (pVar->iAccessCode == usInternal) { return 1; } + + if(pVar->iLock == 1) { + return 1; + } + snprintf(pBueffel,sizeof(pBueffel)-1, "# Variable %s\n", name); switch (pVar->eType) { case veText: diff --git a/sllinux_def b/sllinux_def index 1116d6fb..0e22a767 100644 --- a/sllinux_def +++ b/sllinux_def @@ -12,4 +12,4 @@ MFLAGS=-f makefile_linux$(DUMMY) HDFROOT=/afs/psi.ch/project/sinq/sl6 TCLINC=. -DBG= -g \ No newline at end of file +DBG= -g diff --git a/tasublib.c b/tasublib.c index 4b38bfee..1ef9efa1 100644 --- a/tasublib.c +++ b/tasublib.c @@ -827,7 +827,7 @@ int calcTasQAngles(MATRIX UB, MATRIX planeNormal, int ss, double a3offset, angles->a3 += 360.; } */ - angles->a3 = fmod(angles->a3 + ss*180.,360.) - ss*180.; + angles->a3 = fmod(angles->a3 + ss*180.,360.) - ss*180.; killVector(QC); mat_free(R); diff --git a/test/sicsstat.tcl b/test/sicsstat.tcl index 0618ce7d..009ec577 100644 --- a/test/sicsstat.tcl +++ b/test/sicsstat.tcl @@ -1,3 +1,5 @@ + + exe batchpath ./ exe syspath ./ @@ -218,15 +220,17 @@ tasub r2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 tasub update #----- MultiMotor sa sa recovernampos noeff a3 24 a4 48 + + ref anglesheader stt,om,chi,phi ref clear -singlex cell 0 0 0 0 0 0 -singlex oldub 0 0 0 0 0 0 0 0 0 -singlex ub 0 0 0 0 0 0 0 0 0 -singlex planenormal 0 0 0 +singlex cell { 0 0 0 0 0 0} +singlex oldub { 0 0 0 0 0 0 0 0 0} +singlex ub { 0 0 0 0 0 0 0 0 0} +singlex planenormal { 0 0 0} singlex mode bi singlex spacegroup P -singlex peaksearch +singlex peaksearch {} singlex peaksearch/min2t 5 singlex peaksearch/step2t 1 singlex peaksearch/max2t 15 @@ -238,6 +242,7 @@ singlex peaksearch/phimin 0 singlex peaksearch/phimax 180 singlex peaksearch/chimin 90 singlex peaksearch/chimax 180 + #HKL Settings hkl scantolerance 2.500000 ubcalcint difftheta 0.300000 @@ -249,16 +254,20 @@ messref clear fmess weak 0 fmess weakthreshold 20 fmess fast 0 -fmess hkllim -10 -10 10 10 10 10 -fmess sttlim 5 180 +fmess hkllim { -10 -10 10 10 10 10} +fmess sttlim { 5 180} + fmess table clear -cone target 0 0 0 +cone target { 0 0 0} cone qscale 1 cone center unknown + simidx sttlim 0.2 simidx anglim 0.5 + simi preset 0 simi mode monitor + eva targetposition 0 eva sign 1 eva softzero 0 @@ -273,3 +282,8 @@ eva maxretry 3 eva ignorefault 0 eva movecount 10 eva staticoffset 0 + + + + + diff --git a/test/testini.tcl b/test/testini.tcl index df89ad08..3f35ee2b 100644 --- a/test/testini.tcl +++ b/test/testini.tcl @@ -833,3 +833,12 @@ if {$secmot == 1} { MakeSecSim eva -40 40 .3 } + +set zwickroll 1 + +if {$zwickroll == 1} { + source ../tcl/zwickroll.tcl +# makesctcontroller zwro std pc8977:50370 \r\n 5 \r\n + makesctcontroller zwro std localhost:8080 \r\n 5 \n + zwickroll::makezwickroll zwro +} \ No newline at end of file diff --git a/trace.c b/trace.c index e2a33a9b..cf78f0e1 100644 --- a/trace.c +++ b/trace.c @@ -43,7 +43,7 @@ int traceActive() static char *GetTracePath(pHdb node) { pHdb nodeStack[64]; - int depth = 0, length = 0, i; + int depth = 0, length = 1, i; pHdb current = NULL; char *pPtr = NULL; char sicsdev[80]; @@ -53,7 +53,7 @@ static char *GetTracePath(pHdb node) */ current = node; while (current != NULL && GetHdbProperty(current,"sicsdev",sicsdev,sizeof(sicsdev)) == 0) { - length += strlen(current->name) + 1; + length += strlen(current->name) + 2; nodeStack[depth] = current; depth++; assert(depth < 64); @@ -109,7 +109,7 @@ static hdbCallbackReturn TraceCallback(pHdb node, void *userData, return hdbContinue; } tracePar(pPath,"%s",GetCharArray(printedData)); - DeleteDynString(printedData); + DeleteDynString(printedData); } else { tracePar(pPath,"!!datachange!!"); }