/******************************************************************************
*
*  NSSDC/CDF			CDF C interface for non-macro'ed functions
*				of the Standard Interface.
*
*  Version 2.4a, 8-Mar-97, Hughes STX.
*
*  Modification history:
*
*   V1.0   1-Jun-91, J Love	Original version (for CDF V2.1).  This is a
*				combination of cdf.c, cdfattr.c and cdfvar.c.
*				Most of these functions can be replaced by
*				the macros in 'cdf.h'.
*   V1.1  30-Jul-91, J Love	Use 'CDFlib'.
*   V2.0  10-Feb-92, J Love	IBM PC port.
*   V2.1  21-Aug-92, J Love	CDF V2.3 (shareable/NeXT/zVar).
*   V2.2  18-Oct-93, J Love	CDF V2.4.
*   V2.3   9-Nov-94, J Love	CDF V2.5.
*   V2.4  14-Feb-96, J Love	CDF V2.6 (renamed - previously `cdf_c_if.c').
*   V2.4a  8-Mar-97, J Love	Windows NT for Visual C++ 4 on an IBM PC.
*   V3.0  28-Aug-01, M Liu      Add CDFgetrVarsRecordData, CDFgetzVarsRecordData,
*                               CDFputrVarsRecordData, CDFputzVarsRecordData.
*   V3.1  31-May-05, M Liu      Replaced CDFgetrVarsRecordData and
*                               CDFgetzVarsRecordData with a general function.
*                               So, are the CDFputrVarsRecordData and
*                               CDFputzVarsRecordData.
*
******************************************************************************/

#include "cdflib.h"

/******************************************************************************
* CDFinquire.
* Can't implement with macro because the attribute's scope determines which
* item(s) to use.
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFinquire (id, numDims, dimSizes, encoding, majority,
                                     maxRec, nVars, nAttrs)
CDFid   id;             /* In --  CDF id. */
long    *numDims;       /* Out -- Number of dimensions. */
long    dimSizes[];     /* Out -- Dimensional sizes. */
long    *encoding;      /* Out -- Encoding. */
long    *majority;      /* Out -- Majority. */
long    *maxRec;        /* Out -- Maximum record number. */
long    *nVars;         /* Out -- Number of variables. */
long    *nAttrs;        /* Out -- Number of attributes. */

{
  CDFstatus pStatus = CDF_OK;
  long maxRecrVars, maxReczVars;
  long nrVars, nzVars;
  if (!sX(CDFlib(SELECT_, CDF_, id,
                 GET_, rVARs_NUMDIMS_, numDims, \
                       rVARs_DIMSIZES_, dimSizes, \
                       CDF_ENCODING_, encoding, \
                       CDF_MAJORITY_, majority, \
                       rVARs_MAXREC_, &maxRecrVars, \
                       zVARs_MAXREC_, &maxReczVars, \
                       CDF_NUMrVARS_, &nrVars, \
                       CDF_NUMzVARS_, &nzVars, \
                       CDF_NUMATTRS_, nAttrs, \
                 NULL_), &pStatus)) return pStatus;
  *maxRec = maxRecrVars;
  if (maxReczVars > maxRecrVars) *maxRec = maxReczVars;
  *nVars = nrVars + nzVars;
  return pStatus;
}

/******************************************************************************
* CDFinquireAttrInfo.
* Can't implement with macro because the attribute's scope determines which
* item(s) to use.
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFinquireAttrInfo (id, zEntry, attrNum, attrName, 
                                             scope, maxEntry)
CDFid   id;             /* In -- CDF id. */
int     zEntry;         /* In -- Flag for zEntry. */
long    attrNum;        /* In -- Attribute number. */
char    *attrName;      /* Out -- Attribute name. */
long    *scope;         /* Out -- Attribute scope. */
long    *maxEntry;      /* Out -- Maximum g/r/zEntry number used. */
{
  CDFstatus pStatus = CDF_OK;
  if (!sX(CDFlib(SELECT_, CDF_, id,
                          ATTR_, attrNum,
                 GET_, ATTR_SCOPE_, scope,
                 NULL_), &pStatus)) return pStatus;
  if (GLOBALscope(*scope) && (zEntry == 1)) return ILLEGAL_FOR_SCOPE;
  if (!sX(CDFlib(GET_, ATTR_NAME_, attrName,
                       BOO((zEntry == 1),ATTR_MAXzENTRY_,
                           (BOO(GLOBALscope(*scope),ATTR_MAXgENTRY_,
                                ATTR_MAXrENTRY_))), maxEntry,
                 NULL_), &pStatus)) return pStatus;
  return pStatus;
}

/******************************************************************************
* CDFinquireAttrEntryInfo.
* Can't implement with macro because the attribute's scope determines which
* item(s) to use.
******************************************************************************/
  
VISIBLE_PREFIX CDFstatus CDFinquireAttrEntryInfo (id, zEntry, attrNum, 
                                                  entryNum, dataType, numElems)
CDFid   id;             /* In -- CDF id. */
int     zEntry;         /* In -- Flag for zEntry. */
long    attrNum;        /* In -- Attribute number. */
long    entryNum;       /* In -- gEntry/rEntry/zEntry number. */
long    *dataType;      /* Out -- gEntry/rEntry/zEntry data type. */
long    *numElems;      /* Out -- gEntry/rEntry/zEntry number of elements. */
{
  long scope;
  CDFstatus pStatus = CDF_OK;
  if (!sX(CDFlib(SELECT_, CDF_, id,
                          ATTR_, attrNum,
                 GET_, ATTR_SCOPE_, &scope,
                 NULL_), &pStatus)) return pStatus;
  if (GLOBALscope(scope) && (zEntry == 1)) return ILLEGAL_FOR_SCOPE;
  if (!sX(CDFlib(SELECT_, BOO((zEntry == 1),zENTRY_,
                              (GLOBALscope(scope),gENTRY_,
                               rENTRY_)), entryNum,
                 GET_, BOO((zEntry == 1),zENTRY_DATATYPE_,
                           (BOO(GLOBALscope(scope),gENTRY_DATATYPE_,
                                rENTRY_DATATYPE_))), dataType,
                       BOO((zEntry == 1),zENTRY_NUMELEMS_,
                           (BOO(GLOBALscope(scope),gENTRY_NUMELEMS_,
                                rENTRY_NUMELEMS_))), numElems,
                 NULL_), &pStatus)) return pStatus;
  return pStatus;
}

/******************************************************************************
* CDFputAttrEntry.
* Can't implement with macro because the attribute's scope determines which
* item(s) to use.
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFputAttrEntry (id, zEntry, attrNum, entryNum, 
                                          dataType, numElems, value)
CDFid	id;		/* In -- CDF id. */
int     zEntry;         /* In -- Flag for zEntry. */
long	attrNum;	/* In -- Attribute number. */
long	entryNum;	/* In -- gEntry/rEntry/zEntry number. */
long	dataType;	/* In -- gEntry/rEntry/zEntry data type. */
long	numElems;	/* In -- gEntry/rEntry/zEntry number of elements. */
void	*value;		/* In -- Value. */
{
  long scope;
  CDFstatus pStatus = CDF_OK;
  if (!sX(CDFlib(SELECT_, CDF_, id,
			  ATTR_, attrNum,
		 GET_, ATTR_SCOPE_, &scope,
		 NULL_), &pStatus)) return pStatus;
  if (GLOBALscope(scope) && (zEntry == 1)) return ILLEGAL_FOR_SCOPE;
  if (!sX(CDFlib(SELECT_, BOO((zEntry == 1),zENTRY_,
                              (BOO(GLOBALscope(scope),gENTRY_,
                               rENTRY_))), entryNum,
		 PUT_, BOO((zEntry == 1),zENTRY_DATA_,
                           (BOO(GLOBALscope(scope),gENTRY_DATA_,
                                rENTRY_DATA_))), dataType, numElems, value,
		 NULL_), &pStatus)) return pStatus;
  return pStatus;
}

/******************************************************************************
* CDFgetAttrEntry.
* Can't implement with macro because the attribute's scope determines which
* item(s) to use.
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFgetAttrEntry (id, zEntry, attrNum, entryNum,
                                          value)
CDFid   id;             /* In -- CDF id. */
int     zEntry;         /* In -- Flag for zEntry. */
long    attrNum;        /* In -- Attribute number. */
long    entryNum;       /* In -- gEntry/rEntry/zEntry number. */
void    *value;         /* Out -- Value. */
{
  long scope;
  CDFstatus pStatus = CDF_OK;
  if (!sX(CDFlib(SELECT_, CDF_, id,
                          ATTR_, attrNum,
                 GET_, ATTR_SCOPE_, &scope,
                 NULL_), &pStatus)) return pStatus;
  if (GLOBALscope(scope) && (zEntry == 1)) return ILLEGAL_FOR_SCOPE;  
  if (!sX(CDFlib(SELECT_, BOO((zEntry == 1),zENTRY_,
                              (BOO(GLOBALscope(scope),gENTRY_,
                               rENTRY_))), entryNum,
                 GET_, BOO((zEntry == 1),zENTRY_DATA_,
                           (BOO(GLOBALscope(scope),gENTRY_DATA_,
                                rENTRY_DATA_))), value,
                 NULL_), &pStatus)) return pStatus;
  return pStatus;
}

/******************************************************************************
* CDFdeleteAttrEntry.
* Can't implement with macro because the attribute's scope determines which
* item(s) to use.
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFdeleteAttrEntry (id, zEntry, attrNum, entryNum)
CDFid   id;             /* In -- CDF id. */
int     zEntry;         /* In -- Flag for zEntry. */
long    attrNum;        /* In -- Attribute number. */
long    entryNum;       /* In -- gEntry/rEntry/zEntry number. */
{
  long scope;
  CDFstatus pStatus = CDF_OK;
  if (!sX(CDFlib(SELECT_, CDF_, id,
                          ATTR_, attrNum,
                 GET_, ATTR_SCOPE_, &scope,
                 NULL_), &pStatus)) return pStatus;
  if (GLOBALscope(scope) && (zEntry == 1)) return ILLEGAL_FOR_SCOPE;
  if (!sX(CDFlib(SELECT_, BOO((zEntry == 1),zENTRY_,
                              (BOO(GLOBALscope(scope),gENTRY_,
                               rENTRY_))), entryNum,
                 DELETE_, BOO((zEntry == 1),zENTRY_,
                              (BOO(GLOBALscope(scope),gENTRY_, rENTRY_))), 
                 NULL_), &pStatus)) return pStatus;
  return pStatus;
}

/******************************************************************************
* CDFsetAttrEntryDataSpec.
* Can't implement with macro because the attribute's scope determines which
* item(s) to use.
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFsetAttrEntryDataSpec (id, zEntry, attrNum, 
                                                  entryNum, dataType, numElems)
CDFid   id;             /* In -- CDF id. */
int     zEntry;         /* In -- Flag for zEntry. */
long    attrNum;        /* In -- Attribute number. */
long    entryNum;       /* In -- gEntry/rEntry/zEntry number. */
long    dataType;       /* In -- Data type. */
long    numElems;       /* In -- Number of elements. */
{
  long scope;
  CDFstatus pStatus = CDF_OK;
  if (!sX(CDFlib(SELECT_, CDF_, id,
                          ATTR_, attrNum,
                 GET_, ATTR_SCOPE_, &scope,
                 NULL_), &pStatus)) return pStatus;
  if (GLOBALscope(scope) && (zEntry == 1)) return ILLEGAL_FOR_SCOPE;
  if (!sX(CDFlib(SELECT_, BOO((zEntry == 1),zENTRY_,
                              (BOO(GLOBALscope(scope),gENTRY_,
                               rENTRY_))), entryNum,
                 PUT_, BOO((zEntry == 1),zENTRY_DATASPEC_,
                           (BOO(GLOBALscope(scope),gENTRY_DATASPEC_,
                                                   rENTRY_DATASPEC_))), 
                       dataType, numElems,
                 NULL_), &pStatus)) return pStatus;
  return pStatus;
}

/******************************************************************************
* CDFgetAttrNum.
* Can't implement with macro since it is the attribute number which is to be
* returned (unless an error).
******************************************************************************/

VISIBLE_PREFIX long CDFgetAttrNum (id,attrName)
CDFid	id;		/* In -- CDF id. */
char	*attrName;	/* In -- attribute name. */
{
  CDFstatus status;
  long attrNum;
  status = CDFlib (SELECT_, CDF_, id,
		   GET_, ATTR_NUMBER_, attrName, &attrNum,
		   NULL_);
  if (StatusOK(status))
    return attrNum;
  else
    return status;
}

/******************************************************************************
* CDFgetVarNum.
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/

VISIBLE_PREFIX long CDFgetVarNum (id,varName)
CDFid	id;		/* In -- CDF id. */
char	*varName;	/* In -- variable name. */
{
  CDFstatus status;
  long varNum;
  status = CDFlib (SELECT_, CDF_, id,
		   GET_, rVAR_NUMBER_, varName, &varNum,
		   NULL_);
  if (StatusOK(status))
    return varNum;
  else {
    status = CDFlib (SELECT_, CDF_, id,
	             GET_, zVAR_NUMBER_, varName, &varNum,
		     NULL_);
    if (StatusOK(status))
      return varNum;
  }  
    return status;
}

/******************************************************************************
* CDFgetVarDimIndices.
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFgetVarDimIndices (id,zVar,varNum,indices)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */ 
long    varNum;         /* In -- variable number. */
long    indices[];      /* Out -- Dimensional indices. */
{
  CDFstatus status;
  status = CDFlib (SELECT_, CDF_, id,
                   NULL_);
  if (StatusBAD(status)) return status;

  if (zVar) { 
    status = CDFlib (SELECT_, zVAR_, varNum,
                     NULL_);
    if (StatusBAD(status)) return status;
  }
  status = CDFlib (CONFIRM_, (zVar?zVAR_DIMINDICES_:rVARs_DIMINDICES_), 
                             indices, 
                   NULL_);
  return status;
}

/******************************************************************************
* CDFsetVarDimIndices.
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFsetVarDimIndices (id,zVar,varNum,indices)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */ 
long    varNum;         /* In -- variable number. */
long    indices[];      /* In -- Dimensional indices. */
{
  CDFstatus status;
  status = CDFlib (SELECT_, CDF_, id,
                   NULL_);
  if (StatusBAD(status)) return status;

  if (zVar) { 
    status = CDFlib (SELECT_, zVAR_, varNum,
                     NULL_);
    if (StatusBAD(status)) return status;
  }
  status = CDFlib (SELECT_, (zVar?zVAR_DIMINDICES_:rVARs_DIMINDICES_), 
                             indices, 
                   NULL_);
  return status;
}

/******************************************************************************
* CDFgetVarDimCounts.
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFgetVarDimCounts (id,zVar,varNum,counts)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    varNum;         /* In -- variable number. */
long    counts[];       /* Out -- Dimensional counts. */
{
  CDFstatus status;
  status = CDFlib (SELECT_, CDF_, id,
                   NULL_);
  if (StatusBAD(status)) return status;

  if (zVar) {
    status = CDFlib (SELECT_, zVAR_, varNum,
                     NULL_);
    if (StatusBAD(status)) return status;
  }
  status = CDFlib (CONFIRM_, (zVar?zVAR_DIMCOUNTS_:rVARs_DIMCOUNTS_),  
                             counts,  
                   NULL_);
  return status;
} 

/******************************************************************************
* CDFsetVarDimCounts.
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFsetVarDimCounts (id,zVar,varNum,counts)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    varNum;         /* In -- variable number. */
long    counts[];       /* In -- Dimensional counts. */
{
  CDFstatus status;
  status = CDFlib (SELECT_, CDF_, id,
                   NULL_);
  if (StatusBAD(status)) return status;

  if (zVar) {
    status = CDFlib (SELECT_, zVAR_, varNum,
                     NULL_);
    if (StatusBAD(status)) return status;
  }
  status = CDFlib (SELECT_, (zVar?zVAR_DIMCOUNTS_:rVARs_DIMCOUNTS_),  
                             counts,  
                   NULL_);
  return status;
} 

/******************************************************************************
* CDFgetVarDimIntervals.
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFgetVarDimIntervals (id,zVar,varNum,intervals)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    varNum;         /* In -- variable number. */
long    intervals[];    /* Out -- Dimensional intervals. */
{
  CDFstatus status;
  status = CDFlib (SELECT_, CDF_, id,
                   NULL_);
  if (StatusBAD(status)) return status;

  if (zVar) {
    status = CDFlib (SELECT_, zVAR_, varNum,
                     NULL_);
    if (StatusBAD(status)) return status;
  }
  status = CDFlib (CONFIRM_, (zVar?zVAR_DIMINTERVALS_:rVARs_DIMINTERVALS_),  
                             intervals,  
                   NULL_);
  return status;
} 

/******************************************************************************
* CDFsetVarDimIntervals.
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFsetVarDimIntervals (id,zVar,varNum,intervals)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    varNum;         /* In -- variable number. */
long    intervals[];    /* In -- Dimensional intervals. */
{
  CDFstatus status;
  status = CDFlib (SELECT_, CDF_, id,
                   NULL_);
  if (StatusBAD(status)) return status;

  if (zVar) {
    status = CDFlib (SELECT_, zVAR_, varNum,
                     NULL_);
    if (StatusBAD(status)) return status;
  }
  status = CDFlib (SELECT_, (zVar?zVAR_DIMINTERVALS_:rVARs_DIMINTERVALS_),  
                             intervals,  
                   NULL_);
  return status;
} 

/******************************************************************************
* CDFgetVarRecNumber.
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFgetVarRecNumber (id,zVar,varNum,recNum)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    varNum;         /* In -- Variable number. */
long    *recNum;        /* Out -- Record nuber. */
{
  CDFstatus status;
  status = CDFlib (SELECT_, CDF_, id,
                   NULL_);
  if (StatusBAD(status)) return status;

  if (zVar) {
    status = CDFlib (SELECT_, zVAR_, varNum,
                     NULL_);
    if (StatusBAD(status)) return status;
  }
  status = CDFlib (CONFIRM_, (zVar?zVAR_RECNUMBER_:rVARs_RECNUMBER_),  
                             recNum,  
                   NULL_);
  return status;
} 

/******************************************************************************
* CDFsetVarRecNumber.   
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/
  
VISIBLE_PREFIX CDFstatus CDFsetVarRecNumber (id,zVar,varNum,recNum)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    varNum;         /* In -- Variable number. */
long    recNum;         /* In -- Record nuber. */
{                    
  CDFstatus status;
  status = CDFlib (SELECT_, CDF_, id,
                   NULL_);
  if (StatusBAD(status)) return status;
                   
  if (zVar) {
    status = CDFlib (SELECT_, zVAR_, varNum,
                     NULL_);
    if (StatusBAD(status)) return status;
  }
  status = CDFlib (SELECT_, (zVar?zVAR_RECNUMBER_:rVARs_RECNUMBER_),  
                             recNum,
                   NULL_);
  return status;
} 

/******************************************************************************
* CDFgetVarRecCount.   
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/
  
VISIBLE_PREFIX CDFstatus CDFgetVarRecCount (id,zVar,varNum,count)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    varNum;         /* In -- Variable number. */
long    *count;         /* Out -- Record count */
{                    
  CDFstatus status;
  status = CDFlib (SELECT_, CDF_, id,
                   NULL_);
  if (StatusBAD(status)) return status;
                   
  if (zVar) {
    status = CDFlib (SELECT_, zVAR_, varNum,
                     NULL_);
    if (StatusBAD(status)) return status;
  }
  status = CDFlib (CONFIRM_, (zVar?zVAR_RECCOUNT_:rVARs_RECCOUNT_),  
                             count,
                   NULL_);
  return status;
} 

/******************************************************************************
* CDFsetVarRecCount.    
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/
  
VISIBLE_PREFIX CDFstatus CDFsetVarRecCount (id,zVar,varNum,count)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    varNum;         /* In -- Variable number. */
long    count;          /* Out -- Record count */
{                    
  CDFstatus status;
  status = CDFlib (SELECT_, CDF_, id,
                   NULL_);
  if (StatusBAD(status)) return status;
                   
  if (zVar) {
    status = CDFlib (SELECT_, zVAR_, varNum,
                     NULL_);
    if (StatusBAD(status)) return status;
  }
  status = CDFlib (SELECT_, (zVar?zVAR_RECCOUNT_:rVARs_RECCOUNT_),   
                             count,
                   NULL_);
  return status;
} 

/******************************************************************************
* CDFgetVarRecInterval.    
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/
  
VISIBLE_PREFIX CDFstatus CDFgetVarRecInterval (id,zVar,varNum,interval)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    varNum;         /* In -- Variable number. */
long    *interval;      /* Out -- Record interval */
{                    
  CDFstatus status;
  status = CDFlib (SELECT_, CDF_, id,
                   NULL_);
  if (StatusBAD(status)) return status;
                   
  if (zVar) {
    status = CDFlib (SELECT_, zVAR_, varNum,
                     NULL_);
    if (StatusBAD(status)) return status;
  }
  status = CDFlib (CONFIRM_, (zVar?zVAR_RECCOUNT_:rVARs_RECCOUNT_),   
                             interval,
                   NULL_);
  return status;
} 

/******************************************************************************
* CDFsetVarRecInterval.    
* Can't implement with macro since it is the variable number which is to be
* returned (unless an error).
******************************************************************************/
  
VISIBLE_PREFIX CDFstatus CDFsetVarRecInterval (id,zVar,varNum,interval)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    varNum;         /* In -- Variable number. */
long    interval;       /* In -- Record interval */
{                    
  CDFstatus status;
  status = CDFlib (SELECT_, CDF_, id,
                   NULL_);
  if (StatusBAD(status)) return status;
                   
  if (zVar) {
    status = CDFlib (SELECT_, zVAR_, varNum,
                     NULL_);
    if (StatusBAD(status)) return status;
  }
  status = CDFlib (SELECT_, (zVar?zVAR_RECCOUNT_:rVARs_RECCOUNT_),   
                             interval,
                   NULL_);
  return status;
} 

/******************************************************************************
* CDFgetNumAttrEntries.
* Can't implement with macro because the attribute's scope determines which
* item(s) to use. 
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFgetNumAttrEntries (id, zEntry, attrNum, numEntries)
CDFid   id;             /* In -- CDF id. */
int     zEntry;         /* In -- Flag for zEntry. */
long    attrNum;        /* In -- Attribute number. */
long    *numEntries;    /* Out -- number of gEntries/rEntries/zEntries. */
{
  long scope;
  CDFstatus pStatus = CDF_OK;
  if (!sX(CDFlib(SELECT_, CDF_, id,
                          ATTR_, attrNum,
                 GET_, ATTR_SCOPE_, &scope,
                 NULL_), &pStatus)) return pStatus;
  if (GLOBALscope(scope) && (zEntry == 1)) return ILLEGAL_FOR_SCOPE;
  if (!sX(CDFlib(GET_, BOO((zEntry == 1), ATTR_NUMzENTRIES_, 
                           (BOO(GLOBALscope(scope), ATTR_NUMgENTRIES_,
                                ATTR_NUMrENTRIES_))), numEntries,
                 NULL_), &pStatus)) return pStatus;
  return pStatus;
}

/******************************************************************************
* CDFgetAttrMaxEntry.  
* Can't implement with macro because the attribute's scope determines which
* item(s) to use.
******************************************************************************/
  
VISIBLE_PREFIX CDFstatus CDFgetAttrMaxEntry (id, zEntry, attrNum, maxEntry)
CDFid   id;             /* In -- CDF id. */
int     zEntry;         /* In -- Flag for zEntry. */
long    attrNum;        /* In -- Attribute number. */
long    *maxEntry;      /* Out -- Max. number of gEntry/rEntry/zEntry. */
{                
  long scope;
  CDFstatus pStatus = CDF_OK;
  if (!sX(CDFlib(SELECT_, CDF_, id,
                          ATTR_, attrNum,
                 GET_, ATTR_SCOPE_, &scope,
                 NULL_), &pStatus)) return pStatus;
  if (GLOBALscope(scope) && (zEntry == 1)) return ILLEGAL_FOR_SCOPE;
  if (!sX(CDFlib(GET_, BOO((zEntry == 1), ATTR_MAXzENTRY_,
                           (BOO(GLOBALscope(scope), ATTR_MAXgENTRY_, 
                            ATTR_MAXrENTRY_))), maxEntry,
                 NULL_), &pStatus)) return pStatus;
  return pStatus;
}

/******************************************************************************
* CDFgetAttrEntryDataType.
* Can't implement with macro because the attribute's scope determines which
* item(s) to use.
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFgetAttrEntryDataType (id, zEntry, attrNum, 
                                                  entryNum, dataType)
CDFid   id;             /* In -- CDF id. */
int     zEntry;         /* In -- Flag for zEntry. */
long    attrNum;        /* In -- Attribute number. */
long    entryNum;       /* In -- gEntry/rEntry/zEntry number. */
long    *dataType;      /* Out -- gEntry/rEntry/zEntry dataType. */
{
  long scope;
  CDFstatus pStatus = CDF_OK;
  if (!sX(CDFlib(SELECT_, CDF_, id,
                          ATTR_, attrNum,
                 GET_, ATTR_SCOPE_, &scope,
                 NULL_), &pStatus)) return pStatus;
  if (GLOBALscope(scope) && (zEntry == 1)) return ILLEGAL_FOR_SCOPE;
  if (!sX(CDFlib(SELECT_, BOO((zEntry == 1), zENTRY_, 
                              BOO(GLOBALscope(scope), gENTRY_,
                                  rENTRY_)), entryNum,
                 GET_, BOO((zEntry == 1), zENTRY_DATATYPE_,
                           BOO(GLOBALscope(scope), gENTRY_DATATYPE_,
                               rENTRY_DATATYPE_)), dataType,
                 NULL_), &pStatus)) return pStatus;
  return pStatus;
}

/******************************************************************************
* CDFgetAttrEntryNumElements.
* Can't implement with macro because the attribute's scope determines which
* item(s) to use.
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFgetAttrEntryNumElements (id, zEntry, attrNum, 
                                                     entryNum, numElements)
CDFid   id;             /* In -- CDF id. */
int     zEntry;         /* Flag for zEntry. */
long    attrNum;        /* In -- Attribute number. */
long    entryNum;       /* In -- gEntry/rEntry/zEntry number. */
long    *numElements;   /* Out -- gEntry/rEntry/zEntry numElements. */
{                
  long scope;
  CDFstatus pStatus = CDF_OK;
  if (!sX(CDFlib(SELECT_, CDF_, id,
                          ATTR_, attrNum,         
                 GET_, ATTR_SCOPE_, &scope,
                 NULL_), &pStatus)) return pStatus;
  if (GLOBALscope(scope) && (zEntry == 1)) return ILLEGAL_FOR_SCOPE;
  if (!sX(CDFlib(SELECT_, BOO((zEntry == 1), zENTRY_, 
                              BOO(GLOBALscope(scope), gENTRY_,
                                  rENTRY_)), entryNum,
                 GET_, BOO((zEntry == 1), zENTRY_NUMELEMS_, 
                           BOO(GLOBALscope(scope), gENTRY_NUMELEMS_,
                               rENTRY_NUMELEMS_)), numElements,
                 NULL_), &pStatus)) return pStatus;
  return pStatus;         
}                
                 
/******************************************************************************
* CDFgetVarRecordData.  
* Acquire a full record data from a given record of a variable.
* Retrieved data are filled into the buffer.
******************************************************************************/
  
VISIBLE_PREFIX CDFstatus CDFgetVarRecordData (id, zVar, varNum, recNum, buffer)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    varNum;         /* In -- Variable number. */
long    recNum;         /* In -- Record number to read. */
void    *buffer;        /* Out -- Buffer for holding data. */

{
  CDFstatus pStatus = CDF_OK;
  long numVars, varNums[CDF_MAX_DIMS];

  numVars = 1;
  varNums[0] = varNum;

  if (!sX(CDFlib(SELECT_, CDF_, id,
                          BOO(zVar,zVAR_RECNUMBER_,rVARs_RECNUMBER_),
                          recNum,
                 GET_, BOO((zVar == 1),zVARs_RECDATA_,rVARs_RECDATA_), numVars,
                       varNums, buffer,
                 NULL_), &pStatus)) return pStatus;
  return pStatus;
}

/******************************************************************************
* CDFputVarRecordData.
* Write a full record data for a given record of a variable.
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFputVarRecordData (id, zVar, varNum, recNum, buffer)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    varNum;         /* In -- Variable number. */
long    recNum;         /* In -- Record number to read. */
void    *buffer;        /* In -- Buffer for holding data. */

{
  CDFstatus pStatus = CDF_OK;
  long numVars, varNums[CDF_MAX_DIMS];

  numVars = 1;
  varNums[0] = varNum;

  if (!sX(CDFlib(SELECT_, CDF_, id,
                          BOO((zVar == 1),zVAR_RECNUMBER_,rVARs_RECNUMBER_),
                          recNum,
                 PUT_, BOO((zVar == 1),zVARs_RECDATA_,rVARs_RECDATA_), numVars,
                       varNums, buffer,
                 NULL_), &pStatus)) return pStatus;
  return pStatus;
}

/******************************************************************************
* CDFgetVarsRecordDatabyNames. 
* Acquire a full record data for a given record for a set of the selected 
* r/zVariables. Retrieved data are filled into the buffers that are pointed to
* by the passed array of pointers. The selected variables are identified by 
* their names.
******************************************************************************/

VISIBLE_PREFIX CDFstatus CDFgetVarsRecordDatabyNames (id, zVar, numVars, 
                                                      varNames, recNum, 
                                                      buffptr)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    numVars;        /* In -- Number of rVariables. */
char    *varNames[];    /* In -- Array of rVariable names. */
long    recNum;         /* In -- Record number to read. */ 
void    *buffptr[];     /* Out -- Array of buffer pointers for holding data. */

{ 
  CDFstatus pStatus = CDF_OK;
  long dataType, numElems, numDims; 
  long dimSizes[CDF_MAX_DIMS], dimVarys[CDF_MAX_DIMS];
  long dataTypeSize, recNumValues, phyRecSize[CDF_MAX_DIMS];
  long totalSize, offset, varNums[CDF_MAX_DIMS];
  int i, j;
  void *buffer;

  if (numVars <= 0) return pStatus;

  if (!sX(CDFlib(SELECT_, CDF_, id, 
                 NULL_), &pStatus)) return pStatus;

  totalSize = 0;
  for (i = 0; i < numVars; i++) {
    if (!sX(CDFlib(GET_, BOO((zVar == 1),zVAR_NUMBER_,rVAR_NUMBER_), 
                         varNames[i], &varNums[i], 
                   NULL_), &pStatus)) return pStatus;
    if (!sX(CDFlib(SELECT_, BOO((zVar == 1),zVAR_,rVAR_), varNums[i],
                   GET_, BOO((zVar == 1),zVAR_DATATYPE_,rVAR_DATATYPE_), 
                         &dataType,
                         BOO((zVar == 1),zVAR_NUMELEMS_,rVAR_NUMELEMS_), 
                         &numElems,
                         BOO((zVar == 1),zVAR_NUMDIMS_,rVARs_NUMDIMS_), 
                         &numDims,
                         BOO((zVar == 1),zVAR_DIMSIZES_,rVARs_DIMSIZES_), 
                         dimSizes,
                         BOO((zVar == 1),zVAR_DIMVARYS_,rVAR_DIMVARYS_), 
                         dimVarys,
                   NULL_), &pStatus)) return pStatus;
    if (!sX(CDFlib(GET_, DATATYPE_SIZE_, dataType, &dataTypeSize,
                   NULL_), &pStatus)) return pStatus;

    if (numDims == 0) {
      numDims = 1;
      dimSizes[0] = 1;
      dimVarys[0] = 0;
    }

    recNumValues = 1;
    for (j = 0; j < numDims; j++)
      if (dimVarys[j]) recNumValues *= dimSizes[j];
    phyRecSize[i] = recNumValues * dataTypeSize * numElems;
    totalSize += phyRecSize[i];
  }

  buffer = cdf_AllocateMemory (totalSize, NULL);
  if (buffer == NULL) return BAD_MALLOC;

  if (!sX(CDFlib(SELECT_, BOO((zVar == 1),zVARs_RECNUMBER_,rVARs_RECNUMBER_), 
                         recNum,
                 GET_, BOO((zVar == 1),zVARs_RECDATA_,rVARs_RECDATA_), numVars,
                       varNums, buffer,
                 NULL_), &pStatus)) return pStatus;

  offset = 0;
  for (i = 0; i < numVars; i++) {
    memcpy((char *) buffptr[i], (char *) buffer+offset, phyRecSize[i]);
    offset += phyRecSize[i];
  }
  cdf_FreeMemory (buffer, NULL);
  return CDF_OK;

}

/******************************************************************************
* CDFputVarsRecordDatabyNames.  
* Write a full record data for a given record for a set of the selected 
* r/zVariables. Input data are pointed to by the passed array of pointers.
******************************************************************************/
                   
VISIBLE_PREFIX CDFstatus CDFputVarsRecordDatabyNames (id, zVar, numVars, 
                                                      varNames, recNum, 
                                                      buffptr)
CDFid   id;             /* In -- CDF id. */
int     zVar;           /* In -- Flag for zVariable. */
long    numVars;        /* In -- Number of rVariables. */
char    *varNames[];    /* In -- Array of rVariable names. */
long    recNum;         /* In -- Record number to read. */
void    *buffptr[];     /* In -- Array of buffer pointers for holding data. */
    
{   
  CDFstatus pStatus = CDF_OK;
  long dataType, numElems, numDims; 
  long dimSizes[CDF_MAX_DIMS], dimVarys[CDF_MAX_DIMS];
  long dataTypeSize, recNumValues, phyRecSize[CDF_MAX_DIMS];
  long totalSize, offset, varNums[CDF_MAX_DIMS];
  int i, j;
  void *buffer; 

  if (numVars <= 0) return pStatus;
               
  if (!sX(CDFlib(SELECT_, CDF_, id,
                 NULL_), &pStatus)) return pStatus;

  totalSize = 0;
  for (i = 0; i < numVars; i++) {
    if (!sX(CDFlib(GET_, BOO((zVar == 1),zVAR_NUMBER_,rVAR_NUMBER_), 
                         varNames[i], &varNums[i],
                   NULL_), &pStatus)) return pStatus;
    if (!sX(CDFlib(SELECT_, BOO((zVar == 1),zVAR_,rVAR_), varNums[i],
                   GET_, BOO((zVar == 1),zVAR_DATATYPE_,rVAR_DATATYPE_), 
                         &dataType,
                         BOO((zVar == 1),zVAR_NUMELEMS_,rVAR_NUMELEMS_), 
                         &numElems,
                         BOO((zVar == 1),zVAR_NUMDIMS_,rVARs_NUMDIMS_), 
                         &numDims,
                         BOO((zVar == 1),zVAR_DIMSIZES_,rVARs_DIMSIZES_), 
                         dimSizes,
                         BOO((zVar == 1),zVAR_DIMVARYS_,rVAR_DIMVARYS_), 
                         dimVarys,
                   NULL_), &pStatus)) return pStatus;
    if (!sX(CDFlib(GET_, DATATYPE_SIZE_, dataType, &dataTypeSize,
                   NULL_), &pStatus)) return pStatus;

    if (numDims == 0) {
      numDims = 1;
      dimSizes[0] = 1;
      dimVarys[0] = 0;
    }

    recNumValues = 1;
    for (j = 0; j < numDims; j++)
      if (dimVarys[j]) recNumValues *= dimSizes[j];
    phyRecSize[i] = recNumValues * dataTypeSize * numElems;
    totalSize += phyRecSize[i];
  }

  buffer = cdf_AllocateMemory (totalSize, NULL);
  if (buffer == NULL) return BAD_MALLOC;

  offset = 0;
  for (i = 0; i < numVars; i++) {
    memcpy((char *) buffer+offset, (char *) buffptr[i], phyRecSize[i]);
    offset += phyRecSize[i];
  }

  if (!sX(CDFlib(SELECT_, BOO((zVar == 1),zVARs_RECNUMBER_,rVARs_RECNUMBER_), 
                         recNum,
                 PUT_, BOO((zVar == 1),zVARs_RECDATA_,rVARs_RECDATA_), numVars,
                       varNums, buffer,
                 NULL_), &pStatus)) return pStatus;

  cdf_FreeMemory (buffer, NULL);
  return CDF_OK;

}

