NeXus  4.4.3
 All Data Structures Files Functions Variables Typedefs Macros Pages
napi4.c
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------
2  NeXus - Neutron & X-ray Common Data Format
3 
4  Application Program Interface (HDF4) Routines
5 
6  Copyright (C) 1997-2006 Mark Koennecke, Przemek Klosowski
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Lesser General Public License for more details.
17 
18  You should have received a copy of the GNU Lesser General Public
19  License along with this library; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 
22  For further information, see <http://www.nexusformat.org>
23 
24  $Id$
25 
26 ----------------------------------------------------------------------------*/
27 
28 #include <nxconfig.h>
29 
30 #ifdef WITH_HDF4
31 
32 #include <stdlib.h>
33 #include <assert.h>
34 #include <string.h>
35 #include <time.h>
36 
37 #include "napi.h"
38 #include "napi_internal.h"
39 #include "napi4.h"
40 
41 
42 extern void *NXpData;
43 
44  typedef struct __NexusFile {
45  struct iStack {
46  int32 *iRefDir;
47  int32 *iTagDir;
48  int32 iVref;
49  int32 __iStack_pad;
50  int iNDir;
51  int iCurDir;
52  } iStack[NXMAXSTACK];
53  struct iStack iAtt;
54  int32 iVID;
55  int32 iSID;
56  int32 iCurrentVG;
57  int32 iCurrentSDS;
58  int iNXID;
59  int iStackPtr;
60  char iAccess[2];
61  } NexusFile, *pNexusFile;
62  /*-------------------------------------------------------------------*/
63 
64  static pNexusFile NXIassert(NXhandle fid)
65  {
66  pNexusFile pRes;
67 
68  assert(fid != NULL);
69  pRes = (pNexusFile)fid;
70  assert(pRes->iNXID == NXSIGNATURE);
71  return pRes;
72  }
73  /*----------------------------------------------------------------------*/
74 static int findNapiClass(pNexusFile pFile, int groupRef, NXname nxclass)
75 {
76  NXname classText, linkClass;
77  int32 tags[2], attID, linkID, groupID;
78 
79  groupID = Vattach(pFile->iVID,groupRef,"r");
80  Vgetclass(groupID, classText);
81  if(strcmp(classText,"NAPIlink") != 0)
82  {
83  /* normal group */
84  strcpy(nxclass,classText);
85  Vdetach(groupID);
86  return groupRef;
87  }
88  else
89  {
90  /* code for linked renamed groups */
91  attID = Vfindattr(groupID,"NAPIlink");
92  if(attID >= 0)
93  {
94  Vgetattr(groupID,attID, tags);
95  linkID = Vattach(pFile->iVID,tags[1],"r");
96  Vgetclass(linkID, linkClass);
97  Vdetach(groupID);
98  Vdetach(linkID);
99  strcpy(nxclass,linkClass);
100  return tags[1];
101  }
102  else
103  {
104  /* this allows for finding the NAPIlink group in NXmakenamedlink */
105  strcpy(nxclass,classText);
106  Vdetach(groupID);
107  return groupRef;
108  }
109  }
110 }
111  /* --------------------------------------------------------------------- */
112 
113  static int32 NXIFindVgroup (pNexusFile pFile, CONSTCHAR *name, CONSTCHAR *nxclass)
114  {
115  int32 iNew, iRef, iTag;
116  int iN, i;
117  int32 *pArray = NULL;
118  NXname pText;
119 
120  assert (pFile != NULL);
121 
122  if (pFile->iCurrentVG == 0) { /* root level */
123  /* get the number and ID's of all lone Vgroups in the file */
124  iN = Vlone (pFile->iVID, NULL, 0);
125  if(iN == 0) {
126  return NX_EOD;
127  }
128  pArray = (int32 *) malloc (iN * sizeof (int32));
129  if (!pArray) {
130  NXReportError( "ERROR: out of memory in NXIFindVgroup");
131  return NX_EOD;
132  }
133  Vlone (pFile->iVID, pArray, iN);
134 
135  /* loop and check */
136  for (i = 0; i < iN; i++) {
137  iNew = Vattach (pFile->iVID, pArray[i], "r");
138  Vgetname (iNew, pText);
139  Vdetach(iNew);
140  if (strcmp (pText, name) == 0) {
141  pArray[i] = findNapiClass(pFile,pArray[i],pText);
142  if (strcmp (pText, nxclass) == 0) {
143  /* found ! */
144  iNew = pArray[i];
145  free (pArray);
146  return iNew;
147  }
148  }
149  }
150  /* nothing found */
151  free (pArray);
152  return NX_EOD;
153  } else { /* case in Vgroup */
154  iN = Vntagrefs (pFile->iCurrentVG);
155  for (i = 0; i < iN; i++) {
156  Vgettagref (pFile->iCurrentVG, i, &iTag, &iRef);
157  if (iTag == DFTAG_VG) {
158  iNew = Vattach (pFile->iVID, iRef, "r");
159  Vgetname (iNew, pText);
160  Vdetach(iNew);
161  if (strcmp (pText, name) == 0) {
162  iRef = findNapiClass(pFile,iRef, pText);
163  if (strcmp (pText, nxclass) == 0) {
164  return iRef;
165  }
166  }
167  }
168  } /* end for */
169  } /* end else */
170  /* not found */
171  return NX_EOD;
172  }
173 
174  /*----------------------------------------------------------------------*/
175 
176  static int32 NXIFindSDS (NXhandle fid, CONSTCHAR *name)
177  {
178  pNexusFile self;
179  int32 iNew, iRet, iTag, iRef;
180  int32 i, iN, iA, iD1, iD2;
181  NXname pNam;
182  int32 iDim[H4_MAX_VAR_DIMS];
183 
184  self = NXIassert (fid);
185 
186  /* root level search */
187  if (self->iCurrentVG == 0) {
188  i = SDfileinfo (self->iSID, &iN, &iA);
189  if (i < 0) {
190  NXReportError( "ERROR: failure to read file information");
191  return NX_EOD;
192  }
193  for (i = 0; i < iN; i++) {
194  iNew = SDselect (self->iSID, i);
195  SDgetinfo (iNew, pNam, &iA, iDim, &iD1, &iD2);
196  if (strcmp (pNam, name) == 0) {
197  iRet = SDidtoref (iNew);
198  SDendaccess (iNew);
199  return iRet;
200  } else {
201  SDendaccess (iNew);
202  }
203  }
204  /* not found */
205  return NX_EOD;
206  }
207  /* end root level */
208  else { /* search in a Vgroup */
209  iN = Vntagrefs (self->iCurrentVG);
210  for (i = 0; i < iN; i++) {
211  Vgettagref (self->iCurrentVG, i, &iTag, &iRef);
212  /* we are now writing using DFTAG_NDG, but need others for backward compatability */
213  if ((iTag == DFTAG_SDG) || (iTag == DFTAG_NDG) || (iTag == DFTAG_SDS)) {
214  iNew = SDreftoindex (self->iSID, iRef);
215  iNew = SDselect (self->iSID, iNew);
216  SDgetinfo (iNew, pNam, &iA, iDim, &iD1, &iD2);
217  if (strcmp (pNam, name) == 0) {
218  SDendaccess (iNew);
219  return iRef;
220  }
221  SDendaccess (iNew);
222  }
223  } /* end for */
224  } /* end Vgroup */
225  /* we get here, only if nothing found */
226  return NX_EOD;
227  }
228 
229  /*----------------------------------------------------------------------*/
230 
231  static int NXIInitDir (pNexusFile self)
232  {
233  int i;
234  int32 iTag, iRef;
235  int iStackPtr;
236 
237  /*
238  * Note: the +1 to various malloc() operations is to avoid a
239  * malloc(0), which is an error on some operating systems
240  */
241  iStackPtr = self->iStackPtr;
242  if (self->iCurrentVG == 0 &&
243  self->iStack[iStackPtr].iRefDir == NULL) { /* root level */
244  /* get the number and ID's of all lone Vgroups in the file */
245  self->iStack[iStackPtr].iNDir = Vlone (self->iVID, NULL, 0);
246  self->iStack[iStackPtr].iRefDir =
247  (int32 *) malloc (self->iStack[iStackPtr].iNDir * sizeof (int32) + 1);
248  if (!self->iStack[iStackPtr].iRefDir) {
249  NXReportError( "ERROR: out of memory in NXIInitDir");
250  return NX_EOD;
251  }
252  Vlone (self->iVID,
253  self->iStack[self->iStackPtr].iRefDir,
254  self->iStack[self->iStackPtr].iNDir);
255  } else {
256  /* Vgroup level */
257  self->iStack[iStackPtr].iNDir = Vntagrefs (self->iCurrentVG);
258  self->iStack[iStackPtr].iRefDir =
259  (int32 *) malloc (self->iStack[iStackPtr].iNDir * sizeof (int32) + 1);
260  self->iStack[iStackPtr].iTagDir =
261  (int32 *) malloc (self->iStack[iStackPtr].iNDir * sizeof (int32) + 1);
262  if ((!self->iStack[iStackPtr].iRefDir) ||
263  (!self->iStack[iStackPtr].iTagDir)) {
264  NXReportError( "ERROR: out of memory in NXIInitDir");
265  return NX_EOD;
266  }
267  for (i = 0; i < self->iStack[self->iStackPtr].iNDir; i++) {
268  Vgettagref (self->iCurrentVG, i, &iTag, &iRef);
269  self->iStack[iStackPtr].iRefDir[i] = iRef;
270  self->iStack[iStackPtr].iTagDir[i] = iTag;
271  }
272  }
273  self->iStack[iStackPtr].iCurDir = 0;
274  return 1;
275  }
276 
277  /*----------------------------------------------------------------------*/
278 
279  static void NXIKillDir (pNexusFile self)
280  {
281  if (self->iStack[self->iStackPtr].iRefDir) {
282  free (self->iStack[self->iStackPtr].iRefDir);
283  self->iStack[self->iStackPtr].iRefDir = NULL;
284  }
285  if (self->iStack[self->iStackPtr].iTagDir) {
286  free (self->iStack[self->iStackPtr].iTagDir);
287  self->iStack[self->iStackPtr].iTagDir = NULL;
288  }
289  self->iStack[self->iStackPtr].iCurDir = 0;
290  self->iStack[self->iStackPtr].iNDir = 0;
291  }
292 
293 
294  /*-------------------------------------------------------------------------*/
295 
296  static int NXIInitAttDir (pNexusFile pFile)
297  {
298  int iRet;
299  int32 iData, iAtt, iRank, iType;
300  int32 iDim[H4_MAX_VAR_DIMS];
301  NXname pNam;
302 
303  pFile->iAtt.iCurDir = 0;
304  if (pFile->iCurrentSDS != 0) { /* SDS level */
305  iRet = SDgetinfo (pFile->iCurrentSDS, pNam, &iRank, iDim, &iType,
306  &iAtt);
307  } else {
308  if(pFile->iCurrentVG == 0){
309  /* global level */
310  iRet = SDfileinfo (pFile->iSID, &iData, &iAtt);
311  } else {
312  /* group attribute */
313  iRet = Vnattrs(pFile->iCurrentVG);
314  iAtt = iRet;
315  }
316  }
317  if (iRet < 0) {
318  NXReportError( "ERROR: HDF cannot read attribute numbers");
319  pFile->iAtt.iNDir = 0;
320  return NX_ERROR;
321  }
322  pFile->iAtt.iNDir = iAtt;
323  return NX_OK;
324  }
325 
326  /* --------------------------------------------------------------------- */
327 
328  static void NXIKillAttDir (pNexusFile self)
329  {
330  if (self->iAtt.iRefDir) {
331  free (self->iAtt.iRefDir);
332  self->iAtt.iRefDir = NULL;
333  }
334  if (self->iAtt.iTagDir) {
335  free (self->iAtt.iTagDir);
336  self->iAtt.iTagDir = NULL;
337  }
338  self->iAtt.iCurDir = 0;
339  self->iAtt.iNDir = 0;
340  }
341 /*------------------------------------------------------------------*/
342  static void NXIbuildPath(pNexusFile pFile, char *buffer, int bufLen)
343  {
344  int i;
345  int32 groupID, iA, iD1, iD2, iDim[H4_MAX_VAR_DIMS];
346  NXname pText;
347 
348  buffer[0] = '\0';
349  for(i = 1; i <= pFile->iStackPtr; i++){
350  strncat(buffer,"/",bufLen-strlen(buffer));
351  groupID = Vattach(pFile->iVID,pFile->iStack[i].iVref, "r");
352  if (groupID != -1)
353  {
354  if (Vgetname(groupID, pText) != -1) {
355  strncat(buffer,pText,bufLen-strlen(buffer));
356  } else {
357  NXReportError( "ERROR: NXIbuildPath cannot get vgroup name");
358  }
359  Vdetach(groupID);
360  }
361  else
362  {
363  NXReportError( "ERROR: NXIbuildPath cannot attach to vgroup");
364  }
365  }
366  if(pFile->iCurrentSDS != 0){
367  if (SDgetinfo(pFile->iCurrentSDS,pText,&iA,iDim,&iD1,&iD2) != -1) {
368  strncat(buffer,"/",bufLen-strlen(buffer));
369  strncat(buffer,pText,bufLen-strlen(buffer));
370  }
371  else
372  {
373  NXReportError( "ERROR: NXIbuildPath cannot read SDS");
374  }
375  }
376  }
377  /* ----------------------------------------------------------------------
378 
379  Definition of NeXus API
380 
381  ---------------------------------------------------------------------*/
382 
383 
384  NXstatus NX4open(CONSTCHAR *filename, NXaccess am,
385  NXhandle* pHandle)
386  {
387  pNexusFile pNew = NULL;
388  char pBuffer[512];
389  char *time_puffer = NULL;
390  char HDF_VERSION[64];
391  uint32 lmajor, lminor, lrelease;
392  int32 am1=0;
393 
394  *pHandle = NULL;
395 
396  /* mask off any options for now */
397  am = (NXaccess)(am & NXACCMASK_REMOVEFLAGS);
398  /* map Nexus NXaccess types to HDF4 types */
399  if (am == NXACC_CREATE) {
400  am1 = DFACC_CREATE;
401  } else if (am == NXACC_CREATE4) {
402  am1 = DFACC_CREATE;
403  } else if (am == NXACC_READ) {
404  am1 = DFACC_READ;
405  } else if (am == NXACC_RDWR) {
406  am1 = DFACC_RDWR;
407  }
408  /* get memory */
409  pNew = (pNexusFile) malloc (sizeof (NexusFile));
410  if (!pNew) {
411  NXReportError( "ERROR: no memory to create File datastructure");
412  return NX_ERROR;
413  }
414  memset (pNew, 0, sizeof (NexusFile));
415 
416 #if WRITE_OLD_IDENT /* not used at moment */
417 /*
418  * write something that can be used by OLE
419  */
420 
421  if (am == NXACC_CREATE || am == NXACC_CREATE4) {
422  if ( (file_id = Hopen(filename, am1, 0)) == -1 ) {
423  sprintf (pBuffer, "ERROR: cannot open file_a: %s", filename);
424  NXReportError( pBuffer);
425  free (pNew);
426  return NX_ERROR;
427  }
428  an_id = ANstart(file_id);
429  ann_id = ANcreatef(an_id, AN_FILE_LABEL); /* AN_FILE_DESC */
430  ANwriteann(ann_id, "NeXus", 5);
431  ANendaccess(ann_id);
432  ANend(an_id);
433  if (Hclose(file_id) == -1) {
434  sprintf (pBuffer, "ERROR: cannot close file: %s", filename);
435  NXReportError( pBuffer);
436  free (pNew);
437  return NX_ERROR;
438  }
439  am = NXACC_RDWR;
440  }
441 #endif /* WRITE_OLD_IDENT */
442 
443  /* start SDS interface */
444  pNew->iSID = SDstart (filename, am1);
445  if (pNew->iSID <= 0) {
446  sprintf (pBuffer, "ERROR: cannot open file_b: %s", filename);
447  NXReportError( pBuffer);
448  free (pNew);
449  return NX_ERROR;
450  }
451 /*
452  * need to create global attributes file_name file_time NeXus_version
453  * at some point for new files
454  */
455  if (am == NXACC_CREATE || am == NXACC_CREATE4) {
456  /* set the NeXus_version attribute*/
457  if (SDsetattr(pNew->iSID, "NeXus_version", DFNT_CHAR8,
458  strlen(NEXUS_VERSION), NEXUS_VERSION) < 0)
459  {
460  NXReportError( "ERROR: HDF failed to store NeXus_version attribute ");
461  return NX_ERROR;
462  }
463 
464  /* set the HDF4 version attribute */
465  Hgetlibversion(&lmajor, &lminor, &lrelease, HDF_VERSION);
466  if (SDsetattr(pNew->iSID, "HDF_version", DFNT_CHAR8, strlen(HDF_VERSION),HDF_VERSION) < 0)
467  {
468  NXReportError( "ERROR: HDF failed to store HDF_version attribute ");
469  return NX_ERROR;
470  }
471 
472  /* set the filename attribute */
473  if (SDsetattr(pNew->iSID, "file_name", DFNT_CHAR8, strlen(filename), (char*)filename) < 0)
474  {
475  NXReportError( "ERROR: HDF failed to store file_name attribute ");
476  return NX_ERROR;
477  }
478 
479  /* set the file_time attribute */
480  time_puffer = NXIformatNeXusTime();
481  if(time_puffer != NULL){
482  if (SDsetattr(pNew->iSID, "file_time", DFNT_CHAR8,strlen(time_puffer),time_puffer) < 0)
483  {
484  NXReportError("ERROR: HDF failed to store file_time attribute ");
485  free(time_puffer);
486  return NX_ERROR;
487  }
488  free(time_puffer);
489  }
490 
491  if (SDsetattr(pNew->iSID,"NX_class",DFNT_CHAR8,7,"NXroot")<0)
492  {
493  NXReportError("ERROR: HDF failed to store NX_class attribute ");
494  return NX_ERROR;
495  }
496  }
497 
498  /*
499  * Otherwise we try to create the file two times which makes HDF
500  * Throw up on us.
501  */
502  if (am == NXACC_CREATE || am == NXACC_CREATE4) {
503  am = NXACC_RDWR;
504  am1 = DFACC_RDWR;
505  }
506 
507  /* Set Vgroup access mode */
508  if (am == NXACC_READ) {
509  strcpy(pNew->iAccess,"r");
510  } else {
511  strcpy(pNew->iAccess,"w");
512  }
513 
514  /* start Vgroup API */
515 
516  pNew->iVID = Hopen(filename, am1, 100);
517  if (pNew->iVID <= 0) {
518  sprintf (pBuffer, "ERROR: cannot open file_c: %s", filename);
519  NXReportError( pBuffer);
520  free (pNew);
521  return NX_ERROR;
522  }
523  Vstart (pNew->iVID);
524  pNew->iNXID = NXSIGNATURE;
525  pNew->iStack[0].iVref = 0; /* root! */
526 
527  *pHandle = (NXhandle)pNew;
528  return NX_OK;
529  }
530 
531 /*-----------------------------------------------------------------------*/
532 
533  NXstatus NX4close (NXhandle* fid)
534  {
535  pNexusFile pFile = NULL;
536  int iRet;
537 
538  pFile = NXIassert(*fid);
539  iRet = 0;
540  /* close links into vGroups or SDS */
541  if (pFile->iCurrentVG != 0) {
542  Vdetach (pFile->iCurrentVG);
543  }
544  if (pFile->iCurrentSDS != 0) {
545  iRet = SDendaccess (pFile->iCurrentSDS);
546  }
547  if (iRet < 0) {
548  NXReportError( "ERROR: ending access to SDS");
549  }
550  /* close the SDS and Vgroup API's */
551  Vend (pFile->iVID);
552  iRet = SDend (pFile->iSID);
553  if (iRet < 0) {
554  NXReportError( "ERROR: HDF cannot close SDS interface");
555  }
556  iRet = Hclose (pFile->iVID);
557  if (iRet < 0) {
558  NXReportError( "ERROR: HDF cannot close HDF file");
559  }
560  /* release memory */
561  NXIKillDir (pFile);
562  free (pFile);
563  *fid = NULL;
564  return NX_OK;
565  }
566 
567 
568 /*-----------------------------------------------------------------------*/
569 
570 
571  NXstatus NX4makegroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass)
572  {
573  pNexusFile pFile;
574  int32 iNew, iRet;
575  char pBuffer[256];
576 
577  pFile = NXIassert (fid);
578  /*
579  * Make sure that a group with the same name and nxclass does not
580  * already exist.
581  */
582  if ((iRet = NXIFindVgroup (pFile, (char*)name, nxclass)) >= 0) {
583  sprintf (pBuffer, "ERROR: Vgroup %s, class %s already exists",
584  name, nxclass);
585  NXReportError( pBuffer);
586  return NX_ERROR;
587  }
588 
589  /* create and configure the group */
590  iNew = Vattach (pFile->iVID, -1, "w");
591  if (iNew < 0) {
592  sprintf (pBuffer, "ERROR: HDF could not create Vgroup %s, class %s",
593  name, nxclass);
594  NXReportError( pBuffer);
595  return NX_ERROR;
596  }
597  Vsetname (iNew, name);
598  Vsetclass (iNew, nxclass);
599 
600  /* Insert it into the hierarchy, when appropriate */
601  iRet = 0;
602  if (pFile->iCurrentVG != 0) {
603  iRet = Vinsert (pFile->iCurrentVG, iNew);
604  }
605  Vdetach (iNew);
606  if (iRet < 0) {
607  NXReportError( "ERROR: HDF failed to insert Vgroup");
608  return NX_ERROR;
609  }
610  return NX_OK;
611  }
612 
613 
614  /*------------------------------------------------------------------------*/
615  NXstatus NX4opengroup (NXhandle fid, CONSTCHAR *name, CONSTCHAR *nxclass)
616  {
617  pNexusFile pFile;
618  int32 iRef;
619  char pBuffer[256];
620 
621  pFile = NXIassert (fid);
622 
623  iRef = NXIFindVgroup (pFile, (char*)name, nxclass);
624  if (iRef < 0) {
625  sprintf (pBuffer, "ERROR: Vgroup \"%s\", class \"%s\" NOT found", name, nxclass);
626  NXReportError( pBuffer);
627  return NX_ERROR;
628  }
629  /* are we at root level ? */
630  if (pFile->iCurrentVG == 0) {
631  pFile->iCurrentVG = Vattach (pFile->iVID, iRef,pFile->iAccess);
632  pFile->iStackPtr++;
633  pFile->iStack[pFile->iStackPtr].iVref = iRef;
634  } else {
635  Vdetach (pFile->iCurrentVG);
636  pFile->iStackPtr++;
637  pFile->iStack[pFile->iStackPtr].iVref = iRef;
638  pFile->iCurrentVG = Vattach (pFile->iVID,
639  pFile->iStack[pFile->iStackPtr].iVref,
640  pFile->iAccess);
641  }
642  NXIKillDir (pFile);
643  return NX_OK;
644  }
645  /* ------------------------------------------------------------------- */
646 
647 
648  NXstatus NX4closegroup (NXhandle fid)
649  {
650  pNexusFile pFile;
651 
652  pFile = NXIassert (fid);
653 
654  /* first catch the trivial case: we are at root and cannot get
655  deeper into a negative directory hierarchy (anti-directory)
656  */
657  if (pFile->iCurrentVG == 0) {
658  NXIKillDir (pFile);
659  return NX_OK;
660  } else { /* Sighhh. Some work to do */
661  /* close the current VG and decrement stack */
662  Vdetach (pFile->iCurrentVG);
663  NXIKillDir (pFile);
664  pFile->iStackPtr--;
665  if (pFile->iStackPtr <= 0) { /* we hit root */
666  pFile->iStackPtr = 0;
667  pFile->iCurrentVG = 0;
668  } else {
669  /* attach to the lower Vgroup */
670  pFile->iCurrentVG = Vattach (pFile->iVID,
671  pFile->iStack[pFile->iStackPtr].iVref,
672  pFile->iAccess);
673  }
674  }
675  return NX_OK;
676  }
677 
678 
679  /* --------------------------------------------------------------------- */
680 
681  NXstatus NX4makedata64 (NXhandle fid, CONSTCHAR *name, int datatype, int rank,
682  int64_t dimensions[])
683  {
684  pNexusFile pFile;
685  int32 iNew;
686  char pBuffer[256];
687  int i, iRet, type;
688  int32 myDim[H4_MAX_VAR_DIMS];
689 
690  pFile = NXIassert (fid);
691 
692  if (dimensions[0] == NX_UNLIMITED)
693  {
694  dimensions[0] = SD_UNLIMITED;
695  }
696 
697  if ((iNew = NXIFindSDS (fid, name))>=0) {
698  sprintf (pBuffer, "ERROR: SDS %s already exists at this level", name);
699  NXReportError( pBuffer);
700  return NX_ERROR;
701  }
702 
703  if (datatype == NX_CHAR)
704  {
705  type=DFNT_CHAR8;
706  }
707  else if (datatype == NX_INT8)
708  {
709  type=DFNT_INT8;
710  }
711  else if (datatype == NX_UINT8)
712  {
713  type=DFNT_UINT8;
714  }
715  else if (datatype == NX_INT16)
716  {
717  type=DFNT_INT16;
718  }
719  else if (datatype == NX_UINT16)
720  {
721  type=DFNT_UINT16;
722  }
723  else if (datatype == NX_INT32)
724  {
725  type=DFNT_INT32;
726  }
727  else if (datatype == NX_UINT32)
728  {
729  type=DFNT_UINT32;
730  }
731  else if (datatype == NX_FLOAT32)
732  {
733  type=DFNT_FLOAT32;
734  }
735  else if (datatype == NX_FLOAT64)
736  {
737  type=DFNT_FLOAT64;
738  }
739  else
740  {
741  NXReportError( "ERROR: invalid type in NX4makedata");
742  return NX_ERROR;
743  }
744 
745  if (rank <= 0) {
746  sprintf (pBuffer, "ERROR: invalid rank specified for SDS %s",
747  name);
748  NXReportError( pBuffer);
749  return NX_ERROR;
750  }
751 
752  /*
753  Check dimensions for consistency. The first dimension may be 0
754  thus denoting an unlimited dimension.
755  */
756  for (i = 1; i < rank; i++) {
757  if (dimensions[i] <= 0) {
758  sprintf (pBuffer,
759  "ERROR: invalid dimension %d, value %lld given for SDS %s",
760  i, (long long)dimensions[i], name);
761  NXReportError( pBuffer);
762  return NX_ERROR;
763  }
764  }
765 
766  /* cast the dimensions array properly for non 32-bit ints */
767  for(i = 0; i < rank; i++)
768  {
769  myDim[i] = (int32)dimensions[i];
770  }
771 
772 
773  /* behave nicely, if there is still an SDS open */
774  if (pFile->iCurrentSDS != 0) {
775  SDendaccess (pFile->iCurrentSDS);
776  pFile->iCurrentSDS = 0;
777  }
778 
779  /* Do not allow creation of SDS's at the root level */
780  if (pFile->iCurrentVG == 0) {
781  sprintf(pBuffer, "ERROR: SDS creation at root level is not permitted");
782  NXReportError( pBuffer);
783  return NX_ERROR;
784  }
785 
786  /* dataset creation */
787  iNew = SDcreate (pFile->iSID, (char*)name, (int32)type,
788  (int32)rank, myDim);
789  if (iNew < 0) {
790  sprintf (pBuffer, "ERROR: cannot create SDS %s, check arguments",
791  name);
792  NXReportError( pBuffer);
793  return NX_ERROR;
794  }
795  /* link into Vgroup, if in one */
796  if (pFile->iCurrentVG != 0) {
797  iRet = Vaddtagref (pFile->iCurrentVG, DFTAG_NDG, SDidtoref (iNew));
798  }
799  iRet = SDendaccess (iNew);
800  if (iRet < 0) {
801  NXReportError( "ERROR: HDF cannot end access to SDS");
802  return NX_ERROR;
803  }
804  return NX_OK;
805  }
806 
807 
808  /* --------------------------------------------------------------------- */
809 
810 
811  NXstatus NX4compmakedata64 (NXhandle fid, CONSTCHAR *name, int datatype, int rank,
812  int64_t dimensions[],int compress_type, int64_t chunk_size[])
813  {
814  pNexusFile pFile;
815  int32 iNew, iRet, type;
816  char pBuffer[256];
817  int i, compress_level;
818  int32 myDim[H4_MAX_VAR_DIMS];
819  comp_info compstruct;
820 
821  pFile = NXIassert (fid);
822 
823  if (dimensions[0] == NX_UNLIMITED)
824  {
825  dimensions[0] = SD_UNLIMITED;
826  }
827 
828  if ((iNew = NXIFindSDS (fid, name))>=0) {
829  sprintf (pBuffer, "ERROR: SDS %s already exists at this level", name);
830  NXReportError( pBuffer);
831  return NX_ERROR;
832  }
833 
834  if (datatype == NX_CHAR)
835  {
836  type=DFNT_CHAR8;
837  }
838  else if (datatype == NX_INT8)
839  {
840  type=DFNT_INT8;
841  }
842  else if (datatype == NX_UINT8)
843  {
844  type=DFNT_UINT8;
845  }
846  else if (datatype == NX_INT16)
847  {
848  type=DFNT_INT16;
849  }
850  else if (datatype == NX_UINT16)
851  {
852  type=DFNT_UINT16;
853  }
854  else if (datatype == NX_INT32)
855  {
856  type=DFNT_INT32;
857  }
858  else if (datatype == NX_UINT32)
859  {
860  type=DFNT_UINT32;
861  }
862  else if (datatype == NX_FLOAT32)
863  {
864  type=DFNT_FLOAT32;
865  }
866  else if (datatype == NX_FLOAT64)
867  {
868  type=DFNT_FLOAT64;
869  }
870  else
871  {
872  NXReportError( "ERROR: invalid datatype in NX4compmakedata");
873  return NX_ERROR;
874  }
875 
876  if (rank <= 0) {
877  sprintf (pBuffer, "ERROR: invalid rank specified for SDS %s",
878  name);
879  NXReportError( pBuffer);
880  return NX_ERROR;
881  }
882 
883  /*
884  Check dimensions for consistency. The first dimension may be 0
885  thus denoting an unlimited dimension.
886  */
887  for (i = 1; i < rank; i++) {
888  if (dimensions[i] <= 0) {
889  sprintf (pBuffer,
890  "ERROR: invalid dimension %d, value %lld given for SDS %s",
891  i, (long long)dimensions[i], name);
892  NXReportError( pBuffer);
893  return NX_ERROR;
894  }
895  }
896 
897  /* cast the dimensions array properly for non 32-bit ints */
898  for(i = 0; i < rank; i++)
899  {
900  myDim[i] = (int32)dimensions[i];
901  }
902 
903 
904  /* behave nicely, if there is still an SDS open */
905  if (pFile->iCurrentSDS != 0) {
906  SDendaccess (pFile->iCurrentSDS);
907  pFile->iCurrentSDS = 0;
908  }
909 
910  /* Do not allow creation of SDS's at the root level */
911  if (pFile->iCurrentVG == 0) {
912  sprintf(pBuffer, "ERROR: SDS creation at root level is not permitted");
913  NXReportError( pBuffer);
914  return NX_ERROR;
915  }
916 
917  /* dataset creation */
918  iNew = SDcreate (pFile->iSID, (char*)name, (int32)type,
919  (int32)rank, myDim);
920  if (iNew < 0) {
921  sprintf (pBuffer, "ERROR: cannot create SDS %s, check arguments",
922  name);
923  NXReportError( pBuffer);
924  return NX_ERROR;
925  }
926 
927  /* compress SD data set */
928  compress_level = 6;
929  if( (compress_type / 100) == NX_COMP_LZW )
930  {
931  compress_level = compress_type % 100;
932  compress_type = NX_COMP_LZW;
933  }
934 
935  if(compress_type == NX_COMP_LZW)
936  {
937  compstruct.deflate.level = compress_level;
938  iRet = SDsetcompress(iNew, COMP_CODE_DEFLATE, &compstruct);
939  if (iRet < 0)
940  {
941  NXReportError( "Deflate-Compression failure!");
942  return NX_ERROR;
943  }
944  }
945  else if (compress_type == NX_COMP_RLE)
946  {
947  iRet = SDsetcompress(iNew, COMP_CODE_RLE, &compstruct);
948  if (iRet < 0)
949  {
950  NXReportError( "RLE-Compression failure!");
951  return NX_ERROR;
952  }
953  }
954  else if (compress_type == NX_COMP_HUF)
955  {
956  compstruct.skphuff.skp_size = DFKNTsize(type);
957  iRet = SDsetcompress(iNew, COMP_CODE_SKPHUFF, &compstruct);
958  if (iRet < 0)
959  {
960  NXReportError( "HUF-Compression failure!");
961  return NX_ERROR;
962  }
963  }
964  else if (compress_type == NX_COMP_NONE)
965  {
966  /* */
967  }
968  else
969  {
970  NXReportError( "Unknown compression method!");
971  return NX_ERROR;
972  }
973  /* link into Vgroup, if in one */
974  if (pFile->iCurrentVG != 0) {
975  iRet = Vaddtagref (pFile->iCurrentVG, DFTAG_NDG, SDidtoref (iNew));
976  }
977  iRet = SDendaccess (iNew);
978  if (iRet < 0) {
979  NXReportError( "ERROR: HDF cannot end access to SDS");
980  return NX_ERROR;
981  }
982 
983  return NX_OK;
984  }
985 
986  /* --------------------------------------------------------------------- */
987 
988 
989  NXstatus NX4compress (NXhandle fid, int compress_type)
990  {
991  pNexusFile pFile;
992  int32 iRank, iAtt, iType, iRet;
993  int32 iSize[H4_MAX_VAR_DIMS];
994  comp_coder_t compress_typei = COMP_CODE_NONE;
995  NXname pBuffer;
996  char pError[512];
997  comp_info compstruct;
998  int compress_level = 6;
999 
1000  pFile = NXIassert (fid);
1001 
1002  /* check if there is an SDS open */
1003  if (pFile->iCurrentSDS == 0) {
1004  NXReportError( "ERROR: no SDS open");
1005  return NX_ERROR;
1006  }
1007 
1008  if (compress_type == NX_COMP_NONE)
1009  {
1010  compress_typei = COMP_CODE_NONE;
1011  }
1012  else if (compress_type == NX_COMP_LZW)
1013  {
1014  compress_typei = COMP_CODE_DEFLATE;
1015  }
1016  else if ( (compress_type / 100) == NX_COMP_LZW )
1017  {
1018  compress_typei = COMP_CODE_DEFLATE;
1019  compress_level = compress_type % 100;
1020  compress_type = NX_COMP_LZW;
1021  }
1022  else if (compress_type == NX_COMP_RLE)
1023  {
1024  compress_typei = COMP_CODE_RLE;
1025  }
1026  else if
1027  (compress_type == NX_COMP_HUF)
1028  {
1029  compress_typei = COMP_CODE_SKPHUFF;
1030  }
1031 
1032  /* first read dimension information */
1033  SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, iSize, &iType, &iAtt);
1034 
1035  /*
1036  according to compression type initialize compression
1037  information
1038  */
1039  if(compress_type == NX_COMP_LZW)
1040  {
1041  compstruct.deflate.level = compress_level;
1042  }
1043  else if(compress_type == NX_COMP_HUF)
1044  {
1045  compstruct.skphuff.skp_size = DFKNTsize(iType);
1046  }
1047 
1048  iRet = SDsetcompress(pFile->iCurrentSDS, compress_typei, &compstruct);
1049  if (iRet < 0) {
1050  sprintf (pError, "ERROR: failure to compress data to %s", pBuffer);
1051  NXReportError( pError);
1052  return NX_ERROR;
1053  }
1054  return NX_OK;
1055  }
1056 
1057  /* --------------------------------------------------------------------- */
1058 
1059 
1060  NXstatus NX4opendata (NXhandle fid, CONSTCHAR *name)
1061  {
1062  pNexusFile pFile;
1063  int32 iNew, attID, tags[2];
1064  char pBuffer[256];
1065  int iRet;
1066 
1067  pFile = NXIassert (fid);
1068 
1069  /* First find the reference number of the SDS */
1070  iNew = NXIFindSDS (fid, name);
1071  if (iNew < 0) {
1072  sprintf (pBuffer, "ERROR: SDS \"%s\" not found at this level", name);
1073  NXReportError( pBuffer);
1074  return NX_ERROR;
1075  }
1076  /* Be nice: properly close the old open SDS silently if there is
1077  * still an SDS open.
1078  */
1079  if (pFile->iCurrentSDS) {
1080  iRet = SDendaccess (pFile->iCurrentSDS);
1081  if (iRet < 0) {
1082  NXReportError( "ERROR: HDF cannot end access to SDS");
1083  }
1084  }
1085  /* clear pending attribute directories first */
1086  NXIKillAttDir (pFile);
1087 
1088  /* open the SDS, thereby watching for linked SDS under a different name */
1089  iNew = SDreftoindex (pFile->iSID, iNew);
1090  pFile->iCurrentSDS = SDselect (pFile->iSID, iNew);
1091  attID = SDfindattr(pFile->iCurrentSDS,"NAPIlink");
1092  if(attID >= 0)
1093  {
1094  SDreadattr(pFile->iCurrentSDS,attID, tags);
1095  SDendaccess(pFile->iCurrentSDS);
1096  iNew = SDreftoindex (pFile->iSID, tags[1]);
1097  pFile->iCurrentSDS = SDselect (pFile->iSID, iNew);
1098  }
1099 
1100  if (pFile->iCurrentSDS < 0) {
1101  NXReportError( "ERROR: HDF error opening SDS");
1102  pFile->iCurrentSDS = 0;
1103  return NX_ERROR;
1104  }
1105  return NX_OK;
1106  }
1107 
1108  /* ----------------------------------------------------------------- */
1109 
1110 
1111  NXstatus NX4closedata (NXhandle fid)
1112  {
1113  pNexusFile pFile;
1114  int iRet;
1115 
1116  pFile = NXIassert (fid);
1117 
1118  if (pFile->iCurrentSDS != 0) {
1119  iRet = SDendaccess (pFile->iCurrentSDS);
1120  pFile->iCurrentSDS = 0;
1121  if (iRet < 0) {
1122  NXReportError( "ERROR: HDF cannot end access to SDS");
1123  return NX_ERROR;
1124  }
1125  } else {
1126  NXReportError( "ERROR: no SDS open --> nothing to do");
1127  return NX_ERROR;
1128  }
1129  NXIKillAttDir (pFile); /* for attribute data */
1130  return NX_OK;
1131  }
1132 
1133 
1134  /* ------------------------------------------------------------------- */
1135 
1136  NXstatus NX4putdata (NXhandle fid, const void *data)
1137  {
1138  pNexusFile pFile;
1139  int32 iStart[H4_MAX_VAR_DIMS], iSize[H4_MAX_VAR_DIMS], iStride[H4_MAX_VAR_DIMS];
1140  NXname pBuffer;
1141  int32 iRank, iAtt, iType, iRet, i;
1142  char pError[512];
1143 
1144  pFile = NXIassert (fid);
1145 
1146  /* check if there is an SDS open */
1147  if (pFile->iCurrentSDS == 0) {
1148  NXReportError( "ERROR: no SDS open");
1149  return NX_ERROR;
1150  }
1151  /* first read dimension information */
1152  memset (iStart, 0, H4_MAX_VAR_DIMS * sizeof (int32));
1153  SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, iSize, &iType, &iAtt);
1154 
1155  /* initialise stride to 1 */
1156  for (i = 0; i < iRank; i++) {
1157  iStride[i] = 1;
1158  }
1159 
1160  /* actually write */
1161  iRet = SDwritedata (pFile->iCurrentSDS, iStart, iStride, iSize, (void*)data);
1162  if (iRet < 0) {
1163  /* HEprint(stdout,0); */
1164  sprintf (pError, "ERROR: failure to write data to %s", pBuffer);
1165  NXReportError( pError);
1166  return NX_ERROR;
1167  }
1168  return NX_OK;
1169  }
1170 
1171  /* ------------------------------------------------------------------- */
1172 
1173  NXstatus
1174  NX4putattr (NXhandle fid, CONSTCHAR *name, const void *data, int datalen, int iType)
1175  {
1176  pNexusFile pFile;
1177  int iRet, type;
1178 
1179  pFile = NXIassert (fid);
1180  if (iType == NX_CHAR)
1181  {
1182  type=DFNT_CHAR8;
1183  }
1184  else if (iType == NX_INT8)
1185  {
1186  type=DFNT_INT8;
1187  }
1188  else if (iType == NX_UINT8)
1189  {
1190  type=DFNT_UINT8;
1191  }
1192  else if (iType == NX_INT16)
1193  {
1194  type=DFNT_INT16;
1195  }
1196  else if (iType == NX_UINT16)
1197  {
1198  type=DFNT_UINT16;
1199  }
1200  else if (iType == NX_INT32)
1201  {
1202  type=DFNT_INT32;
1203  }
1204  else if (iType == NX_UINT32)
1205  {
1206  type=DFNT_UINT32;
1207  }
1208  else if (iType == NX_FLOAT32)
1209  {
1210  type=DFNT_FLOAT32;
1211  }
1212  else if (iType == NX_FLOAT64)
1213  {
1214  type=DFNT_FLOAT64;
1215  }
1216  else
1217  {
1218  NXReportError( "ERROR: Invalid data type for HDF attribute");
1219  return NX_ERROR;
1220  }
1221  if (pFile->iCurrentSDS != 0) {
1222  /* SDS attribute */
1223  iRet = SDsetattr (pFile->iCurrentSDS, (char*)name, (int32)type,
1224  (int32)datalen, data);
1225  } else {
1226  if(pFile->iCurrentVG == 0){
1227  /* global attribute */
1228  iRet = SDsetattr (pFile->iSID, (char*)name, (int32)type,
1229  (int32)datalen, data);
1230  } else {
1231  /* group attribute */
1232  iRet = Vsetattr(pFile->iCurrentVG, (char *)name, (int32) type,
1233  (int32)datalen,data);
1234  }
1235  }
1236  iType = type;
1237  if (iRet < 0) {
1238  NXReportError( "ERROR: HDF failed to store attribute ");
1239  return NX_ERROR;
1240  }
1241  return NX_OK;
1242  }
1243 
1244  /* ------------------------------------------------------------------- */
1245 
1246 
1247  NXstatus NX4putslab64 (NXhandle fid, const void *data, const int64_t iStart[], const int64_t iSize[])
1248  {
1249  pNexusFile pFile;
1250  int iRet;
1251  int32 iStride[H4_MAX_VAR_DIMS];
1252  int32 myStart[H4_MAX_VAR_DIMS], mySize[H4_MAX_VAR_DIMS];
1253  int32 i, iRank, iType, iAtt;
1254  NXname pBuffer;
1255 
1256 
1257  pFile = NXIassert (fid);
1258 
1259  /* check if there is an SDS open */
1260  if (pFile->iCurrentSDS == 0) {
1261  NXReportError( "ERROR: no SDS open");
1262  return NX_ERROR;
1263  }
1264  /* initialise stride to 1 */
1265  for (i = 0; i < H4_MAX_VAR_DIMS; i++) {
1266  iStride[i] = 1;
1267  }
1268 
1269  SDgetinfo (pFile->iCurrentSDS, pBuffer,
1270  &iRank, myStart, &iType, &iAtt);
1271  for(i = 0; i < iRank; i++)
1272  {
1273  myStart[i] = (int32)iStart[i];
1274  mySize[i] = (int32)iSize[i];
1275  }
1276  /* finally write */
1277  iRet = SDwritedata (pFile->iCurrentSDS, myStart,
1278  iStride, mySize, (void*)data);
1279 
1280 
1281  /* deal with HDF errors */
1282  if (iRet < 0) {
1283  NXReportError( "ERROR: writing slab failed");
1284  return NX_ERROR;
1285  }
1286  return NX_OK;
1287  }
1288 
1289 
1290  /* ------------------------------------------------------------------- */
1291 
1292  NXstatus NX4getdataID (NXhandle fid, NXlink* sRes)
1293  {
1294  pNexusFile pFile;
1295  int datalen, type = NX_CHAR;
1296 
1297  pFile = NXIassert (fid);
1298 
1299  if (pFile->iCurrentSDS == 0) {
1300  sRes->iTag = NX_ERROR;
1301  return NX_ERROR;
1302  } else {
1303  sRes->iTag = DFTAG_NDG;
1304  sRes->iRef = SDidtoref (pFile->iCurrentSDS);
1306  datalen = 1024;
1307  memset(&sRes->targetPath,0,1024);
1308  if(NX4getattr(fid,"target",&sRes->targetPath,&datalen,&type) != NX_OK)
1309  {
1310  NXIbuildPath(pFile,sRes->targetPath,1024);
1311  }
1313  return NX_OK;
1314  }
1315  sRes->iTag = NX_ERROR;
1316  return NX_ERROR; /* not reached */
1317  }
1318 
1319 
1320  /* ------------------------------------------------------------------- */
1321 
1322 
1323  NXstatus NX4makelink (NXhandle fid, NXlink* sLink)
1324  {
1325  pNexusFile pFile;
1326  int32 dataID, type = DFNT_CHAR8, length;
1327  char name[] = "target";
1328 
1329  pFile = NXIassert (fid);
1330 
1331  if (pFile->iCurrentVG == 0) { /* root level, can not link here */
1332  return NX_ERROR;
1333  }
1334  Vaddtagref(pFile->iCurrentVG, sLink->iTag, sLink->iRef);
1335  length = strlen(sLink->targetPath);
1336  if(sLink->iTag == DFTAG_SDG || sLink->iTag == DFTAG_NDG ||
1337  sLink->iTag == DFTAG_SDS)
1338  {
1339  dataID = SDreftoindex(pFile->iSID,sLink->iRef);
1340  dataID = SDselect(pFile->iSID,dataID);
1341  SDsetattr(dataID,name,type,length,sLink->targetPath);
1342  SDendaccess(dataID);
1343  }
1344  else
1345  {
1346  dataID = Vattach(pFile->iVID,sLink->iRef,"w");
1347  Vsetattr(dataID, (char *)name, type, (int32) length, sLink->targetPath);
1348  Vdetach(dataID);
1349  }
1350  return NX_OK;
1351  }
1352  /* ------------------------------------------------------------------- */
1353 
1354 
1355  NXstatus NX4makenamedlink (NXhandle fid, CONSTCHAR* newname, NXlink* sLink)
1356  {
1357  pNexusFile pFile;
1358  int32 dataID, type = DFNT_CHAR8, length, dataType = NX_CHAR,
1359  rank = 1, attType = NX_INT32;
1360  int64_t iDim[1];
1361  char name[] = "target";
1362  int tags[2];
1363 
1364  pFile = NXIassert (fid);
1365 
1366  if (pFile->iCurrentVG == 0) { /* root level, can not link here */
1367  return NX_ERROR;
1368  }
1369 
1370  tags[0] = sLink->iTag;
1371  tags[1] = sLink->iRef;
1372 
1373  length = strlen(sLink->targetPath);
1374  if(sLink->iTag == DFTAG_SDG || sLink->iTag == DFTAG_NDG ||
1375  sLink->iTag == DFTAG_SDS)
1376  {
1377  iDim[0] = 1;
1378  NX4makedata64(fid,newname, dataType,rank,iDim);
1379  NX4opendata(fid,newname);
1380  NX4putattr(fid,"NAPIlink",tags, 2, attType);
1381  NX4closedata(fid);
1382  dataID = SDreftoindex(pFile->iSID,sLink->iRef);
1383  dataID = SDselect(pFile->iSID,dataID);
1384  SDsetattr(dataID,name,type,length,sLink->targetPath);
1385  SDendaccess(dataID);
1386  } else {
1387  NX4makegroup(fid,newname,"NAPIlink");
1388  NX4opengroup(fid,newname,"NAPIlink");
1389  NX4putattr(fid,"NAPIlink",tags, 2, attType);
1390  NX4closegroup(fid);
1391  dataID = Vattach(pFile->iVID,sLink->iRef,"w");
1392  Vsetattr(dataID, (char *)name, type, (int32) length, sLink->targetPath);
1393  Vdetach(dataID);
1394  }
1395  return NX_OK;
1396  }
1397 
1398  /*----------------------------------------------------------------------*/
1399 
1400  NXstatus NX4printlink (NXhandle fid, NXlink* sLink)
1401  {
1402  NXIassert (fid);
1403  printf("HDF4 link: iTag = %ld, iRef = %ld, target=\"%s\"\n", sLink->iTag, sLink->iRef, sLink->targetPath);
1404  return NX_OK;
1405  }
1406 
1407  /*----------------------------------------------------------------------*/
1408 
1409  NXstatus NX4flush(NXhandle *pHandle)
1410  {
1411  char *pFileName, *pCopy = NULL;
1412  int access, dummy, iRet, i, iStack;
1413  pNexusFile pFile = NULL;
1414  NXaccess ac;
1415  int *iRefs = NULL;
1416 
1417  pFile = NXIassert(*pHandle);
1418 
1419  /*
1420  The HDF4-API does not support a flush. We help ourselves with
1421  inquiring the name and access type of the file, closing it and
1422  opening it again. This is also the reason why this needs a pointer
1423  to the handle structure as the handle changes. The other thing we
1424  do is to store the refs of all open vGroups in a temporary array
1425  in order to recover the position in the vGroup hierarchy before the
1426  flush.
1427  */
1428  iRet = Hfidinquire(pFile->iVID,&pFileName,&access,&dummy);
1429  if (iRet < 0) {
1430  NXReportError(
1431  "ERROR: Failed to inquire file name for HDF file");
1432  return NX_ERROR;
1433  }
1434  if(pFile->iAccess[0] == 'r') {
1435  ac = NXACC_READ;
1436  }else if(pFile->iAccess[0] == 'w') {
1437  ac = NXACC_RDWR;
1438  } else {
1439  NXReportError(
1440  "ERROR: NX4flush failed to determine file access mode");
1441  return NX_ERROR;
1442  }
1443  pCopy = (char *)malloc((strlen(pFileName)+10)*sizeof(char));
1444  if(!pCopy) {
1445  NXReportError(
1446  "ERROR: Failed to allocate data for filename copy");
1447  return NX_ERROR;
1448  }
1449  memset(pCopy,0,strlen(pFileName)+10);
1450  strcpy(pCopy,pFileName);
1451 
1452  /* get refs for recovering vGroup position */
1453  iStack = 0;
1454  if(pFile->iStackPtr > 0) {
1455  iStack = pFile->iStackPtr + 1;
1456  iRefs = (int *)malloc(iStack*sizeof(int));
1457  if(!iRefs){
1458  NXReportError(
1459  "ERROR: Failed to allocate data for hierarchy copy");
1460  return NX_ERROR;
1461  }
1462  for(i = 0; i < iStack; i++){
1463  iRefs[i] = pFile->iStack[i].iVref;
1464  }
1465  }
1466 
1467  iRet = NX4close(pHandle);
1468  if(iRet != NX_OK) {
1469  return iRet;
1470  }
1471 
1472  iRet = NX4open(pCopy, ac, pHandle);
1473  free(pCopy);
1474 
1475  /* return to position in vGroup hierarchy */
1476  pFile = NXIassert(*pHandle);
1477  if(iStack > 0){
1478  pFile->iStackPtr = iStack - 1;
1479  for(i = 0; i < iStack; i++){
1480  pFile->iStack[i].iVref = iRefs[i];
1481  }
1482  free(iRefs);
1483  pFile->iCurrentVG = Vattach(pFile->iVID,
1484  pFile->iStack[pFile->iStackPtr].iVref,
1485  pFile->iAccess);
1486  }
1487 
1488  return iRet;
1489  }
1490 
1491  /*-------------------------------------------------------------------------*/
1492 
1493 
1494  NXstatus NX4getnextentry (NXhandle fid, NXname name, NXname nxclass, int *datatype)
1495  {
1496  pNexusFile pFile;
1497  int iRet, iStackPtr, iCurDir;
1498  int32 iTemp, iD1, iD2, iA;
1499  int32 iDim[H4_MAX_VAR_DIMS];
1500 
1501  pFile = NXIassert (fid);
1502 
1503  iStackPtr = pFile->iStackPtr;
1504  iCurDir = pFile->iStack[pFile->iStackPtr].iCurDir;
1505 
1506  /* first case to check for: no directory entry */
1507  if (pFile->iStack[pFile->iStackPtr].iRefDir == NULL) {
1508  iRet = NXIInitDir (pFile);
1509  if (iRet < 0) {
1510  NXReportError(
1511  "ERROR: no memory to store directory info");
1512  return NX_EOD;
1513  }
1514  }
1515 
1516  /* Next case: end of directory */
1517  if (iCurDir >= pFile->iStack[pFile->iStackPtr].iNDir) {
1518  NXIKillDir (pFile);
1519  return NX_EOD;
1520  }
1521 
1522  /* Next case: we have data! supply it and increment counter */
1523  if (pFile->iCurrentVG == 0) { /* root level */
1524  iTemp = Vattach (pFile->iVID,
1525  pFile->iStack[iStackPtr].iRefDir[iCurDir], "r");
1526  if (iTemp < 0) {
1527  NXReportError( "ERROR: HDF cannot attach to Vgroup");
1528  return NX_ERROR;
1529  }
1530  Vgetname (iTemp, name);
1531  Vdetach (iTemp);
1532  findNapiClass(pFile, pFile->iStack[pFile->iStackPtr].iRefDir[iCurDir], nxclass);
1533  *datatype = DFTAG_VG;
1534  pFile->iStack[pFile->iStackPtr].iCurDir++;
1535  return NX_OK;
1536  } else { /* in Vgroup */
1537  if (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_VG) {/* Vgroup */
1538  iTemp = Vattach (pFile->iVID,
1539  pFile->iStack[iStackPtr].iRefDir[iCurDir], "r");
1540  if (iTemp < 0) {
1541  NXReportError( "ERROR: HDF cannot attach to Vgroup");
1542  return NX_ERROR;
1543  }
1544  Vgetname (iTemp, name);
1545  Vdetach(iTemp);
1546  findNapiClass(pFile, pFile->iStack[pFile->iStackPtr].iRefDir[iCurDir], nxclass);
1547  *datatype = DFTAG_VG;
1548  pFile->iStack[pFile->iStackPtr].iCurDir++;
1549  Vdetach (iTemp);
1550  return NX_OK;
1551  /* we are now writing using DFTAG_NDG, but need others for backward compatability */
1552  } else if ((pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_SDG) ||
1553  (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_NDG) ||
1554  (pFile->iStack[iStackPtr].iTagDir[iCurDir] == DFTAG_SDS)) {
1555  iTemp = SDreftoindex (pFile->iSID,
1556  pFile->iStack[iStackPtr].iRefDir[iCurDir]);
1557  iTemp = SDselect (pFile->iSID, iTemp);
1558  SDgetinfo (iTemp, name, &iA, iDim, &iD1, &iD2);
1559  strcpy (nxclass, "SDS");
1560  *datatype = iD1;
1561  SDendaccess (iTemp);
1562  pFile->iStack[pFile->iStackPtr].iCurDir++;
1563  return NX_OK;
1564  } else { /* unidentified */
1565  strcpy (name, "UNKNOWN");
1566  strcpy (nxclass, "UNKNOWN");
1567  *datatype = pFile->iStack[iStackPtr].iTagDir[iCurDir];
1568  pFile->iStack[pFile->iStackPtr].iCurDir++;
1569  return NX_OK;
1570  }
1571  }
1572  return NX_ERROR; /* not reached */
1573  }
1574 
1575 
1576  /*-------------------------------------------------------------------------*/
1577 
1578 
1579  NXstatus NX4getdata (NXhandle fid, void *data)
1580  {
1581  pNexusFile pFile;
1582  int32 iStart[H4_MAX_VAR_DIMS], iSize[H4_MAX_VAR_DIMS];
1583  NXname pBuffer;
1584  int32 iRank, iAtt, iType;
1585 
1586  pFile = NXIassert (fid);
1587 
1588  /* check if there is an SDS open */
1589  if (pFile->iCurrentSDS == 0) {
1590  NXReportError( "ERROR: no SDS open");
1591  return NX_ERROR;
1592  }
1593  /* first read dimension information */
1594  memset (iStart, 0, H4_MAX_VAR_DIMS * sizeof (int32));
1595  SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, iSize, &iType, &iAtt);
1596  /* actually read */
1597  SDreaddata (pFile->iCurrentSDS, iStart, NULL, iSize, data);
1598  return NX_OK;
1599  }
1600 
1601  /*-------------------------------------------------------------------------*/
1602 
1603  NXstatus
1604  NX4getinfo64 (NXhandle fid, int *rank, int64_t dimension[],
1605  int *iType)
1606  {
1607  pNexusFile pFile;
1608  NXname pBuffer;
1609  int32 iAtt, myDim[H4_MAX_VAR_DIMS], i, iRank, mType;
1610 
1611  pFile = NXIassert (fid);
1612 
1613  /* check if there is an SDS open */
1614  if (pFile->iCurrentSDS == 0) {
1615  NXReportError( "ERROR: no SDS open");
1616  return NX_ERROR;
1617  }
1618  /* read information */
1619  SDgetinfo (pFile->iCurrentSDS, pBuffer, &iRank, myDim,
1620  &mType, &iAtt);
1621 
1622  /* conversion to proper ints for the platform */
1623  *iType = (int)mType;
1624  *rank = (int)iRank;
1625  for(i = 0; i < iRank; i++)
1626  {
1627  dimension[i] = (int)myDim[i];
1628  }
1629  return NX_OK;
1630  }
1631 
1632 
1633  /*-------------------------------------------------------------------------*/
1634 
1635 
1636  NXstatus NX4getslab64 (NXhandle fid, void *data, const int64_t iStart[], const int64_t iSize[])
1637  {
1638  pNexusFile pFile;
1639  int32 myStart[H4_MAX_VAR_DIMS], mySize[H4_MAX_VAR_DIMS];
1640  int32 i, iRank, iType, iAtt;
1641  NXname pBuffer;
1642 
1643  pFile = NXIassert (fid);
1644 
1645  /* check if there is an SDS open */
1646  if (pFile->iCurrentSDS == 0) {
1647  NXReportError( "ERROR: no SDS open");
1648  return NX_ERROR;
1649  }
1650 
1651  SDgetinfo (pFile->iCurrentSDS, pBuffer,
1652  &iRank, myStart, &iType, &iAtt);
1653  for(i = 0; i < iRank; i++)
1654  {
1655  myStart[i] = (int32)iStart[i];
1656  mySize[i] = (int32)iSize[i];
1657  }
1658  /* finally read */
1659  SDreaddata (pFile->iCurrentSDS, myStart, NULL,
1660  mySize, data);
1661  return NX_OK;
1662  }
1663 
1664  /*-------------------------------------------------------------------------*/
1665 
1666  NXstatus NX4getnextattr (NXhandle fileid, NXname pName,
1667  int *iLength, int *iType)
1668  {
1669  pNexusFile pFile;
1670  int iRet;
1671  int32 iPType, iCount, count;
1672 
1673  pFile = NXIassert (fileid);
1674 
1675  /* first check if we have to start a new attribute search */
1676  if (pFile->iAtt.iNDir == 0) {
1677  iRet = NXIInitAttDir (pFile);
1678  if (iRet == NX_ERROR) {
1679  return NX_ERROR;
1680  }
1681  }
1682  /* are we done ? */
1683  if (pFile->iAtt.iCurDir >= pFile->iAtt.iNDir) {
1684  NXIKillAttDir (pFile);
1685  return NX_EOD;
1686  }
1687  /* well, there must be data to copy */
1688  if (pFile->iCurrentSDS == 0) {
1689  if(pFile->iCurrentVG == 0) {
1690  /* global attribute */
1691  iRet = SDattrinfo (pFile->iSID, pFile->iAtt.iCurDir,
1692  pName, &iPType, &iCount);
1693  }else {
1694  /* group attribute */
1695  iRet = Vattrinfo(pFile->iCurrentVG, pFile->iAtt.iCurDir,
1696  pName, &iPType, &iCount, &count);
1697  }
1698  } else {
1699  iRet = SDattrinfo (pFile->iCurrentSDS, pFile->iAtt.iCurDir,
1700  pName, &iPType, &iCount);
1701  }
1702  if (iRet < 0) {
1703  NXReportError( "ERROR: HDF cannot read attribute info");
1704  return NX_ERROR;
1705  }
1706  *iLength = iCount;
1707  *iType = iPType;
1708  pFile->iAtt.iCurDir++;
1709  return NX_OK;
1710  }
1711 
1712 
1713  /*-------------------------------------------------------------------------*/
1714 
1715 
1716  NXstatus NX4getattr (NXhandle fid, const char *name, void *data, int* datalen, int* iType)
1717  {
1718  pNexusFile pFile;
1719  int32 iNew, iType32, count;
1720  void *pData = NULL;
1721  int32 iLen, iRet;
1722  int type;
1723  char pBuffer[256];
1724  NXname pNam;
1725 
1726  type = *iType;
1727  if (type == NX_CHAR)
1728  {
1729  type=DFNT_CHAR8;
1730  }
1731  else if (type == NX_INT8)
1732  {
1733  type=DFNT_INT8;
1734  }
1735  else if (type == NX_UINT8)
1736  {
1737  type=DFNT_UINT8;
1738  }
1739  else if (type == NX_INT16)
1740  {
1741  type=DFNT_INT16;
1742  }
1743  else if (type == NX_UINT16)
1744  {
1745  type=DFNT_UINT16;
1746  }
1747  else if (type == NX_INT32)
1748  {
1749  type=DFNT_INT32;
1750  }
1751  else if (type == NX_UINT32)
1752  {
1753  type=DFNT_UINT32;
1754  }
1755  else if (type == NX_FLOAT32)
1756  {
1757  type=DFNT_FLOAT32;
1758  }
1759  else if (type == NX_FLOAT64)
1760  {
1761  type=DFNT_FLOAT64;
1762  }
1763  *datalen = (*datalen) * DFKNTsize(type);
1764  pFile = NXIassert (fid);
1765 
1766  /* find attribute */
1767  if (pFile->iCurrentSDS != 0) {
1768  /* SDS attribute */
1769  iNew = SDfindattr (pFile->iCurrentSDS, name);
1770  } else {
1771  if(pFile->iCurrentVG == 0){
1772  /* global attribute */
1773  iNew = SDfindattr (pFile->iSID, name);
1774  } else {
1775  /* group attribute */
1776  iNew = Vfindattr(pFile->iCurrentVG, name);
1777  }
1778  }
1779  if (iNew < 0) {
1780  sprintf (pBuffer, "ERROR: attribute \"%s\" not found", name);
1781  NXReportError( pBuffer);
1782  return NX_ERROR;
1783  }
1784  /* get more info, allocate temporary data space */
1785  iType32 = (int32)type;
1786  if (pFile->iCurrentSDS != 0) {
1787  iRet = SDattrinfo (pFile->iCurrentSDS, iNew, pNam, &iType32, &iLen);
1788  } else {
1789  if(pFile->iCurrentVG == 0){
1790  iRet = SDattrinfo (pFile->iSID, iNew, pNam, &iType32, &iLen);
1791  } else {
1792  iRet = Vattrinfo(pFile->iCurrentVG,iNew,pNam,&iType32,&count,
1793  &iLen);
1794  }
1795  }
1796  if (iRet < 0) {
1797  sprintf (pBuffer, "ERROR: HDF could not read attribute info");
1798  NXReportError( pBuffer);
1799  return NX_ERROR;
1800  }
1801  *iType = (int)iType32;
1802  iLen = iLen * DFKNTsize (*iType);
1803  if(*iType == NX_CHAR){
1804  iLen += 1;
1805  }
1806  pData = (void *) malloc (iLen);
1807  if (!pData) {
1808  NXReportError( "ERROR: allocating memory in NXgetattr");
1809  return NX_ERROR;
1810  }
1811  memset (pData, 0, iLen);
1812 
1813  /* finally read the data */
1814  if (pFile->iCurrentSDS != 0) {
1815  iRet = SDreadattr (pFile->iCurrentSDS, iNew, pData);
1816  } else {
1817  if(pFile->iCurrentVG == 0){
1818  iRet = SDreadattr (pFile->iSID, iNew, pData);
1819  } else {
1820  iRet = Vgetattr(pFile->iCurrentVG, iNew, pData);
1821  }
1822  }
1823  if (iRet < 0) {
1824  sprintf (pBuffer, "ERROR: HDF could not read attribute data");
1825  NXReportError( pBuffer);
1826  return NX_ERROR;
1827  }
1828  /* copy data to caller */
1829  memset (data, 0, *datalen);
1830  if ((*datalen <= iLen) &&
1831  (*iType == DFNT_UINT8 || *iType == DFNT_CHAR8 || *iType == DFNT_UCHAR8)) {
1832  iLen = *datalen - 1; /* this enforces NULL termination regardless of size of datalen */
1833  }
1834  memcpy (data, pData, iLen);
1835  *datalen = iLen / DFKNTsize(*iType);
1836  free (pData);
1837  return NX_OK;
1838  }
1839 
1840  /*-------------------------------------------------------------------------*/
1841 
1842 
1843  NXstatus NX4getattrinfo (NXhandle fid, int *iN)
1844  {
1845  pNexusFile pFile;
1846  int iRet;
1847  int32 iData, iAtt, iRank, iType;
1848  int32 iDim[H4_MAX_VAR_DIMS];
1849  NXname pNam;
1850 
1851  pFile = NXIassert (fid);
1852  if (pFile->iCurrentSDS != 0) { /* SDS level */
1853  iRet = SDgetinfo (pFile->iCurrentSDS, pNam, &iRank, iDim, &iType,
1854  &iAtt);
1855  } else {
1856  if(pFile->iCurrentVG == 0){
1857  /* global level */
1858  iRet = SDfileinfo (pFile->iSID, &iData, &iAtt);
1859  } else {
1860  iRet = Vnattrs(pFile->iCurrentVG);
1861  iAtt = iRet;
1862  }
1863  }
1864  if (iRet < 0) {
1865  NXReportError( "NX_ERROR: HDF cannot read attribute numbers");
1866  *iN = 0;
1867  return NX_ERROR;
1868  }
1869  *iN = iAtt;
1870  return NX_OK;
1871  }
1872 
1873  /*-------------------------------------------------------------------------*/
1874 
1875  NXstatus NX4getgroupID (NXhandle fileid, NXlink* sRes)
1876  {
1877  pNexusFile pFile;
1878 
1879  pFile = NXIassert (fileid);
1880 
1881  if (pFile->iCurrentVG == 0) {
1882  sRes->iTag = NX_ERROR;
1883  return NX_ERROR;
1884  } else {
1885  sRes->iTag = DFTAG_VG;
1886  sRes->iRef = VQueryref(pFile->iCurrentVG);
1887  NXIbuildPath(pFile,sRes->targetPath,1024);
1888  return NX_OK;
1889  }
1890  /* not reached */
1891  sRes->iTag = NX_ERROR;
1892  return NX_ERROR;
1893  }
1894 
1895  /*-------------------------------------------------------------------------*/
1896 
1897  NXstatus
1898  NX4getgroupinfo (NXhandle fid, int *iN, NXname pName, NXname pClass)
1899  {
1900  pNexusFile pFile;
1901 
1902  pFile = NXIassert (fid);
1903  /* check if there is a group open */
1904  if (pFile->iCurrentVG == 0) {
1905  *iN = Vlone (pFile->iVID, NULL, 0);
1906  strcpy (pName, "root");
1907  strcpy (pClass, "NXroot");
1908  }
1909  else {
1910  *iN = Vntagrefs (pFile->iCurrentVG);
1911  Vgetname (pFile->iCurrentVG, pName);
1912  Vgetclass (pFile->iCurrentVG, pClass);
1913  }
1914  return NX_OK;
1915  }
1916 
1917  /* ------------------------------------------------------------------- */
1918 
1919  NXstatus NX4sameID (NXhandle fileid, NXlink* pFirstID, NXlink* pSecondID)
1920  {
1921  NXIassert (fileid);
1922  if ((pFirstID->iTag == pSecondID->iTag) & (pFirstID->iRef == pSecondID->iRef)) {
1923  return NX_OK;
1924  } else {
1925  return NX_ERROR;
1926  }
1927  }
1928 
1929  /*-------------------------------------------------------------------------*/
1930 
1931 
1932  NXstatus NX4initattrdir (NXhandle fid)
1933  {
1934  pNexusFile pFile;
1935  int iRet;
1936 
1937  pFile = NXIassert (fid);
1938  NXIKillAttDir (pFile);
1939  iRet = NXIInitAttDir (pFile);
1940  if (iRet == NX_ERROR)
1941  return NX_ERROR;
1942  return NX_OK;
1943  }
1944 
1945 
1946  /*-------------------------------------------------------------------------*/
1947 
1948 
1949  NXstatus NX4initgroupdir (NXhandle fid)
1950  {
1951  pNexusFile pFile;
1952  int iRet;
1953 
1954  pFile = NXIassert (fid);
1955  NXIKillDir (pFile);
1956  iRet = NXIInitDir (pFile);
1957  if (iRet < 0) {
1958  NXReportError("NX_ERROR: no memory to store directory info");
1959  return NX_EOD;
1960  }
1961  return NX_OK;
1962  }
1963 
1964 /*--------------------------------------------------------------------*/
1965 NXstatus NX4putattra(NXhandle handle, CONSTCHAR* name, const void* data, const int rank, const int dim[], const int iType)
1966 {
1967  if (rank > 1) {
1968  NXReportError("This is a HDF4 file, there is only rudimentary support for attribute arrays wirh rank <=1");
1969  return NX_ERROR;
1970  }
1971 
1972  return NX4putattr(handle, name, data, dim[0], iType);
1973 }
1974 
1975 /*--------------------------------------------------------------------*/
1976 NXstatus NX4getnextattra(NXhandle handle, NXname pName, int *rank, int dim[], int *iType)
1977 {
1978  NXstatus ret = NX4getnextattr(handle, pName, dim, iType);
1979  if (ret != NX_OK) return ret;
1980  (*rank) = 1;
1981  if (dim[0] <= 1 ) (*rank) = 0;
1982  return NX_OK;
1983 }
1984 
1985 /*--------------------------------------------------------------------*/
1986 NXstatus NX4getattra(NXhandle handle, const char* name, void* data)
1987 {
1988  NXReportError("This is a HDF4 file, attribute array API is not supported here");
1989  return NX_ERROR;
1990 }
1991 
1992 /*--------------------------------------------------------------------*/
1993 NXstatus NX4getattrainfo(NXhandle handle, NXname pName, int *rank, int dim[], int *iType)
1994 {
1995  NXReportError("This is a HDF4 file, attribute array API is not supported here");
1996  return NX_ERROR;
1997 }
1998 
1999 
2000 /*--------------------------------------------------------------------*/
2001 void NX4assignFunctions(pNexusFunction fHandle)
2002 {
2003  fHandle->nxclose=NX4close;
2004  fHandle->nxreopen=NULL;
2005  fHandle->nxflush=NX4flush;
2006  fHandle->nxmakegroup=NX4makegroup;
2007  fHandle->nxopengroup=NX4opengroup;
2008  fHandle->nxclosegroup=NX4closegroup;
2009  fHandle->nxmakedata64=NX4makedata64;
2011  fHandle->nxcompress=NX4compress;
2012  fHandle->nxopendata=NX4opendata;
2013  fHandle->nxclosedata=NX4closedata;
2014  fHandle->nxputdata=NX4putdata;
2015  fHandle->nxputattr=NX4putattr;
2016  fHandle->nxputslab64=NX4putslab64;
2017  fHandle->nxgetdataID=NX4getdataID;
2018  fHandle->nxmakelink=NX4makelink;
2019  fHandle->nxmakenamedlink=NX4makenamedlink;
2020  fHandle->nxgetdata=NX4getdata;
2021  fHandle->nxgetinfo64=NX4getinfo64;
2023  fHandle->nxgetslab64=NX4getslab64;
2024  fHandle->nxgetnextattr=NX4getnextattr;
2025  fHandle->nxgetattr=NX4getattr;
2026  fHandle->nxgetattrinfo=NX4getattrinfo;
2027  fHandle->nxgetgroupID=NX4getgroupID;
2029  fHandle->nxsameID=NX4sameID;
2031  fHandle->nxinitattrdir=NX4initattrdir;
2032  fHandle->nxprintlink=NX4printlink;
2033  fHandle->nxnativeexternallink=NULL;
2034  fHandle->nxputattra = NX4putattra;
2035  fHandle->nxgetnextattra = NX4getnextattra;
2036  fHandle->nxgetattra = NX4getattra;
2037  fHandle->nxgetattrainfo = NX4getattrainfo;
2038 }
2039 
2040 #endif /*HDF4*/
NXstatus NX4close(NXhandle *pHandle)
NXstatus(* nxgetinfo64)(NXhandle handle, int *rank, int64_t dimension[], int *datatype)
Definition: napi_internal.h:61
NXstatus NX4getdataID(NXhandle handle, NXlink *pLink)
NXstatus(* nxgetdataID)(NXhandle handle, NXlink *pLink)
Definition: napi_internal.h:57
NXstatus NX4putattr(NXhandle handle, CONSTCHAR *name, const void *data, int iDataLen, int iType)
NXstatus(* nxmakedata64)(NXhandle handle, CONSTCHAR *label, int datatype, int rank, int64_t dim[])
Definition: napi_internal.h:48
void NXMEnableErrorReporting()
Definition: napi.c:375
NXstatus(* nxinitgroupdir)(NXhandle handle)
Definition: napi_internal.h:73
NXstatus(* nxgetnextattr)(NXhandle handle, NXname pName, int *iLength, int *iType)
Definition: napi_internal.h:64
NXstatus NX4getinfo64(NXhandle handle, int *rank, int64_t dimension[], int *datatype)
NXstatus NX4compmakedata64(NXhandle handle, CONSTCHAR *label, int datatype, int rank, int64_t dim[], int comp_typ, int64_t bufsize[])
NXstatus(* nxgetattrinfo)(NXhandle handle, int *no_items)
Definition: napi_internal.h:69
NXstatus NX4makedata64(NXhandle handle, CONSTCHAR *label, int datatype, int rank, int64_t dim[])
NXstatus NX4closegroup(NXhandle handle)
NXstatus(* nxgetnextattra)(NXhandle handle, NXname pName, int *rank, int dim[], int *iType)
Definition: napi_internal.h:65
NXstatus(* nxclose)(NXhandle *pHandle)
Definition: napi_internal.h:43
NXstatus(* nxputattr)(NXhandle handle, CONSTCHAR *name, const void *data, int iDataLen, int iType)
Definition: napi_internal.h:54
NXstatus(* nxcompmakedata64)(NXhandle handle, CONSTCHAR *label, int datatype, int rank, int64_t dim[], int comp_typ, int64_t bufsize[])
Definition: napi_internal.h:49
#define NX_INT8
Definition: nxdataset.h:41
NXstatus NX4putslab64(NXhandle handle, const void *data, const int64_t start[], const int64_t size[])
NXstatus(* nxgetgroupinfo)(NXhandle handle, int *no_items, NXname name, NXname nxclass)
Definition: napi_internal.h:71
#define NX_FLOAT64
Definition: nxdataset.h:40
NXstatus(* nxputdata)(NXhandle handle, const void *data)
Definition: napi_internal.h:53
NXstatus(* nxgetdata)(NXhandle handle, void *data)
Definition: napi_internal.h:60
NXstatus NX4getattrainfo(NXhandle handle, NXname pName, int *rank, int dim[], int *iType)
NXstatus(* nxprintlink)(NXhandle handle, NXlink *link)
Definition: napi_internal.h:76
NXstatus(* nxputslab64)(NXhandle handle, const void *data, const int64_t start[], const int64_t size[])
Definition: napi_internal.h:56
#define NX_UINT8
Definition: nxdataset.h:42
NXstatus NX4open(CONSTCHAR *filename, NXaccess access_method, NXhandle *pHandle)
NXstatus(* nxmakegroup)(NXhandle handle, CONSTCHAR *name, CONSTCHAR *NXclass)
Definition: napi_internal.h:45
#define H4_MAX_VAR_DIMS
Definition: napi4.h:61
NXstatus NX4getattra(NXhandle handle, const char *name, void *data)
NXstatus NX4putattra(NXhandle handle, CONSTCHAR *name, const void *data, const int rank, const int dim[], const int iType)
NXstatus NX4closedata(NXhandle handle)
NXstatus(* nxgetattra)(NXhandle handle, const char *name, void *data)
Definition: napi_internal.h:67
NXstatus(* nxmakenamedlink)(NXhandle handle, CONSTCHAR *newname, NXlink *pLink)
Definition: napi_internal.h:59
NXstatus NX4getgroupinfo(NXhandle handle, int *no_items, NXname name, NXname nxclass)
#define NX_FLOAT32
Definition: nxdataset.h:39
NXstatus(* nxflush)(NXhandle *pHandle)
Definition: napi_internal.h:44
NXstatus NX4opengroup(NXhandle handle, CONSTCHAR *Vgroup, CONSTCHAR *NXclass)
void NX4assignFunctions(pNexusFunction fHandle)
NXstatus(* nxopengroup)(NXhandle handle, CONSTCHAR *name, CONSTCHAR *NXclass)
Definition: napi_internal.h:46
NXstatus NX4flush(NXhandle *pHandle)
NXstatus(* nxmakelink)(NXhandle handle, NXlink *pLink)
Definition: napi_internal.h:58
NXstatus(* nxcompress)(NXhandle handle, int compr_type)
Definition: napi_internal.h:50
NXstatus NX4getnextattr(NXhandle handle, NXname pName, int *iLength, int *iType)
NXstatus NX4makegroup(NXhandle handle, CONSTCHAR *Vgroup, CONSTCHAR *NXclass)
NXstatus NX4getnextattra(NXhandle handle, NXname pName, int *rank, int dim[], int *iType)
NXstatus(* nxopendata)(NXhandle handle, CONSTCHAR *label)
Definition: napi_internal.h:51
NXstatus(* nxgetattrainfo)(NXhandle handle, NXname pName, int *rank, int dim[], int *iType)
Definition: napi_internal.h:68
NXstatus(* nxgetnextentry)(NXhandle handle, NXname name, NXname nxclass, int *datatype)
Definition: napi_internal.h:62
NXstatus(* nxgetslab64)(NXhandle handle, void *data, const int64_t start[], const int64_t size[])
Definition: napi_internal.h:63
NXstatus NX4getdata(NXhandle handle, void *data)
NXstatus NX4makelink(NXhandle handle, NXlink *pLink)
NXstatus NX4getattr(NXhandle handle, const char *name, void *data, int *iDataLen, int *iType)
NXstatus NX4putdata(NXhandle handle, const void *data)
NXstatus(* nxsameID)(NXhandle handle, NXlink *pFirstID, NXlink *pSecondID)
Definition: napi_internal.h:72
NXstatus NX4opendata(NXhandle handle, CONSTCHAR *label)
NXstatus NX4getnextentry(NXhandle handle, NXname name, NXname nxclass, int *datatype)
NXstatus(* nxputattra)(NXhandle handle, CONSTCHAR *name, const void *data, const int rank, const int dim[], const int iType)
Definition: napi_internal.h:55
NXstatus(* nxreopen)(NXhandle pOrigHandle, NXhandle *pNewHandle)
Definition: napi_internal.h:42
void NXReportError(char *string)
Definition: napi.c:305
NXstatus NX4getgroupID(NXhandle handle, NXlink *pLink)
void NXMDisableErrorReporting()
Definition: napi.c:360
NXstatus NX4getattrinfo(NXhandle handle, int *no_items)
NXstatus NX4getslab64(NXhandle handle, void *data, const int64_t start[], const int64_t size[])
NXstatus NX4initgroupdir(NXhandle handle)
#define NX_UINT16
Definition: nxdataset.h:44
NXstatus(* nxclosedata)(NXhandle handle)
Definition: napi_internal.h:52
NXstatus(* nxclosegroup)(NXhandle handle)
Definition: napi_internal.h:47
NXstatus(* nxnativeexternallink)(NXhandle handle, CONSTCHAR *name, CONSTCHAR *externalfile, CONSTCHAR *remotetarget)
Definition: napi_internal.h:77
char * NXIformatNeXusTime()
Definition: napi.c:1973
#define NX_CHAR
Definition: nxdataset.h:49
NXstatus NX4compress(NXhandle handle, int compr_type)
NXstatus(* nxinitattrdir)(NXhandle handle)
Definition: napi_internal.h:74
#define NX_UINT32
Definition: nxdataset.h:46
#define NX_INT32
Definition: nxdataset.h:45
NXstatus NX4printlink(NXhandle handle, NXlink *pLink)
NXstatus(* nxgetattr)(NXhandle handle, const char *name, void *data, int *iDataLen, int *iType)
Definition: napi_internal.h:66
#define NX_INT16
Definition: nxdataset.h:43
NXstatus NX4initattrdir(NXhandle handle)
NXstatus(* nxgetgroupID)(NXhandle handle, NXlink *pLink)
Definition: napi_internal.h:70
#define NXSIGNATURE
Definition: napi4.h:4