Files
sics/nxdict.c
Koennecke Mark b60ce746d4 Merge commit 'refs/merge-requests/1' of ssh://gitorious.psi.ch/sinqdev/sics into merge-requests/1
First merge with ANSTO which compiles

Conflicts:
	SICSmain.c
	asynnet.c
	confvirtualmot.c
	counter.c
	devexec.c
	drive.c
	exebuf.c
	hipadaba.c
	interface.h
	make_gen
	motor.c
	nserver.c
	nwatch.c
	ofac.c
	protocol.c
	sicshipadaba.c
2015-04-23 17:00:33 +02:00

1952 lines
46 KiB
C

/*---------------------------------------------------------------------------
Nexus Dictionary API implementation file.
For documentation see the nxdict.tex file which comes with this
distribution.
copyleft: Mark Koennecke
Labor fuer Neutronenstreuung
Paul Scherrer Institut
CH-5232 Villigen-PSI
Switzerland
Mark.Koennecke@psi.ch
No warranties of any kind, whether explicit or implied, taken.
Distributed under the GNU copyleft license as documented elsewhere.
August, 1997
Version: 1.0
Version 1.1
Updated to use the combined HDF4 HDF5 API. New keyword -chunk which
defines the chunk buffer size for a SDS.
Mark Koennecke, August 2001
-----------------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <time.h>
#include "lld.h"
#include "napi.h"
#include "stringdict.h"
#include "dynstring.h"
#include "nxdict.h"
/*------------------ The magic number used for pointer checking */
#define NXDMAGIC 260558
/*--------------------------------------------------------------------------
Things defined in napi.c for error reporting
---------------------------------------------------------------------------*/
void *NXpData = NULL;
/*--------------------------------------------------------------------------*/
/* #define DEFDEBUG 1 */
/* define DEFDEBUG when you wish to print your definition strings before
action. This can help a lot to resolve mysteries when working with
dictionaries.
*/
/*-------------------------------------------------------------------------*/
typedef struct __NXdict {
int iID;
pStringDict pDictionary;
} sNXdict;
/*------------------ verbosity level -------------------------------------*/
static int iVerbosity = 0;
/*-------------------------------------------------------------------------*/
static char *NXDIReadFile(FILE * fd)
{
char *pNew = NULL;
long lLength = 0;
assert(fd);
/* determine length of file */
fseek(fd, 0L, SEEK_END);
lLength = ftell(fd);
if (lLength <= 0) {
return NULL;
}
fseek(fd, 0L, SEEK_SET);
/* allocate buffer */
lLength += 3;
pNew = (char *) malloc(lLength * sizeof(char));
if (!pNew) {
return NULL;
}
memset(pNew, 0, lLength); /* this ensures a 0 at the end */
/* read file */
fread(pNew, sizeof(char), lLength - 3, fd);
/* check for existence of the NXDICT string in the file */
if (strncmp(pNew, "##NXDICT-1.0", 12) != 0) {
NXReportError("ERROR: This is NO NXdict file");
free(pNew);
return NULL;
}
return pNew;
}
/*--------------------------------------------------------------------------*/
#define FWORD 1
#define FHASH 2
#define FEOL 3
#define FEOB 4
#define FEQUAL 5
#define FSLASH 6
static char *NXDIfNextToken(char *pPtr, char *pToken, int *iToken)
{
pToken[0] = '\0';
/* skip whitespace */
while ((*pPtr == ' ') || (*pPtr == '\t')) {
pPtr++;
}
/* check for special characters */
if (*pPtr == '#') {
*iToken = FHASH;
pToken[0] = *pPtr;
pPtr++;
return pPtr;
} else if (*pPtr == '\n') {
*iToken = FEOL;
pToken[0] = *pPtr;
pPtr++;
return pPtr;
} else if (*pPtr == '\0') {
*iToken = FEOB;
pToken[0] = *pPtr;
pPtr++;
return pPtr;
} else if (*pPtr == '=') {
*iToken = FEQUAL;
pToken[0] = *pPtr;
pPtr++;
return pPtr;
} else if (*pPtr == '\\') {
*iToken = FSLASH;
pToken[0] = *pPtr;
pPtr++;
return pPtr;
} else {
*iToken = FWORD;
/* copy word to pToken */
while ((*pPtr != ' ') && (*pPtr != '\t') &&
(*pPtr != '\n') && (*pPtr != '\0') && (*pPtr != '=')) {
*pToken = *pPtr;
pPtr++;
pToken++;
}
*pToken = '\0';
return pPtr;
}
/* not reached */
return pPtr;
}
/*------------------------------------------------------------------------*/
#define AMODE 0
#define DMODE 1
static void NXDIParse(char *pBuffer, pStringDict pDict)
{
char *pPtr;
int iToken;
int iMode;
char pAlias[1024];
char pDefinition[8192]; /* this is > 10 lines of definition */
char pWord[1024];
assert(pBuffer);
assert(pDict);
iMode = AMODE;
pPtr = pBuffer;
iToken = -1;
pDefinition[0] = '\0';
pAlias[0] = '\0';
pWord[0] = '\0';
while (iToken != FEOB) {
pPtr = NXDIfNextToken(pPtr, pWord, &iToken);
switch (iToken) {
case FHASH:
case FSLASH: /* skip over \n to next non blank */
while (*pPtr != '\n') {
pPtr++;
/* check for end of file */
if (*pPtr == '\0') {
return;
}
}
pPtr++;
break;
case FEQUAL: /* do a mode change */
iMode = DMODE;
pDefinition[0] = '\0';
break;
case FWORD:
if (iMode == AMODE) {
strcpy(pAlias, pWord);
} else {
strcat(pDefinition, pWord);
strcat(pDefinition, " ");
}
break;
case FEOL:
if (iMode == DMODE) {
/* enter in dictionary */
StringDictAddPair(pDict, pAlias, pDefinition);
iMode = AMODE;
pAlias[0] = '\0';
}
break;
case FEOB:
if (iMode == AMODE) {
/* empty line or a problem */
} else {
/* enter in dictionary */
StringDictAddPair(pDict, pAlias, pDefinition);
iMode = AMODE;
pAlias[0] = '\0';
}
return;
default:
assert(0); /* unrecognized token is a programming
error
*/
break;
}
}
}
/*--------------------------------------------------------------------------*/
NXstatus NXDinitfromfile(char *filename, NXdict * pData)
{
NXdict pNew = NULL;
FILE *fd = NULL;
char *pBuffer = NULL;
char pError[512];
/* allocate a new NXdict structure */
if (iVerbosity == NXalot) {
NXReportError("Allocating new NXdict structure ");
}
pNew = (NXdict) malloc(sizeof(sNXdict));
if (!pNew) {
NXReportError("Insufficient memory for creation of NXdict");
return NX_ERROR;
}
/* initialise it */
pNew->iID = NXDMAGIC;
pNew->pDictionary = CreateStringDict();
if (!pNew->pDictionary) {
NXReportError("Insufficient memory for creation of NXdict");
free(pNew);
return NX_ERROR;
}
/* is there a file name argument */
if (filename == NULL) {
if (iVerbosity == NXalot) {
NXReportError("NXDinitfrom file finished without data");
}
*pData = pNew;
return NX_OK;
}
fd = fopen(filename, "rb");
if (!fd) {
sprintf(pError, "ERROR: file %s NOT found ", filename);
NXReportError(pError);
NXReportError("NXDinitfrom file finished without data");
*pData = pNew;
return NX_ERROR;
}
/* read the file contents */
if (iVerbosity == NXalot) {
NXReportError("NXDinitfrom: reading file");
}
pBuffer = NXDIReadFile(fd);
fclose(fd); /* we are done with it then */
if (!pBuffer) {
sprintf(pError, "ERROR: reading file %s or no memory", filename);
NXReportError(pError);
NXReportError("NXDinitfrom file finished without data");
*pData = pNew;
return NX_ERROR;
}
/* parse it */
if (iVerbosity == NXalot) {
NXReportError("NXDinitfrom: parsing dictionary definitions");
}
NXDIParse(pBuffer, pNew->pDictionary);
if (iVerbosity == NXalot) {
NXReportError("NXDinitfrom: performed successfully");
}
free(pBuffer);
*pData = pNew;
return NX_OK;
}
/*--------------------------------------------------------------------------*/
NXdict NXDIAssert(NXdict handle)
{
NXdict self = NULL;
assert(handle);
self = (NXdict) handle;
assert(self->iID == NXDMAGIC);
return self;
}
/*-------------------------------------------------------------------------*/
NXstatus NXDclose(NXdict handle, char *filename)
{
NXdict self;
const char *pKey = NULL;
char pValue[1024];
FILE *fd = NULL;
self = NXDIAssert(handle);
if (filename) { /* we must write a file */
if (iVerbosity == NXalot) {
sprintf(pValue, "Writing file %s", filename);
NXReportError(pValue);
}
fd = fopen(filename, "w");
if (!fd) {
sprintf(pValue, "ERROR: opening file %s for write", filename);
NXReportError(pValue);
return NX_ERROR;
}
/* write our magic recognition header */
fprintf(fd, "##NXDICT-1.0\n");
/* write all our keys */
pKey = StringDictGetNext(self->pDictionary, pValue, 1023);
while (pKey != NULL) {
fprintf(fd, "%s = %s\n", pKey, pValue);
pKey = StringDictGetNext(self->pDictionary, pValue, 1023);
}
fclose(fd);
if (iVerbosity == NXalot) {
sprintf(pValue, "File %s written", filename);
NXReportError(pValue);
}
}
/* now we send the cleaners in */
DeleteStringDict(self->pDictionary);
free(self);
return NX_OK;
}
/*------------------------------------------------------------------------*/
NXstatus NXDadd(NXdict handle, char *alias, char *pDef)
{
NXdict self;
int iRet;
self = NXDIAssert(handle);
iRet = StringDictAddPair(self->pDictionary, alias, pDef);
if (!iRet) {
return NX_ERROR;
}
return NX_OK;
}
/*---------------------------------------------------------------------------*/
NXstatus NXDget(NXdict handle, char *pKey, char *pBuffer, int iBufLen)
{
NXdict self;
int iRet;
self = NXDIAssert(handle);
iRet = StringDictGet(self->pDictionary, pKey, pBuffer, iBufLen);
if (!iRet) {
return NX_ERROR;
}
#ifdef DEFDEBUG
printf("Resolved: %s to %s\n", pKey, pBuffer);
#endif
return NX_OK;
}
/*-------------------------------------------------------------------------*/
NXstatus NXDupdate(NXdict handle, char *pKey, char *pNewVal)
{
NXdict self;
int iRet;
self = NXDIAssert(handle);
iRet = StringDictUpdate(self->pDictionary, pKey, pNewVal);
if (!iRet) {
return NX_ERROR;
}
return NX_OK;
}
/*-----------------------------------------------------------------------*/
#define NORMAL 1
#define ALIAS 2
pDynString NXDItextreplace(NXdict handle, char *pDefString)
{
NXdict self;
int iRet, iPos, i;
pDynString pReplaced = NULL;
char pBueffel[1024];
char pBuffer2[1024];
char *pPtr;
int iState;
self = NXDIAssert(handle);
/* create a dynamic string */
pReplaced = CreateDynString(strlen(pDefString), 512);
if (!pReplaced) {
NXReportError("ERROR: out of memory in NXDtextreplace");
return NULL;
}
/* the loop */
iState = NORMAL;
for (i = 0, pPtr = pDefString; i < strlen(pDefString); i++, pPtr++) {
if (iState == NORMAL) {
if (*pPtr == '$') {
iState = ALIAS;
memset(pBueffel, 0, 1024);
iPos = 0;
} else {
DynStringConcatChar(pReplaced, *pPtr);
}
} else if (iState == ALIAS) {
switch (*pPtr) {
case '(': /* ignore */
break;
case ')':
/* do the replacement */
memset(pBuffer2, 0, 1023);
iRet = NXDget(handle, pBueffel, pBuffer2, 1023);
if (iRet != NX_OK) {
DeleteDynString(pReplaced);
return NULL;
}
DynStringConcat(pReplaced, pBuffer2);
iState = NORMAL;
break;
default:
pBueffel[iPos] = *pPtr;
iPos++;
if (iPos >= 1024) {
NXReportError("ERROR: buffer overrun in NXDItextreplace");
DeleteDynString(pReplaced);
return NULL;
}
break;
}
}
}
#ifdef DEFDEBUG
printf("Replacement result: %s\n", GetCharArray(pReplaced));
#endif
return pReplaced;
}
/*------------------------------------------------------------------------*/
NXstatus NXDdefget(NXdict handle, char *pKey, char *pBuffer, int iBufLen)
{
int status;
pDynString pRep = NULL;
status = NXDget(handle, pKey, pBuffer, iBufLen);
if (status != NX_OK) {
return status;
}
pRep = NXDItextreplace(handle, pBuffer);
if (pRep) {
strncpy(pBuffer, GetCharArray(pRep), iBufLen);
status = NX_OK;
DeleteDynString(pRep);
} else {
status = NX_ERROR;
}
return status;
}
/*--------------------------------------------------------------------------*/
NXstatus NXDtextreplace(NXdict handle, char *pDefString,
char *pBuffer, int iBufLen)
{
pDynString pResult = NULL;
char *pPtr = NULL;
pResult = NXDItextreplace(handle, pDefString);
if (!pResult) {
return NX_ERROR;
}
/* copy results home */
pPtr = GetCharArray(pResult);
strncpy(pBuffer, pPtr, iBufLen);
DeleteDynString(pResult);
return NX_OK;
}
/*------------------- The Defintion String Parser -----------------------*/
/*------- Data structures */
typedef struct {
char *pText;
int iCode;
} TokDat;
#define TERMSDS 100
#define TERMVG 200
#define TERMLINK 300
typedef struct {
char *pPtr;
char pToken[256];
int iToken;
int iDepth;
int iMayCreate;
int iTerminal;
} ParDat;
static void DummyError(void *p, char *pError)
{
return;
}
typedef struct {
char name[256];
char value[256];
} AttItem;
/*---------------- Token name defines ---------------------------*/
#define DSLASH 0
#define DKOMMA 1
#define DSDS 2
#define DLINK 3
#define DGROUP 4
#define DRANK 5
#define DDIM 6
#define DTYPE 7
#define DWORD 9
#define DOPEN 10
#define DCLOSE 11
#define DATTR 12
#define DEND 13
#define DLZW 14
#define DHUF 15
#define DRLE 16
#define CHUNK 17
/*----------------- Keywords ----------------------------------------*/
static TokDat TokenList[12] = {
{"SDS", DSDS},
{"NXLINK", DLINK},
{"NXVGROUP", DGROUP},
{"-dim", DDIM},
{"-type", DTYPE},
{"-rank", DRANK},
{"-attr", DATTR},
{"-chunk", CHUNK},
{"-LZW", DLZW},
{"-HUF", DHUF},
{"-RLE", DRLE},
{NULL, 0}
};
/*-----------------------------------------------------------------------*/
static void NXDIDefToken(ParDat * sStat)
{
int i;
sStat->pToken[0] = '\0';
/* skip whitespace */
while ((*(sStat->pPtr) == ' ') || (*(sStat->pPtr) == '\t')) {
sStat->pPtr++;
}
/* check for special characters */
if (*(sStat->pPtr) == '/') {
sStat->iToken = DSLASH;
sStat->pToken[0] = *(sStat->pPtr);
sStat->pPtr++;
return;
} else if (*(sStat->pPtr) == ',') {
sStat->iToken = DKOMMA;
sStat->pToken[0] = *(sStat->pPtr);
sStat->pPtr++;
return;
} else if (*(sStat->pPtr) == '\0') {
sStat->iToken = DEND;
sStat->pToken[0] = *(sStat->pPtr);
sStat->pPtr++;
return;
} else if (*(sStat->pPtr) == '{') {
sStat->iToken = DOPEN;
sStat->pToken[0] = *(sStat->pPtr);
sStat->pPtr++;
return;
} else if (*(sStat->pPtr) == '}') {
sStat->iToken = DCLOSE;
sStat->pToken[0] = *(sStat->pPtr);
sStat->pPtr++;
return;
} else {
sStat->iToken = DWORD;
/* copy word to pToken */
i = 0;
while ((*(sStat->pPtr) != ' ') && (*(sStat->pPtr) != '\t') &&
(*(sStat->pPtr) != '/') && (*(sStat->pPtr) != '\0') &&
(*(sStat->pPtr) != ',') && (*(sStat->pPtr) != '}')) {
sStat->pToken[i] = *(sStat->pPtr);
sStat->pPtr++;
i++;
}
sStat->pToken[i] = '\0';
/*--------- try to find word in Tokenlist */
for (i = 0; i < 11; i++) {
if (strcmp(sStat->pToken, TokenList[i].pText) == 0) {
sStat->iToken = TokenList[i].iCode;
break;
}
}
return;
}
/* not reached */
return;
}
/*-----------------------------------------------------------------------*/
static void NXDIAttValue(ParDat * sStat)
{
int i;
sStat->pToken[0] = '\0';
/* skip whitespace */
while ((*(sStat->pPtr) == ' ') || (*(sStat->pPtr) == '\t')) {
sStat->pPtr++;
}
if (*(sStat->pPtr) == ',') {
sStat->iToken = DKOMMA;
sStat->pToken[0] = *(sStat->pPtr);
sStat->pPtr++;
return;
} else if (*(sStat->pPtr) == '\0') {
sStat->iToken = DEND;
sStat->pToken[0] = *(sStat->pPtr);
sStat->pPtr++;
return;
} else if (*(sStat->pPtr) == '{') {
sStat->iToken = DOPEN;
sStat->pToken[0] = *(sStat->pPtr);
sStat->pPtr++;
return;
} else if (*(sStat->pPtr) == '}') {
sStat->iToken = DCLOSE;
sStat->pToken[0] = *(sStat->pPtr);
sStat->pPtr++;
return;
} else if(*(sStat->pPtr) == '"') {
sStat->pPtr++;
sStat->iToken = DWORD;
i= 0;
while(*(sStat->pPtr) != '"') {
sStat->pToken[i] = *(sStat->pPtr);
sStat->pPtr++;
i++;
}
sStat->pToken[i] = '\0';
sStat->pPtr++;
return;
} else {
sStat->iToken = DWORD;
/* copy word to pToken */
i = 0;
while ((*(sStat->pPtr) != ' ') && (*(sStat->pPtr) != '\t') &&
(*(sStat->pPtr) != '\0') &&
(*(sStat->pPtr) != ',') && (*(sStat->pPtr) != '}')) {
sStat->pToken[i] = *(sStat->pPtr);
sStat->pPtr++;
i++;
}
sStat->pToken[i] = '\0';
return;
}
/* not reached */
return;
}
/*------------------------------------------------------------------------*/
int NXDIParsePath(NXhandle hfil, ParDat * pParse)
{
int iRet, iToken;
char pName[132], pClass[132];
char pError[256];
void *pData = NULL;
/* get the name */
NXDIDefToken(pParse); /* next token */
if ((pParse->iToken == DSDS) || (pParse->iToken == DGROUP)
|| (pParse->iToken == DLINK)) {
/* put back & OK */
pParse->pPtr -= strlen(pParse->pToken);
return NX_OK;
}
if (pParse->iToken != DWORD) {
sprintf(pError, "ERROR: parse error at %s, expected vGroup name",
pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
strcpy(pName, pParse->pToken);
/* now we expect a komma */
NXDIDefToken(pParse); /* next token */
if (pParse->iToken != DKOMMA) {
sprintf(pError, "ERROR: parse error at %s, expected komma",
pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
/* next must be the class */
NXDIDefToken(pParse); /* next token */
if (pParse->iToken != DWORD) {
sprintf(pError, "ERROR: parse error at %s, expected vGroup class",
pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
strcpy(pClass, pParse->pToken);
/* done reading, ACTION, first install dummy error handler */
NXMDisableErrorReporting();
/* try opening vGroup */
iRet = NXopengroup(hfil, pName, pClass);
NXMEnableErrorReporting();
if (iRet == NX_OK) {
pParse->iDepth++;
return NX_OK;
} else {
/* we need to create it, if we may */
if (pParse->iMayCreate) {
iRet = NXmakegroup(hfil, pName, pClass);
if (iRet != NX_OK) {
/* a comment on this one has already been written! */
return iRet;
}
iRet = NXopengroup(hfil, pName, pClass);
if (iRet != NX_OK) {
/* a comment on this one has already been written! */
return iRet;
}
pParse->iDepth++;
return NX_OK;
} else {
/* this is an error */
sprintf(pError, "ERROR: vGroup %s, %s NOT found", pName, pClass);
NXReportError(pError);
return NX_ERROR;
}
}
/* not reached */
return NX_ERROR;
}
/*------------------------------------------------------------------------*/
static int NXDIParseAttr(ParDat * pParse, int iList)
{
char pError[256];
int iRet;
AttItem sAtt;
/* a { is expected */
NXDIDefToken(pParse);
if (pParse->iToken != DOPEN) {
sprintf(pError, "ERROR: expected {, got %s", pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
/* a word is expected */
NXDIDefToken(pParse);
if (pParse->iToken != DWORD) {
sprintf(pError, "ERROR: expected attribute name, got %s",
pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
strcpy(sAtt.name, pParse->pToken);
if(strstr(sAtt.name,"offset") != NULL){
printf("%s \n",sAtt.name);
}
/* a , is expected */
NXDIDefToken(pParse);
if (pParse->iToken != DKOMMA) {
sprintf(pError, "ERROR: expected , , got %s", pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
/* a word is expected */
NXDIAttValue(pParse);
if (pParse->iToken != DWORD) {
sprintf(pError, "ERROR: expected attribute value, got %s",
pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
strcpy(sAtt.value, pParse->pToken);
/* a } is expected */
NXDIDefToken(pParse);
if (pParse->iToken != DCLOSE) {
sprintf(pError, "ERROR: expected }, got %s", pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
/* enter into list */
LLDnodeAppendFrom(iList, &sAtt);
return NX_OK;
}
/*------------------------------------------------------------------------*/
static int NXDIParseDim(ParDat * pParse, int *iDim)
{
char pError[256];
int iRet, i;
/* initialise dimensions to 0 */
for (i = 0; i < NX_MAXRANK; i++) {
iDim[i] = 0;
}
NXDIDefToken(pParse);
if (pParse->iToken != DOPEN) {
sprintf(pError, "ERROR: expected {, got %s", pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
i = 0;
while (pParse->iToken != DCLOSE) {
/* get a number */
NXDIDefToken(pParse);
if (pParse->iToken != DWORD) {
sprintf(pError, "ERROR: expected number, got %s", pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
iDim[i] = atoi(pParse->pToken);
i++;
/* next must be close of komma */
NXDIDefToken(pParse);
if ((pParse->iToken != DKOMMA) && (pParse->iToken != DCLOSE)) {
sprintf(pError, "ERROR: expected , or }, got %s", pParse->pToken);
NXReportError( pError);
return NX_ERROR;
}
if (pParse->iToken == DCLOSE) {
break;
}
}
return NX_OK;
}
/*------------------------------------------------------------------------*/
static TokDat tDatType[] = {
{"DFNT_FLOAT32", NX_FLOAT32},
{"DFNT_FLOAT64", NX_FLOAT64},
{"DFNT_INT8", NX_INT8},
{"DFNT_UINT8", NX_UINT8},
{"DFNT_INT16", NX_INT16},
{"DFNT_UINT16", NX_UINT16},
{"DFNT_INT32", NX_INT32},
{"DFNT_UINT32", NX_UINT32},
{"DFNT_CHAR", NX_CHAR},
{"NX_FLOAT32", NX_FLOAT32},
{"NX_FLOAT64", NX_FLOAT64},
{"NX_INT8", NX_INT8},
{"NX_UINT8", NX_UINT8},
{"NX_INT16", NX_INT16},
{"NX_UINT16", NX_UINT16},
{"NX_INT32", NX_INT32},
{"NX_UINT32", NX_UINT32},
{"NX_CHAR", NX_CHAR},
{NULL, -122}
};
static int NXDIParseType(ParDat * pParse, int *iType)
{
char pError[256];
int i = 0;
NXDIDefToken(pParse);
if (pParse->iToken != DWORD) {
sprintf(pError, "ERROR: expected data type, got %s", pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
/* try to interpret data type */
while (tDatType[i].iCode > 0) {
if (strcmp(tDatType[i].pText, pParse->pToken) == 0) {
*iType = tDatType[i].iCode;
return NX_OK;
}
i++;
}
/* if we are here, the data type has not been recognized. Reason for
some boring error reporting code
*/
sprintf(pError, "ERROR: %s not recognized as valid data type",
pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
/*-------------------------------------------------------------------------*/
static int NXDIParseSDS(NXhandle hfil, ParDat * pParse)
{
int iType = NX_FLOAT32;
int iRank = 1;
int iCompress = NX_COMP_NONE;
int iDim[NX_MAXRANK], iChunk[NX_MAXRANK];
int iList, iChunkDefined = 0;
int iRet, iStat, i;
char pError[256];
char pName[NX_MAXNAMELEN];
AttItem sAtt;
iDim[0] = 1;
/* first find the name */
NXDIDefToken(pParse);
if (pParse->iToken != DWORD) {
sprintf(pError, "ERROR: parsing, expected name, got %s",
pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
strcpy(pName, pParse->pToken);
/* create the attribute list */
iList = LLDcreate(sizeof(AttItem));
if (iList < 0) {
NXReportError("ERROR: cannot create list in NXDIParseSDS");
return NX_ERROR;
}
NXDIDefToken(pParse);
while (pParse->iToken != DEND) {
switch (pParse->iToken) {
case DRANK: /* rank */
NXDIDefToken(pParse); /* advance */
if (pParse->iToken != DWORD) {
sprintf(pError, "ERROR: expected int, got %s", pParse->pToken);
NXReportError(pError);
LLDdelete(iList);
return NX_ERROR;
}
iRank = atoi(pParse->pToken);
break;
case CHUNK: /* chunk size for compression */
iRet = NXDIParseDim(pParse, iChunk);
if (iRet == NX_ERROR) {
LLDdelete(iList);
return iRet;
}
iChunkDefined = 1;
break;
case DDIM:
iRet = NXDIParseDim(pParse, iDim);
if (iRet == NX_ERROR) {
LLDdelete(iList);
return iRet;
}
break;
case DTYPE:
iRet = NXDIParseType(pParse, &iType);
if (iRet == NX_ERROR) {
LLDdelete(iList);
return iRet;
}
break;
case DATTR:
iRet = NXDIParseAttr(pParse, iList);
if (iRet == NX_ERROR) {
LLDdelete(iList);
return iRet;
}
break;
case DLZW:
iCompress = NX_COMP_LZW;
break;
case DRLE:
iCompress = NX_COMP_RLE;
break;
case DHUF:
iCompress = NX_COMP_HUF;
break;
case DEND:
break;
default:
sprintf(pError, "ERROR: cannot identify token %s", pParse->pToken);
NXReportError(pError);
LLDdelete(iList);
return NX_ERROR;
}
NXDIDefToken(pParse);
}
/* whew! got all information for doing the SDS
However, if the chunk sizes for compression have not
been set, default them to the dimensions of the data set
*/
if (iChunkDefined == 0) {
for (i = 0; i < iRank; i++) {
iChunk[i] = iDim[i];
}
}
if (iChunk[0] < 0) {
iChunk[0] = 1;
}
/* first install dummy error handler, try open it, then
deinstall again and create if allowed
*/
NXMDisableErrorReporting();
/* try opening SDS */
iRet = NXopendata(hfil, pName);
NXMEnableErrorReporting();
if (iRet == NX_OK) {
LLDdelete(iList);
return NX_OK;
} else {
/* we need to create it, if we may */
if (pParse->iMayCreate) {
iRet = NXcompmakedata(hfil, pName, iType, iRank, iDim,
iCompress, iChunk);
if (iRet != NX_OK) {
/* a comment on this one has already been written! */
LLDdelete(iList);
return iRet;
}
iRet = NXopendata(hfil, pName);
if (iRet != NX_OK) {
/* a comment on this one has already been written! */
LLDdelete(iList);
return iRet;
}
/* put attributes in */
iRet = LLDnodePtr2First(iList);
while (iRet != 0) {
LLDnodeDataTo(iList, &sAtt);
iStat = NXputattr(hfil, sAtt.name,
sAtt.value, strlen(sAtt.value), NX_CHAR);
if (iStat != NX_OK) {
/* NeXus already complained bitterly */
LLDdelete(iList);
return iStat;
}
iRet = LLDnodePtr2Next(iList);
}
LLDdelete(iList);
return NX_OK;
} else {
/* this is an error */
sprintf(pError, "ERROR: SDS %s NOT found", pName);
NXReportError(pError);
LLDdelete(iList);
return NX_ERROR;
}
}
return NX_OK;
}
/*------------------------------------------------------------------------*/
static int NXDIParseLink(NXhandle hfil, NXdict pDict, ParDat * pParse)
{
char pError[256];
int i, iRet;
/* need one word of alias */
NXDIDefToken(pParse);
if (pParse->iToken != DCLOSE) {
sprintf(pError, "ERROR: expected alias , got %s", pParse->pToken);
NXReportError(pError);
return NX_ERROR;
}
/* move back in hierarchy */
for (i = 0; i < pParse->iDepth; i++) {
iRet = NXclosegroup(hfil);
if (iRet == NX_ERROR) {
return NX_ERROR;
}
}
/* open the link instead */
return NXDopenalias(hfil, pDict, pParse->pToken);
}
/*------------------------------------------------------------------------*/
int NXDIDefParse(NXhandle hFil, NXdict pDict, ParDat * pParse)
{
int iRet;
char pError[256];
pParse->iToken = -1;
while (pParse->iToken != DEND) {
NXDIDefToken(pParse); /* next token */
switch (pParse->iToken) {
case DEND:
break;
case DSLASH:
iRet = NXDIParsePath(hFil, pParse);
if (iRet == NX_ERROR) {
return NX_ERROR;
}
break;
case DSDS:
iRet = NXDIParseSDS(hFil, pParse);
if (iRet == NX_ERROR) {
return NX_ERROR;
}
pParse->iTerminal = TERMSDS;
break;
case DLINK:
iRet = NXDIParseLink(hFil, pDict, pParse);
if (iRet == NX_ERROR) {
return NX_ERROR;
}
pParse->iTerminal = TERMLINK;
break;
case DGROUP:
pParse->iTerminal = TERMVG;
return NX_OK;
default:
sprintf(pError,
"ERROR: Definition String parse error: %s not permitted here",
pParse->pToken);
NXReportError(pError);
return NX_ERROR;
break;
}
}
return NX_OK;
}
/*----------------------------------------------------------------------*/
NXstatus NXDIUnwind(NXhandle hFil, int iDepth)
{
int i, iRet;
for (i = 0; i < iDepth; i++) {
iRet = NXclosegroup(hFil);
if (iRet != NX_OK) {
return NX_ERROR;
}
}
return NX_OK;
}
/*-------------------- The Data Transfer Functions ----------------------*/
NXstatus NXDopendef(NXhandle hfil, NXdict dict, char *pDef)
{
NXdict pDict;
ParDat pParse;
int iRet, i, iStat;
pDict = NXDIAssert(dict);
/* parse and act on definition string */
pParse.iMayCreate = 1;
pParse.pPtr = pDef;
pParse.iDepth = 0;
iRet = NXDIDefParse(hfil, pDict, &pParse);
if (iRet == NX_ERROR) {
/* unwind and throw up */
iRet = NXDIUnwind(hfil, pParse.iDepth);
return NX_ERROR;
}
return iRet;
}
/*------------------------------------------------------------------------*/
NXstatus NXDopenalias(NXhandle hfil, NXdict dict, char *pAlias)
{
NXdict pDict;
int iRet;
char pDefinition[2048];
pDynString pReplaced = NULL;
pDict = NXDIAssert(dict);
/* get Definition String */
iRet = NXDget(pDict, pAlias, pDefinition, 2047);
if (iRet != NX_OK) {
sprintf(pDefinition, "ERROR: alias %s not recognized", pAlias);
NXReportError(pDefinition);
return NX_ERROR;
}
/* do the text replacement */
pReplaced = NXDItextreplace(dict, pDefinition);
if (!pReplaced) {
return NX_ERROR;
}
/* call NXDopendef */
iRet = NXDopendef(hfil, dict, GetCharArray(pReplaced));
DeleteDynString(pReplaced);
return iRet;
}
/*------------------------------------------------------------------------*/
NXstatus NXDputdef(NXhandle hFil, NXdict dict, char *pDef, void *pData)
{
NXdict pDict;
ParDat pParse;
int iRet, i, iStat;
pDict = NXDIAssert(dict);
/* parse and act on definition string */
pParse.iMayCreate = 1;
pParse.pPtr = pDef;
pParse.iDepth = 0;
#ifdef DEFDEBUG
printf("Putting: %s\n", pDef);
#endif
iRet = NXDIDefParse(hFil, pDict, &pParse);
if (iRet == NX_ERROR) {
NXDIUnwind(hFil, pParse.iDepth);
return NX_ERROR;
}
/* only SDS can be written */
if (pParse.iTerminal != TERMSDS) {
NXReportError("ERROR: can only write to an SDS!");
iStat = NX_ERROR;
} else {
/* the SDS should be open by now, write it */
iStat = NXputdata(hFil, pData);
iRet = NXclosedata(hFil);
}
/* rewind the hierarchy */
iRet = NXDIUnwind(hFil, pParse.iDepth);
if (iRet != NX_OK) {
return NX_ERROR;
}
return iStat;
}
/*------------------------------------------------------------------------*/
NXstatus NXDputalias(NXhandle hFil, NXdict dict, char *pAlias, void *pData)
{
NXdict pDict;
int iRet;
char pDefinition[2048];
pDynString pReplaced = NULL;
pDict = NXDIAssert(dict);
/* get Definition String */
iRet = NXDget(pDict, pAlias, pDefinition, 2047);
if (iRet != NX_OK) {
sprintf(pDefinition, "ERROR: alias %s not recognized", pAlias);
NXReportError( pDefinition);
return NX_ERROR;
}
/* do text replacement */
pReplaced = NXDItextreplace(dict, pDefinition);
if (!pReplaced) {
return NX_ERROR;
}
/* call NXDputdef */
iRet = NXDputdef(hFil, dict, GetCharArray(pReplaced), pData);
DeleteDynString(pReplaced);
return iRet;
}
/*------------------------------------------------------------------------*/
NXstatus NXDgetdef(NXhandle hFil, NXdict dict, char *pDef, void *pData)
{
NXdict pDict;
ParDat pParse;
int iRet, i, iStat;
pDict = NXDIAssert(dict);
/* parse and act on definition string */
pParse.iMayCreate = 0;
pParse.pPtr = pDef;
pParse.iDepth = 0;
#ifdef DEFDEBUG
printf("Getting: %s\n", pDef);
#endif
iRet = NXDIDefParse(hFil, pDict, &pParse);
if (iRet == NX_ERROR) {
/* unwind and throw up */
NXDIUnwind(hFil, pParse.iDepth);
return NX_ERROR;
}
/* only SDS can be written */
if (pParse.iTerminal != TERMSDS) {
NXReportError("ERROR: can only write to an SDS!");
iStat = NX_ERROR;
} else {
/* the SDS should be open by now, read it */
iStat = NXgetdata(hFil, pData);
iRet = NXclosedata(hFil);
}
/* rewind the hierarchy */
iRet = NXDIUnwind(hFil, pParse.iDepth);
if (iRet != NX_OK) {
return NX_ERROR;
}
return iStat;
}
/*------------------------------------------------------------------------*/
NXstatus NXDgetalias(NXhandle hFil, NXdict dict, char *pAlias, void *pData)
{
NXdict pDict;
int iRet;
char pDefinition[2048];
pDynString pReplaced = NULL;
pDict = NXDIAssert(dict);
/* get Definition String */
iRet = NXDget(pDict, pAlias, pDefinition, 2047);
if (iRet != NX_OK) {
sprintf(pDefinition, "ERROR: alias %s not recognized", pAlias);
NXReportError(pDefinition);
return NX_ERROR;
}
/* do text replacement */
pReplaced = NXDItextreplace(dict, pDefinition);
if (!pReplaced) {
return NX_ERROR;
}
/* call NXDgetdef */
iRet = NXDgetdef(hFil, dict, GetCharArray(pReplaced), pData);
DeleteDynString(pReplaced);
return iRet;
}
/*------------------------------------------------------------------------*/
NXstatus NXDinfodef(NXhandle hFil, NXdict dict, char *pDef, int *rank,
int dimension[], int *iType)
{
NXdict pDict;
ParDat pParse;
int iRet, i, iStat;
pDict = NXDIAssert(dict);
/* parse and act on definition string */
pParse.iMayCreate = 0;
pParse.pPtr = pDef;
pParse.iDepth = 0;
#ifdef DEFDEBUG
printf("Getting: %s\n", pDef);
#endif
iRet = NXDIDefParse(hFil, pDict, &pParse);
if (iRet == NX_ERROR) {
/* unwind and throw up */
NXDIUnwind(hFil, pParse.iDepth);
return NX_ERROR;
}
/* only SDS can be written */
if (pParse.iTerminal != TERMSDS) {
NXReportError("ERROR: can only write to an SDS!");
iStat = NX_ERROR;
} else {
/* the SDS should be open by now, read it */
iStat = NXgetinfo(hFil, rank, dimension, iType);
iRet = NXclosedata(hFil);
}
/* rewind the hierarchy */
iRet = NXDIUnwind(hFil, pParse.iDepth);
if (iRet != NX_OK) {
return NX_ERROR;
}
return iStat;
}
/*------------------------------------------------------------------------*/
NXstatus NXDinfoalias(NXhandle hFil, NXdict dict, char *pAlias, int *rank,
int dimension[], int *iType)
{
NXdict pDict;
int iRet;
char pDefinition[2048];
pDynString pReplaced = NULL;
pDict = NXDIAssert(dict);
/* get Definition String */
iRet = NXDget(pDict, pAlias, pDefinition, 2047);
if (iRet != NX_OK) {
sprintf(pDefinition, "ERROR: alias %s not recognized", pAlias);
NXReportError(pDefinition);
return NX_ERROR;
}
/* do text replacement */
pReplaced = NXDItextreplace(dict, pDefinition);
if (!pReplaced) {
return NX_ERROR;
}
/* call NXDgetdef */
iRet =
NXDinfodef(hFil, dict, GetCharArray(pReplaced), rank, dimension,
iType);
DeleteDynString(pReplaced);
return iRet;
}
/*------------------------------------------------------------------------*/
NXstatus NXDdefnamedlink(NXhandle hFil, NXdict dict,
char *pTarget, char *pVictim, char *newname)
{
NXdict pDict;
ParDat pParseT, pParseV;
int iRet, i, iStat;
NXlink sLink;
pDict = NXDIAssert(dict);
#ifdef DEFDEBUG
printf("Linking: %s\n", pVictim);
printf("To: %s\n", pTarget);
#endif
/* parse Victim */
pParseV.iMayCreate = 0;
pParseV.pPtr = pVictim;
pParseV.iDepth = 0;
iRet = NXDIDefParse(hFil, pDict, &pParseV);
if (iRet == NX_ERROR) {
/* unwind and throw up */
NXDIUnwind(hFil, pParseV.iDepth);
return NX_ERROR;
}
/* get link data */
if (pParseV.iTerminal == TERMSDS) {
NXgetdataID(hFil, &sLink);
iRet = NXclosedata(hFil);
if (iRet != NX_OK) {
/* unwind and throw up */
NXDIUnwind(hFil, pParseV.iDepth);
return NX_ERROR;
}
} else if (pParseV.iTerminal == TERMVG) {
NXgetgroupID(hFil, &sLink);
} else {
assert(0); /* serious programming error */
}
/* Unwind */
iRet = NXDIUnwind(hFil, pParseV.iDepth);
if (iRet != NX_OK) {
return NX_ERROR;
}
/* parse Target */
pParseT.iMayCreate = 1;
pParseT.pPtr = pTarget;
pParseT.iDepth = 0;
iRet = NXDIDefParse(hFil, pDict, &pParseT);
if (iRet == NX_ERROR) {
/* unwind and throw up */
NXDIUnwind(hFil, pParseT.iDepth);
return NX_ERROR;
}
/* check it being a vGroup! */
if (pParseT.iTerminal != TERMVG) {
NXReportError("ERROR: can link only into a vGroup");
NXDIUnwind(hFil, pParseT.iDepth);
return NX_ERROR;
}
/* link, finally */
iRet = NXmakenamedlink(hFil, newname, &sLink);
/* Unwind anyway */
iStat = NXDIUnwind(hFil, pParseT.iDepth);
if (iStat != NX_OK) {
return NX_ERROR;
}
return iStat;
}
/*--------------------------------------------------------------------------*/
NXstatus NXDaliasnamedlink(NXhandle hFil, NXdict dict,
char *pTarget, char *pVictim, char *newname)
{
char pTargetDef[2048], pVictimDef[2048];
int iRet;
NXdict pDict;
pDynString pRep1 = NULL, pRep2 = NULL;
pDict = NXDIAssert(dict);
/* get Target Definition String */
iRet = NXDget(pDict, pTarget, pTargetDef, 2047);
if (iRet != NX_OK) {
sprintf(pTargetDef, "ERROR: alias %s not recognized", pTarget);
NXReportError(pTargetDef);
return NX_ERROR;
}
/* get Victim definition string */
iRet = NXDget(pDict, pVictim, pVictimDef, 2047);
if (iRet != NX_OK) {
sprintf(pTargetDef, "ERROR: alias %s not recognized", pTarget);
NXReportError(pTargetDef);
return NX_ERROR;
}
/* do replacements */
pRep1 = NXDItextreplace(dict, pTargetDef);
pRep2 = NXDItextreplace(dict, pVictimDef);
if ((!pRep1) || (!pRep2)) {
if (pRep1)
DeleteDynString(pRep1);
if (pRep2)
DeleteDynString(pRep2);
return NX_ERROR;
}
/* call NXdeflin */
iRet = NXDdefnamedlink(hFil, pDict, GetCharArray(pRep1), GetCharArray(pRep2), newname);
DeleteDynString(pRep1);
DeleteDynString(pRep2);
return iRet;
}
/*------------------------------------------------------------------------*/
NXstatus NXDdeflink(NXhandle hFil, NXdict dict,
char *pTarget, char *pVictim)
{
NXdict pDict;
ParDat pParseT, pParseV;
int iRet, i, iStat;
NXlink sLink;
pDict = NXDIAssert(dict);
#ifdef DEFDEBUG
printf("Linking: %s\n", pVictim);
printf("To: %s\n", pTarget);
#endif
/* parse Victim */
pParseV.iMayCreate = 0;
pParseV.pPtr = pVictim;
pParseV.iDepth = 0;
iRet = NXDIDefParse(hFil, pDict, &pParseV);
if (iRet == NX_ERROR) {
/* unwind and throw up */
NXDIUnwind(hFil, pParseV.iDepth);
return NX_ERROR;
}
/* get link data */
if (pParseV.iTerminal == TERMSDS) {
NXgetdataID(hFil, &sLink);
iRet = NXclosedata(hFil);
if (iRet != NX_OK) {
/* unwind and throw up */
NXDIUnwind(hFil, pParseV.iDepth);
return NX_ERROR;
}
} else if (pParseV.iTerminal == TERMVG) {
NXgetgroupID(hFil, &sLink);
} else {
assert(0); /* serious programming error */
}
/* Unwind */
iRet = NXDIUnwind(hFil, pParseV.iDepth);
if (iRet != NX_OK) {
return NX_ERROR;
}
/* parse Target */
pParseT.iMayCreate = 1;
pParseT.pPtr = pTarget;
pParseT.iDepth = 0;
iRet = NXDIDefParse(hFil, pDict, &pParseT);
if (iRet == NX_ERROR) {
/* unwind and throw up */
NXDIUnwind(hFil, pParseT.iDepth);
return NX_ERROR;
}
/* check it being a vGroup! */
if (pParseT.iTerminal != TERMVG) {
NXReportError("ERROR: can link only into a vGroup");
NXDIUnwind(hFil, pParseT.iDepth);
return NX_ERROR;
}
/* link, finally */
iRet = NXmakelink(hFil, &sLink);
/* Unwind anyway */
iStat = NXDIUnwind(hFil, pParseT.iDepth);
if (iStat != NX_OK) {
return NX_ERROR;
}
return iStat;
}
/*--------------------------------------------------------------------------*/
NXstatus NXDaliaslink(NXhandle hFil, NXdict dict,
char *pTarget, char *pVictim)
{
char pTargetDef[2048], pVictimDef[2048];
int iRet;
NXdict pDict;
pDynString pRep1 = NULL, pRep2 = NULL;
pDict = NXDIAssert(dict);
/* get Target Definition String */
iRet = NXDget(pDict, pTarget, pTargetDef, 2047);
if (iRet != NX_OK) {
sprintf(pTargetDef, "ERROR: alias %s not recognized", pTarget);
NXReportError(pTargetDef);
return NX_ERROR;
}
/* get Victim definition string */
iRet = NXDget(pDict, pVictim, pVictimDef, 2047);
if (iRet != NX_OK) {
sprintf(pTargetDef, "ERROR: alias %s not recognized", pTarget);
NXReportError(pTargetDef);
return NX_ERROR;
}
/* do replacements */
pRep1 = NXDItextreplace(dict, pTargetDef);
pRep2 = NXDItextreplace(dict, pVictimDef);
if ((!pRep1) || (!pRep2)) {
if (pRep1)
DeleteDynString(pRep1);
if (pRep2)
DeleteDynString(pRep2);
return NX_ERROR;
}
/* call NXdeflin */
iRet = NXDdeflink(hFil, pDict, GetCharArray(pRep1), GetCharArray(pRep2));
DeleteDynString(pRep1);
DeleteDynString(pRep2);
return iRet;
}
/*-------------------------------------------------------------------------*/
static void SNXFormatTime(char *pBuffer, int iBufLen)
{
time_t iDate;
struct tm *psTime;
/* make time string */
iDate = time(NULL);
psTime = localtime(&iDate);
memset(pBuffer, 0, iBufLen);
strftime(pBuffer, iBufLen, "%Y-%m-%d %H:%M:%S", psTime);
}
/*--------------------------------------------------------------------------*/
NXstatus NXUwriteglobals(NXhandle pFile,
char *filename,
char *owner,
char *adress,
char *phone,
char *email, char *fax, char *instrument)
{
char pBueffel[512];
int iStat;
/* store global attributes, now done by NXopen
iStat = NXputattr(pFile,"file_name",filename,
strlen(filename)+1,NX_CHAR);
if(iStat == NX_ERROR)
{
return NX_ERROR;
}
*/
/* write creation time, now done by NXopen
SNXFormatTime(pBueffel,512);
iStat = NXputattr(pFile,"file_time",pBueffel,
strlen(pBueffel)+1,NX_CHAR);
if(iStat == NX_ERROR)
{
return NX_ERROR;
}
*/
/* instrument name */
iStat = NXputattr(pFile, "instrument", instrument,
strlen(instrument) + 1, NX_CHAR);
if (iStat == NX_ERROR) {
return iStat;
}
/* owner */
iStat = NXputattr(pFile, "owner", owner, strlen(owner) + 1, NX_CHAR);
if (iStat == NX_ERROR) {
return iStat;
}
/* Adress */
iStat = NXputattr(pFile, "owner_adress", adress,
strlen(adress) + 1, NX_CHAR);
if (iStat == NX_ERROR) {
return iStat;
}
/* phone */
iStat = NXputattr(pFile, "owner_telephone_number", phone,
strlen(phone) + 1, NX_CHAR);
if (iStat == NX_ERROR) {
return iStat;
}
/* fax */
iStat = NXputattr(pFile, "owner_fax_number", fax,
strlen(fax) + 1, NX_CHAR);
if (iStat == NX_ERROR) {
return iStat;
}
/* email */
iStat = NXputattr(pFile, "owner_email", email,
strlen(email) + 1, NX_CHAR);
if (iStat == NX_ERROR) {
return iStat;
}
return NX_OK;
}
/*-----------------------------------------------------------------------*/
NXstatus NXUentergroup(NXhandle hFil, char *name, char *class)
{
int iRet;
/* ACTION, first install dummy error handler */
NXMDisableErrorReporting();
/* try opening vGroup */
iRet = NXopengroup(hFil, name, class);
NXMEnableErrorReporting();
if (iRet == NX_OK) {
return NX_OK;
} else {
/* we need to create it */
iRet = NXmakegroup(hFil, name, class);
if (iRet != NX_OK) {
/* a comment on this one has already been written! */
return iRet;
}
iRet = NXopengroup(hFil, name, class);
if (iRet != NX_OK) {
/* a comment on this one has already been written! */
return iRet;
}
}
return NX_OK;
}
/*-----------------------------------------------------------------------*/
NXstatus NXUenterdata(NXhandle hFil, char *label, int datatype,
int rank, int dim[], char *pUnits)
{
int iRet;
/* ACTION, first install dummy error handler */
NXMDisableErrorReporting();
/* try opening SDS */
iRet = NXopendata(hFil, label);
NXMEnableErrorReporting();
if (iRet == NX_OK) {
return NX_OK;
} else {
/* we need to create it */
iRet = NXmakedata(hFil, label, datatype, rank, dim);
if (iRet != NX_OK) {
/* a comment on this one has already been written! */
return iRet;
}
iRet = NXopendata(hFil, label);
if (iRet != NX_OK) {
/* a comment on this one has already been written! */
return iRet;
}
iRet = NXputattr(hFil, "Units", pUnits, strlen(pUnits) + 1, NX_INT8);
if (iRet != NX_OK) {
/* a comment on this one has already been written! */
return iRet;
}
}
return NX_OK;
}
/*-----------------------------------------------------------------------*/
NXstatus NXUallocSDS(NXhandle hFil, void **pData)
{
int iDIM[NX_MAXRANK];
int iRank, iType;
int iRet, i;
long lLength;
/* get info */
iRet = NXgetinfo(hFil, &iRank, iDIM, &iType);
if (iRet != NX_OK) {
return iRet;
}
/* calculate Size */
lLength = iDIM[0];
for (i = 1; i < iRank; i++) {
lLength *= iDIM[i];
}
switch (iType) {
case NX_FLOAT32:
lLength *= sizeof(float);
break;
case NX_FLOAT64:
lLength *= sizeof(double);
break;
case NX_INT8:
case NX_CHAR:
lLength *= sizeof(char);
break;
case NX_UINT8:
lLength *= sizeof(unsigned char);
break;
case NX_INT16:
lLength *= sizeof(short);
break;
case NX_UINT16:
lLength *= sizeof(unsigned short);
break;
case NX_INT32:
lLength *= sizeof(int);
break;
case NX_UINT32:
lLength *= sizeof(int);
break;
default:
NXReportError("ERROR: Internal: number type not recoginized");
return NX_ERROR;
}
/* time to malloc */
*pData = NULL;
*pData = malloc(lLength);
if (*pData == NULL) {
NXReportError("ERROR: memory exhausted in NXUallocSDS");
return NX_ERROR;
}
memset(*pData, 0, lLength);
return NX_OK;
}
/*----------------------------------------------------------------------*/
NXstatus NXUfreeSDS(void **pData)
{
free(*pData);
*pData = NULL;
return NX_OK;
}