/*****************************************************************************
*
* NCSA HDF version 3.10
* July 1, 1990
*
* NCSA HDF Version 3.10 source code and documentation are in the public
* domain. Specifically, we give to the public domain all rights for
future
* licensing of the source code, all resale rights, and all publishing
rights.
*
* We ask, but do not require, that the following message be included in
all
* derived works:
*
* Portions developed at the National Center for Supercomputing
Applications at
* the University of Illinois at Urbana-Champaign.
*
* THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED,
FOR THE
* SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT
LIMITATION,
* WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR
PURPOSE
*
*****************************************************************************/
#ifdef RCSID
static char RcsId??(??) = "@(#)$Revision: 3.1 $";
#endif
/*
$Header: /pita/work/HDF/dev/RCS/src/dfgroup.c,v 3.1 90/07/02 10:13:24
clow beta $
$Log: dfgroup.c,v $
* Revision 3.1 90/07/02 10:13:24 clow
* some cosmetic modifications
*
*/
/*-----------------------------------------------------------------------------
* File: dfgroup.c
* Purpose: Low level functions for implementing groups
* Invokes: df.c df.h
* Contents:
* DFdiread: read in the data identifier list from the group
* DFdiget: get next data identifier from list
* DFdisetup: get ready to store a list of data identifiers to write
out
* DFdiput: add a data identifier to the list to be written out
* DFdiwrite: write out the list of data identifiers
* DFDIputgroup: write out a group (array of tag/refs)
* DFDIgetgroup: read in a group (array of tag/refs)
* Remarks: A group is a way of associating data elements with each
other.
* It is a tag whose data is a list of tag/refs
* Each tag/ref combination is called a data identifier (DI).
*---------------------------------------------------------------------------*/
#include "df.h"
static DFdi *Dilist=NULL; /* list of tag/refs constituting group
*/
static int Dinlist; /* no of tag/refs in list */
static int Ndi; /* current position in list */
/*-----------------------------------------------------------------------------
* Name: DFdiread
* Purpose: Read a list of DIs into memory
* Inputs: dfile: HDF file pointer
* tag, ref: id of group which is to be read in
* Returns: 0 on success, -1 on failure with DFerror set
* Users: HDF systems programmers, DF8getrig, other routines
* Invokes: DFIcheck, DFIfind, DFgetelement
* Remarks: assumes tag is a group
*---------------------------------------------------------------------------*/
int DFdiread(dfile, tag, ref)
DF *dfile;
uint16 tag, ref; /* tag, ref of group */
{
DFdle *dlep;
int cdd;
int32 length;
if (DFIcheck(dfile))
return(-1);
/* find group */
if (DFIfind(dfile, tag, ref, 1, 0, 0, &dlep, &cdd) <0) {
DFerror = DFE_NOMATCH;
return(-1);
}
/* get space for group */
length = dlep->dd??(cdd??).length;
if (Dilist) DFIfreespace((char*)Dilist); /* ensure earlier allocs
freed */
Dilist = (DFdi *) DFIgetspace((unsigned)length);
if (!Dilist) {
DFerror = DFE_NOSPACE;
return(-1);
}
Dinlist = length / 4; /* 4==sizeof DFdi */
Ndi = 0; /* no DIs returned so far */
/* read in group */
if (DFgetelement(dfile, tag, ref, (char*) Dilist)<0) {
DFIfreespace((char*)Dilist);
Dilist = NULL; /* flag value */
return(-1);
}
return(0);
}
/*-----------------------------------------------------------------------------
* Name: DFdiget
* Purpose: reaturn next DI from list
* Inputs: di: space to return DI
* Returns: 0 on success, -1 on failure with DFerror set
* Users: HDF systems programmers, DF8getrig, other routines
* Invokes: none
* Remarks: frees Dilist space when all DIs returned
*---------------------------------------------------------------------------*/
int DFdiget(di)
DFdi *di;
{
if (Ndi>=Dinlist)
return(-1);
#ifdef DF_STRUCTOK
*di = Dilist??(Ndi++??); /* return next DI on list */
#else /*DF_STRUCTOK*/
{
register char *p;
/* compute address of Ndi'th di */
p = (char *) Dilist + 4 * Ndi++;
UINT16READ(p, di->tag);
UINT16READ(p, di->ref);
}
#endif /*DF_STRUCTOK*/
if (Ndi==Dinlist) {
DFIfreespace((char*)Dilist); /* if all returned, free storage
*/
Dilist = NULL; /* flag value */
}
return(0);
}
/*-----------------------------------------------------------------------------
* Name: DFdisetup
* Purpose: setup space for storing a list of DIs to be written out
* Inputs: maxsize: maximum number of DIs expected in the list
* Returns: 0 on success, -1 on failure with DFerror set
* Users: HDF systems programmers, DF8putrig, other routines
* Invokes: none
* Remarks: This call should go away sometime. Need better way to
allocate
* space, possibly just use a big block of static space
*---------------------------------------------------------------------------*/
int DFdisetup(maxsize)
int maxsize;
{
if (Dilist) DFIfreespace((char*)Dilist);
Dilist = (DFdi *) DFIgetspace((unsigned)(maxsize * 4));
/* 4==sizeof(DFdi) */
if (!Dilist) {
DFerror = DFE_NOSPACE;
return(-1);
}
Dinlist = maxsize; /* maximum size of list */
Ndi = 0; /* current size of list */
return(0);
}
/*-----------------------------------------------------------------------------
* Name: DFdiput
* Purpose: add a DI to the list to be written out
* Inputs: tag, ref: DI to add
* Returns: 0 on success, -1 on failure with DFerror set
* Users: HDF systems programmers, DF8putrig, other routines
* Invokes: none
* Remarks: arg is tag/ref rather than DI for convenience
*---------------------------------------------------------------------------*/
int DFdiput(tag, ref)
uint16 tag, ref;
{
register char *p;
if (Ndi>=Dinlist) {
DFerror = DFE_NOTENOUGH;
return(-1);
}
#ifdef DF_STRUCTOK
Dilist??(Ndi??).tag = tag;
Dilist??(Ndi++??).ref = ref;
#else /*DF_STRUCTOK*/
/* compute address of Ndi'th di to put tag/ref in */
p = (char *) Dilist + 4 * Ndi++;
UINT16WRITE(p, tag);
UINT16WRITE(p, ref);
#endif /*DF_STRUCTOK*/
return(0);
}
/*-----------------------------------------------------------------------------
* Name: DFdiwrite
* Purpose: Write DI list out to HDF file
* Inputs: dfile: HDF file pointer
* tag, ref: tag and ref of group whose contents is the list
* Returns: 0 on success, -1 on failure with DFerror set
* Users: HDF systems programmers, DF8putrig, other routines
* Invokes: none
* Remarks: frees storage for Dilist
*---------------------------------------------------------------------------*/
int DFdiwrite(dfile, tag, ref)
DF *dfile;
uint16 tag, ref;
{
int ret; /* return value */
if (DFIcheck(dfile))
return(-1);
ret = DFputelement(dfile, tag, ref, (char*)Dilist,(int32)Ndi*4);
/* 4==sizeof(DFdi) */
DFIfreespace((char*)Dilist);
Dilist = NULL; /* flag value */
Dinlist = Ndi = 0;
return(ret);
}
/*-----------------------------------------------------------------------------
* Name: DFDIgetgroup
* Purpose: Read array of tag/refs from file
* Inputs: filename: name of HDF file to read from
* diarray: array to put tag/refs in
* maxdis: maximum number of DIs that may be returned
* groupdi: tag/ref of group to read
* Returns: number of DIs read on success, -1 on failure with DFerror
set
* Users: HDF systems programmers, other routines
* Invokes: none
* Remarks: none
*---------------------------------------------------------------------------*/
int DFDIgetgroup(filename, diarray, maxdis, groupdi)
char *filename;
int maxdis;
DFdi diarray??(??), *groupdi;
{
DF *dfile;
int cdd, ret;
DFdle *dlep;
DFerror = DFE_NOERROR;
if (!filename??(0??)) {
DFerror = DFE_BADPTR;
return(-1);
}
dfile = DFopen(filename, DFACC_ALL, -1);
if (dfile==NULL) return(-1);
if (DFIfind(dfile, groupdi->tag, groupdi->ref, 1, 0, 0, &dlep,
&cdd)<0)
return(DFIerr(dfile));
if (DFaccess(dfile, groupdi->tag, groupdi->ref, "r")<0)
return(DFIerr(dfile));
ret = dlep->dd??(cdd??).length / 4; /* 4==sizeof(DFdi) */
if (maxdis < ret) ret = maxdis;
#ifdef DF_STRUCTOK
if (DFread(dfile, diarray, (int32) (ret * sizeof( DFdi)))<0)
return(DFIerr(dfile));
#else /*DF_STRUCTOK*/
{
int i;
char *p;
p = (char *) DFtbuf;
if (DFread(dfile, p, (int32) ret*4)<0)
return(DFIerr(dfile));
for (i=0; itag, groupdi->ref, diarray,
(int32) (ndis * 4));
#else /*DF_STRUCTOK*/
{
int i;
char *p;
p = (char *) DFtbuf;
for (i=0; itag, groupdi->ref, p,
(int32)ndis*sizeof(DFdi));
}
#endif /*DF_STRUCTOK*/
if (ret<0) return(DFIerr(dfile));
return(DFclose(dfile));
}