home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / plotting / imagetoo / imagetl1.lha / Imagetool / HDF / dfgroup.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-09-20  |  10.4 KB  |  349 lines

  1. /*****************************************************************************
  2. *              NCSA HDF version 3.10
  3. *                July 1, 1990
  4. *
  5. * NCSA HDF Version 3.10 source code and documentation are in the public
  6. * domain.  Specifically, we give to the public domain all rights for future
  7. * licensing of the source code, all resale rights, and all publishing rights.
  8. * We ask, but do not require, that the following message be included in all
  9. * derived works:
  10. * Portions developed at the National Center for Supercomputing Applications at
  11. * the University of Illinois at Urbana-Champaign.
  12. * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
  13. * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
  14. * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
  15. *****************************************************************************/
  16.  
  17. #ifdef RCSID
  18. static char RcsId[] = "@(#)$Revision: 3.1 $";
  19. #endif
  20. /*
  21. $Header: /pita/work/HDF/dev/RCS/src/dfgroup.c,v 3.1 90/07/02 10:13:24 clow beta $
  22.  
  23. $Log:    dfgroup.c,v $
  24.  * Revision 3.1  90/07/02  10:13:24  clow
  25.  * some cosmetic modifications
  26.  * 
  27. */
  28. /*-----------------------------------------------------------------------------
  29.  * File:    dfgroup.c
  30.  * Purpose: Low level functions for implementing groups
  31.  * Invokes: df.c df.h
  32.  * Contents: 
  33.  *  DFdiread: read in the data identifier list from the group
  34.  *  DFdiget: get next data identifier from list
  35.  *  DFdisetup: get ready to store a list of data identifiers to write out
  36.  *  DFdiput: add a data identifier to the list to be written out
  37.  *  DFdiwrite: write out the list of data identifiers
  38.  *  DFDIputgroup: write out a group (array of tag/refs)
  39.  *  DFDIgetgroup: read in a group (array of tag/refs)
  40.  * Remarks: A group is a way of associating data elements with each other.
  41.  *          It is a tag whose data is a list of tag/refs
  42.  *          Each tag/ref combination is called a data identifier (DI).
  43.  *---------------------------------------------------------------------------*/
  44.  
  45.  
  46. #include "df.h"
  47.  
  48.  
  49. static DFdi *Dilist=NULL;    /* list of tag/refs constituting group */
  50. static int Dinlist;             /* no of tag/refs in list */
  51. static int Ndi;                 /* current position in list */
  52.  
  53. /*-----------------------------------------------------------------------------
  54.  * Name:    DFdiread
  55.  * Purpose: Read a list of DIs into memory
  56.  * Inputs:  dfile: HDF file pointer
  57.  *          tag, ref: id of group which is to be read in
  58.  * Returns: 0 on success, -1 on failure with DFerror set
  59.  * Users:   HDF systems programmers, DF8getrig, other routines
  60.  * Invokes: DFIcheck, DFIfind, DFgetelement
  61.  * Remarks: assumes tag is a group
  62.  *---------------------------------------------------------------------------*/
  63.  
  64. int DFdiread(dfile, tag, ref)
  65. DF *dfile;
  66. uint16 tag, ref;        /* tag, ref of group */
  67. {
  68.     DFdle *dlep;
  69.     int cdd;
  70.     int32 length;
  71.  
  72.     if (DFIcheck(dfile))
  73.         return(-1);
  74.  
  75.     /* find group */
  76.     if (DFIfind(dfile, tag, ref, 1, 0, 0, &dlep, &cdd) <0) {
  77.         DFerror = DFE_NOMATCH;
  78.         return(-1);
  79.     }
  80.  
  81.     /* get space for group */
  82.     length = dlep->dd[cdd].length;
  83.     if (Dilist) DFIfreespace((char*)Dilist); /* ensure earlier allocs freed */
  84.     Dilist = (DFdi *) DFIgetspace((unsigned)length);
  85.     if (!Dilist) {
  86.         DFerror = DFE_NOSPACE;
  87.         return(-1);
  88.     }
  89.  
  90.     Dinlist = length / 4;    /* 4==sizeof DFdi */
  91.     Ndi = 0;            /* no DIs returned so far */
  92.  
  93.     /* read in group */
  94.     if (DFgetelement(dfile, tag, ref, (char*) Dilist)<0) {
  95.         DFIfreespace((char*)Dilist);
  96.         Dilist = NULL;        /* flag value */
  97.         return(-1);
  98.     }
  99.     return(0);
  100. }
  101.  
  102. /*-----------------------------------------------------------------------------
  103.  * Name:    DFdiget
  104.  * Purpose: reaturn next DI from list
  105.  * Inputs:  di: space to return DI
  106.  * Returns: 0 on success, -1 on failure with DFerror set
  107.  * Users:   HDF systems programmers, DF8getrig, other routines
  108.  * Invokes: none
  109.  * Remarks: frees Dilist space when all DIs returned
  110.  *---------------------------------------------------------------------------*/
  111.  
  112. int DFdiget(di)
  113. DFdi *di;
  114. {
  115.     if (Ndi>=Dinlist)
  116.     return(-1);
  117.  
  118. #ifdef DF_STRUCTOK
  119.     *di = Dilist[Ndi++];    /* return next DI on list */
  120. #else /*DF_STRUCTOK*/
  121.     {
  122.         register char *p;
  123.     /* compute address of Ndi'th di */
  124.         p = (char *) Dilist + 4 * Ndi++;
  125.         UINT16READ(p, di->tag);
  126.         UINT16READ(p, di->ref);
  127.     }
  128. #endif /*DF_STRUCTOK*/
  129.     
  130.     if (Ndi==Dinlist) {
  131.         DFIfreespace((char*)Dilist); /* if all returned, free storage */
  132.         Dilist = NULL;        /* flag value */
  133.     }
  134.     return(0);
  135. }
  136.  
  137.  
  138. /*-----------------------------------------------------------------------------
  139.  * Name:    DFdisetup
  140.  * Purpose: setup space for storing a list of DIs to be written out
  141.  * Inputs:  maxsize: maximum number of DIs expected in the list
  142.  * Returns: 0 on success, -1 on failure with DFerror set
  143.  * Users:   HDF systems programmers, DF8putrig, other routines
  144.  * Invokes: none
  145.  * Remarks: This call should go away sometime.  Need better way to allocate
  146.  *          space, possibly just use a big block of static space
  147.  *---------------------------------------------------------------------------*/
  148.  
  149. int DFdisetup(maxsize)
  150. int maxsize;
  151. {
  152.     if (Dilist) DFIfreespace((char*)Dilist);
  153.     Dilist = (DFdi *) DFIgetspace((unsigned)(maxsize * 4));
  154.                 /* 4==sizeof(DFdi) */
  155.     if (!Dilist) {
  156.         DFerror = DFE_NOSPACE;
  157.         return(-1);
  158.     }
  159.     Dinlist = maxsize;        /* maximum size of list */
  160.     Ndi = 0;                    /* current size of list */
  161.     return(0);
  162. }
  163.  
  164. /*-----------------------------------------------------------------------------
  165.  * Name:    DFdiput
  166.  * Purpose: add a DI to the list to be written out
  167.  * Inputs:  tag, ref: DI to add
  168.  * Returns: 0 on success, -1 on failure with DFerror set
  169.  * Users:   HDF systems programmers, DF8putrig, other routines
  170.  * Invokes: none
  171.  * Remarks: arg is tag/ref rather than DI for convenience
  172.  *---------------------------------------------------------------------------*/
  173.  
  174. int DFdiput(tag, ref)
  175. uint16 tag, ref;
  176. {
  177.     register char *p;
  178.  
  179.     if (Ndi>=Dinlist) {
  180.         DFerror = DFE_NOTENOUGH;
  181.         return(-1);
  182.     }
  183.  
  184. #ifdef DF_STRUCTOK
  185.     Dilist[Ndi].tag = tag;
  186.     Dilist[Ndi++].ref = ref;
  187. #else /*DF_STRUCTOK*/
  188.     /* compute address of Ndi'th di to put tag/ref in */
  189.     p = (char *) Dilist + 4 * Ndi++;
  190.     UINT16WRITE(p, tag);
  191.     UINT16WRITE(p, ref);
  192. #endif /*DF_STRUCTOK*/
  193.  
  194.     return(0);
  195. }
  196.  
  197. /*-----------------------------------------------------------------------------
  198.  * Name:    DFdiwrite
  199.  * Purpose: Write DI list out to HDF file
  200.  * Inputs:  dfile: HDF file pointer
  201.  *          tag, ref: tag and ref of group whose contents is the list
  202.  * Returns: 0 on success, -1 on failure with DFerror set
  203.  * Users:   HDF systems programmers, DF8putrig, other routines
  204.  * Invokes: none
  205.  * Remarks: frees storage for Dilist
  206.  *---------------------------------------------------------------------------*/
  207.  
  208. int DFdiwrite(dfile, tag, ref)
  209. DF *dfile;
  210. uint16 tag, ref;
  211. {
  212.     int ret;            /* return value */
  213.  
  214.     if (DFIcheck(dfile))
  215.         return(-1);
  216.  
  217.     ret = DFputelement(dfile, tag, ref, (char*)Dilist,(int32)Ndi*4);
  218.                 /* 4==sizeof(DFdi) */
  219.     DFIfreespace((char*)Dilist);
  220.     Dilist = NULL;        /* flag value */
  221.     Dinlist = Ndi = 0;
  222.     return(ret);
  223. }
  224.  
  225. /*-----------------------------------------------------------------------------
  226.  * Name:    DFDIgetgroup
  227.  * Purpose: Read array of tag/refs from file
  228.  * Inputs:  filename: name of HDF file to read from
  229.  *          diarray: array to put tag/refs in
  230.  *          maxdis: maximum number of DIs that may be returned
  231.  *          groupdi: tag/ref of group to read
  232.  * Returns: number of DIs read on success, -1 on failure with DFerror set
  233.  * Users:   HDF systems programmers, other routines
  234.  * Invokes: none
  235.  * Remarks: none
  236.  *---------------------------------------------------------------------------*/
  237.  
  238. int DFDIgetgroup(filename, diarray, maxdis, groupdi)
  239. char *filename;
  240. int maxdis;
  241.  DFdi diarray[], *groupdi;
  242. {
  243.     DF *dfile;
  244.     int cdd, ret;
  245.     DFdle *dlep;
  246.     
  247.     DFerror = DFE_NOERROR;
  248.  
  249.     if (!filename[0]) {
  250.         DFerror = DFE_BADPTR;
  251.         return(-1);
  252.     }
  253.  
  254.     dfile = DFopen(filename, DFACC_ALL, -1);
  255.     if (dfile==NULL) return(-1);
  256.  
  257.     if (DFIfind(dfile, groupdi->tag, groupdi->ref, 1, 0, 0, &dlep, &cdd)<0)
  258.         return(DFIerr(dfile));
  259.  
  260.     if (DFaccess(dfile, groupdi->tag, groupdi->ref, "r")<0)
  261.         return(DFIerr(dfile));
  262.  
  263.     ret = dlep->dd[cdd].length / 4; /* 4==sizeof(DFdi) */
  264.     if (maxdis < ret) ret = maxdis;
  265.  
  266. #ifdef DF_STRUCTOK
  267.     if (DFread(dfile, diarray, (int32) (ret * sizeof( DFdi)))<0)
  268.         return(DFIerr(dfile));
  269. #else /*DF_STRUCTOK*/
  270.     {
  271.         int i;
  272.         char *p;
  273.  
  274.         p = (char *) DFtbuf;
  275.         if (DFread(dfile, p, (int32) ret*4)<0)
  276.             return(DFIerr(dfile));
  277.  
  278.         for (i=0; i<ret; i++) {
  279.             UINT16READ(p, diarray[i].tag);
  280.             UINT16READ(p, diarray[i].ref);
  281.         }
  282.     }
  283. #endif /*DF_STRUCTOK*/
  284.     
  285.     if (ret<maxdis) {
  286.         DFerror = DFE_NOTENOUGH;
  287.         return(DFIerr(dfile));
  288.     }
  289.     return(DFclose(dfile));
  290. }
  291.     
  292. /*-----------------------------------------------------------------------------
  293.  * Name:    DFDIputgroup
  294.  * Purpose: Write array of tag/refs to file
  295.  * Inputs:  filename: name of HDF file to write to
  296.  *          diarray: array of tag/refs to write out
  297.  *          ndis: number of DIs in array
  298.  *          groupdi: tag/ref of group to write array as
  299.  * Returns: 0 on success, -1 on failure with DFerror set
  300.  * Users:   HDF systems programmers, other routines
  301.  * Invokes: none
  302.  * Remarks: The group is always appended to an existing file
  303.  *---------------------------------------------------------------------------*/
  304.  
  305. int DFDIputgroup(filename, diarray, ndis, groupdi)
  306. char *filename;
  307. int ndis;
  308. DFdi diarray[], *groupdi;
  309. {
  310.     DF *dfile;
  311.     int ret;
  312.     
  313.     DFerror = DFE_NOERROR;
  314.  
  315.     if (!filename[0]) {
  316.         DFerror = DFE_BADPTR;
  317.         return(-1);
  318.     }
  319.  
  320.     dfile = DFopen(filename, DFACC_ALL, -1);
  321.     if (dfile==NULL) return(-1);
  322.  
  323. #ifdef DF_STRUCTOK
  324.     ret = DFputelement(dfile, groupdi->tag, groupdi->ref, diarray,
  325.                (int32) (ndis * 4));
  326. #else /*DF_STRUCTOK*/
  327.     {
  328.         int i;
  329.         char *p;
  330.  
  331.         p = (char *) DFtbuf;
  332.         for (i=0; i<ndis; i++) {
  333.             UINT16WRITE(p, diarray[i].tag);
  334.             UINT16WRITE(p, diarray[i].ref);
  335.         }
  336.         ret = DFputelement(dfile, groupdi->tag, groupdi->ref, p,
  337.                (int32)ndis*sizeof(DFdi));
  338.     }
  339. #endif /*DF_STRUCTOK*/
  340.     
  341.     if (ret<0) return(DFIerr(dfile));
  342.     return(DFclose(dfile));
  343. }
  344.