/* This is a library of support functions and data structures which can be used in order to create interfaces between the NeXus-API and scripting languages or data analysis systems with a native code interface. copyright: GPL Mark Koennecke, October 2002 Mark Koennecke, November 2002 */ #include #include #include #include #include "nxinterhelper.h" #include "nxdataset.h" /*----------------------------------------------------------------- An own error handler. nx_getlasterror will return the test of the last NeXus error. --------------------------------------------------------------------*/ static char errorText[256] = ""; static void nxinterError(void *pData, char *error) { strncpy(errorText, error, 255); } /*-----------------------------------------------------------------------*/ char *nx_getlasterror(void) { return strdup(errorText); } /*-------------------- opening and closing -------------------------------*/ void *nx_open(char *filename, int accessMethod) { NXhandle handle = NULL; int status; NXMSetError(NULL, nxinterError); status = NXopen(filename, (NXaccess) accessMethod, &handle); if (status == NX_OK) { return handle; } else { return NULL; } } /*------------------------------------------------------------------------*/ void *nx_flush(void *hundle) { NXhandle handle; int status; handle = (NXhandle) hundle; status = NXflush(&handle); if (status == NX_OK) { return handle; } else { return NULL; } } /*-----------------------------------------------------------------------*/ void nx_close(void *hundle) { NXhandle handle; handle = (NXhandle) hundle; NXclose(&handle); } /*=================== group handling functions ========================*/ int nx_makegroup(void *handle, char *name, char *nxclass) { int status; NXhandle hfil; hfil = (NXhandle) handle; status = NXmakegroup(hfil, name, nxclass); if (status == NX_OK) { return 1; } else { return 0; } } /*---------------------------------------------------------------------*/ int nx_opengroup(void *handle, char *name, char *nxclass) { int status; NXhandle hfil; hfil = (NXhandle) handle; status = NXopengroup(hfil, name, nxclass); if (status == NX_OK) { return 1; } else { return 0; } } /*---------------------------------------------------------------------*/ int nx_openpath(void *handle, char *path) { int status; NXhandle hfil; hfil = (NXhandle) handle; status = NXopenpath(hfil, path); if (status == NX_OK) { return 1; } else { return 0; } } /*---------------------------------------------------------------------*/ int nx_opengrouppath(void *handle, char *path) { int status; NXhandle hfil; hfil = (NXhandle) handle; status = NXopengrouppath(hfil, path); if (status == NX_OK) { return 1; } else { return 0; } } /*--------------------------------------------------------------------*/ int nx_closegroup(void *handle) { int status; NXhandle hfil; hfil = (NXhandle) handle; status = NXclosegroup(hfil); if (status == NX_OK) { return 1; } else { return 0; } } /*-------------------------------------------------------------------*/ char *nx_getnextentry(void *handle, char separator) { int status, length, type; NXhandle hfil; char *resultBuffer = NULL; NXname group, nxclass; hfil = (NXhandle) handle; status = NXgetnextentry(hfil, group, nxclass, &type); if (status == NX_OK) { length = 30 + strlen(group) + strlen(nxclass); /* This introduces a memory leak. I had hoped, that swig would kill it for me after use, but I'am afraid, this is not the case. Unfortately I do not know how to fix the issue. */ resultBuffer = (char *) malloc(length * sizeof(char)); if (resultBuffer == NULL) { return NULL; } sprintf(resultBuffer, "%s%c%s%c%d", group, separator, nxclass, separator, type); return resultBuffer; } else { return NULL; } } /*-------------------------------------------------------------------*/ void *nx_getgroupID(void *handle) { int status; NXhandle hfil; NXlink *linki; linki = (NXlink *) malloc(sizeof(NXlink)); if (linki == NULL) { return NULL; } hfil = (NXhandle) handle; status = NXgetgroupID(hfil, linki); if (status == NX_OK) { return linki; } else { return NULL; } } /*------------------------------------------------------------------*/ int nx_initgroupdir(void *handle) { int status; NXhandle hfil; hfil = (NXhandle) handle; status = NXinitgroupdir(hfil); if (status == NX_OK) { return 1; } else { return 0; } } /*========================== dataset handling =======================*/ int nx_makedata(void *ptr, char *name, int rank, int type, void *dimPtr) { int status; NXhandle hfil; pNXDS dimData; hfil = (NXhandle) ptr; dimData = (pNXDS) dimPtr; if (dimData->type != NX_INT32) { NXIReportError(NULL, "ERROR: dimension data not integer"); return 0; } status = NXmakedata(hfil, name, type, rank, dimData->u.iPtr); if (status == NX_OK) { return 1; } else { return 0; } } /*--------------------------------------------------------------------*/ int nx_compmakedata(void *ptr, char *name, int rank, int type, void *dimPtr, void *bufPtr) { int status; NXhandle hfil; pNXDS dimData, bufData; hfil = (NXhandle) ptr; dimData = (pNXDS) dimPtr; if (dimData->type != NX_INT32) { NXIReportError(NULL, "ERROR: dimension data not integer"); return 0; } bufData = (pNXDS) bufPtr; status = NXcompmakedata(hfil, name, type, rank, dimData->u.iPtr, NX_COMP_LZW, bufData->u.iPtr); if (status == NX_OK) { return 1; } else { return 0; } } /*----------------------------------------------------------------------*/ int nx_opendata(void *handle, char *name) { int status; NXhandle hfil; hfil = (NXhandle) handle; status = NXopendata(hfil, name); if (status == NX_OK) { return 1; } else { return 0; } } /*----------------------------------------------------------------------*/ int nx_closedata(void *handle) { int status; NXhandle hfil; hfil = (NXhandle) handle; status = NXclosedata(hfil); if (status == NX_OK) { return 1; } else { return 0; } } /*------------------------------------------------------------------------*/ int nx_putslab(void *handle, void *dataset, void *startDim) { int status; NXhandle hfil; pNXDS data; pNXDS start; int end[NX_MAXRANK], i; hfil = (NXhandle) handle; data = (pNXDS) dataset; start = (pNXDS) startDim; for (i = 0; i < data->rank; i++) { end[i] = data->dim[i]; } status = NXputslab(hfil, data->u.ptr, start->u.iPtr, end); if (status == NX_OK) { return 1; } else { return 0; } } /*-----------------------------------------------------------------------*/ void *nx_getslab(void *handle, void *startdim, void *sizedim) { pNXDS resultdata; pNXDS start, size; int status, rank, type, dim[NX_MAXRANK]; int64_t cdim[NX_MAXRANK], i; NXhandle hfil; hfil = (NXhandle) handle; start = (pNXDS) startdim; size = (pNXDS) sizedim; /* get info first, then allocate data */ status = NXgetinfo(hfil, &rank, dim, &type); if (status != NX_OK) { return NULL; } for(i = 0; i < rank; i++){ cdim[i] = size->u.iPtr[i]; } resultdata = createNXDataset(rank, type, cdim); if (resultdata == NULL) { return NULL; } status = NXgetslab(hfil, resultdata->u.ptr, start->u.iPtr, size->u.iPtr); if (status == NX_OK) { return resultdata; } else { dropNXDataset(resultdata); return NULL; } } /*------------------------------------------------------------------------*/ void *nx_getds(void *handle, char *name) { pNXDS result = NULL; int rank, type,status; int64_t dim[NX_MAXRANK]; NXhandle hfil; hfil = (NXhandle) handle; status = NXopendata(hfil, name); if (status != NX_OK) { return NULL; } status = NXgetinfo64(hfil, &rank, dim, &type); if (status != NX_OK) { return NULL; } result = createNXDataset(rank, type, dim); if (result == NULL) { NXclosedata(hfil); return NULL; } status = NXgetdata(hfil, result->u.ptr); if (result == NULL) { NXclosedata(hfil); dropNXDataset(result); return NULL; } NXclosedata(hfil); return result; } /*----------------------------------------------------------------------*/ int nx_putds(void *handle, char *name, void *dataset) { NXhandle hfil; int status; pNXDS data; hfil = (NXhandle) handle; data = (pNXDS) dataset; status = NXopendata(hfil, name); if (status != NX_OK) { status = NXmakedata64(hfil, name, data->type, data->rank, data->dim); if (status != NX_OK) { return 0; } NXopendata(hfil, name); } status = NXputdata(hfil, data->u.ptr); NXclosedata(hfil); if (status != NX_OK) { return 0; } else { return 1; } } /*------------------------------------------------------------------------*/ void *nx_getdata(void *handle) { pNXDS result = NULL; int rank, type, status; int64_t dim[NX_MAXRANK]; NXhandle hfil; hfil = (NXhandle) handle; status = NXgetinfo64(hfil, &rank, dim, &type); if (status != NX_OK) { return NULL; } result = createNXDataset(rank, type, dim); if (result == NULL) { NXclosedata(hfil); return NULL; } status = NXgetdata(hfil, result->u.ptr); if (result == NULL) { dropNXDataset(result); return NULL; } return result; } /*----------------------------------------------------------------------*/ int nx_putdata(void *handle, void *dataset) { NXhandle hfil; int status; pNXDS data; hfil = (NXhandle) handle; data = (pNXDS) dataset; if (data == NULL) { NXIReportError(NULL, "ERROR: NULL data pointer in nx_putdata"); return 0; } status = NXputdata(hfil, data->u.ptr); if (status != NX_OK) { return 0; } else { return 1; } } /*----------------------------------------------------------------------*/ void *nx_getinfo(void *handle) { NXhandle hfil; int status, type, rank, dim[NX_MAXRANK], i; int64_t rdim[1]; pNXDS data = NULL; hfil = (NXhandle) handle; status = NXgetinfo(handle, &rank, dim, &type); if (status != NX_OK) { return NULL; } rdim[0] = 2 + rank; data = createNXDataset(1, NX_INT32, rdim); data->u.iPtr[0] = type; data->u.iPtr[1] = rank; for (i = 0; i < rank; i++) { data->u.iPtr[2 + i] = dim[i]; } return data; } /*----------------------------------------------------------------------*/ void *nx_getdataID(void *handle) { NXhandle hfil; int status; NXlink *linki; linki = (NXlink *) malloc(sizeof(NXlink)); if (linki == NULL) { return NULL; } hfil = (NXhandle) handle; status = NXgetdataID(hfil, linki); if (status == NX_OK) { return linki; } else { free(linki); return NULL; } } /*-------------------------------------------------------------------*/ char *nx_getnextattr(void *handle, char separator) { int status, length, type; char *result; NXhandle hfil; NXname aName; hfil = (NXhandle) handle; status = NXgetnextattr(hfil, aName, &length, &type); if (status == NX_OK) { /* This introduces a memory leak. I had hoped, that swig would kill it for me after use, but I'am afraid, this is not the case. Unfortately I do not know how to fix the issue. */ result = (char *) malloc((20 + strlen(aName)) * sizeof(char)); if (result == NULL) { return NULL; } memset(result, 0, (20 + strlen(aName)) * sizeof(char)); sprintf(result, "%s%c%d%c%d", aName, separator, length, separator, type); return result; } else { return NULL; } } /*-------------------------------------------------------------------*/ int nx_putattr(void *handle, char *name, void *ds) { int status; NXhandle hfil; pNXDS data; hfil = (NXhandle) handle; data = (pNXDS) ds; status = NXputattr(hfil, name, data->u.ptr, data->dim[0], data->type); if (status == NX_OK) { return 1; } else { return 0; } } /*-------------------------------------------------------------------*/ void *nx_getattr(void *handle, char *name, int type, int length) { NXhandle hfil; int status, tp, ll; int64_t dim[1]; pNXDS data = NULL; hfil = (NXhandle) handle; /* prepare dataset */ dim[0] = length + 1; data = createNXDataset(1, type, dim); if (data == NULL) { return NULL; } /* finally read the real data */ ll = length; tp = type; status = NXgetattr(hfil, name, data->u.ptr, &ll, &tp); if (status != NX_OK) { dropNXDataset(data); return NULL; } return data; } /*-----------------------------------------------------------------------*/ int nx_makelink(void *handle, void *link) { NXhandle hfil; NXlink *lk; int status; hfil = (NXhandle) handle; lk = (NXlink *) link; status = NXmakelink(hfil, lk); if (status == NX_OK) { return 1; } else { return 0; } } /*-----------------------------------------------------------------------*/ int nx_opensourcegroup(void *handle) { NXhandle hfil; int status; hfil = (NXhandle) handle; status = NXopensourcegroup(hfil); if (status == NX_OK) { return 1; } else { return 0; } }