/******************************************************************************
*
* NSSDC/CDF CDF `get' operations.
*
* Version 1.4, 9-Sep-96, Hughes STX.
*
* Modification history:
*
* V1.0 20-May-92, J Love Original version (was part of `cdflib.c').
* V1.1 16-Sep-92, J Love CDF V2.3 (shareable/NeXT/zVar).
* V1.2 13-Dec-93, J Love CDF V2.4.
* V1.3 15-Dec-94, J Love CDF V2.5.
* V1.3a 9-Jan-95, J Love Encode/decode changes. More cache-residency.
* V1.3b 24-Feb-95, J Love Solaris 2.3 IDL i/f.
* V1.3c 4-Aug-95, J Love CDFexport-related changes.
* V1.4 9-Sep-96, J Love CDF V2.6.
* V2.0 08-Apr-04, M Liu Removed call to LocateCurrentVar function as
* its offset becomes avilable when it is
* selected.
* V2.1 21-Jun-04, M Liu Modified the error message for NOT_A_CDF.
* V3.2 16-Oct-07, D Han The length of the pad value for a CDF_CHAR
* variable is the length of the variable (i.e.
* CHAR/162, etc.). If the length of the pad
* value is greater than 16, it causes
* segmentation fault for the IDL CDF interface
* routine.
******************************************************************************/
#include "cdflib.h"
#include "cdfrev.h"
/******************************************************************************
* CDFget.
******************************************************************************/
STATICforIDL CDFstatus CDFget (Va, Cur)
struct VAstruct *Va;
struct CurStruct *Cur;
{
CDFstatus tStatus, pStatus = CDF_OK;
switch (Va->item) {
/****************************************************************************
* CDF_INFO_
****************************************************************************/
case CDF_INFO_: {
char CDFpathX[DU_MAX_PATH_LEN+1], CDFpathT[CDF_PATHNAME_LEN+1], *CDFpathP;
vFILE *dotFp; Logical upper_case_ext, version_numbers, no_append;
Int32 magicNumber1, magicNumber2; int i;
long *cType, *cParms, *cFileSize, *uFileSize;
CDFpathP = va_arg (Va->ap, char *);
cType = va_arg (Va->ap, long *);
cParms = va_arg (Va->ap, long *);
cFileSize = va_arg (Va->ap, long *);
uFileSize = va_arg (Va->ap, long *);
if (strlen(CDFpathP) > (size_t) CDF_PATHNAME_LEN) {
if (!sX(CDF_NAME_TRUNC,&pStatus)) return pStatus;
}
strcpyX (CDFpathT, CDFpathP, CDF_PATHNAME_LEN);
#if STRIP_TRAILING_BLANKS_FROM_CDFPATH
StripTrailingBlanks (CDFpathT);
#endif
#if defined(vms) || defined(dos)
MakeUpperString (CDFpathT);
#endif
if (!ValidCDFname(CDFpathT)) return BAD_CDF_NAME;
if (!sX(FindCDF(CDFpathT,&no_append,
&upper_case_ext,
&version_numbers),&pStatus)) return pStatus;
BuildFilePath (CDFt, CDFpathT, no_append, upper_case_ext, version_numbers,
INT32_ZERO, CDFpathX);
dotFp = V_open (CDFpathX, READ_ONLY_a_mode);
if (dotFp == NULL) return CDF_OPEN_ERROR;
if (!Read32(dotFp,&magicNumber1)) {
V_close (dotFp, NULL, NULL);
return CDF_READ_ERROR;
}
if (!Read32(dotFp,&magicNumber2)) {
V_close (dotFp, NULL, NULL);
return CDF_READ_ERROR;
}
switch (magicNumber1) {
case V1magicNUMBER_flip:
V_close (dotFp, NULL, NULL);
return ILLEGAL_ON_V1_CDF;
case V2magicNUMBER_1pre:
*cType = NO_COMPRESSION;
*cFileSize = 0;
if (!SEEKv(dotFp,0L,vSEEK_END)) {
V_close (dotFp, NULL, NULL);
return CDF_READ_ERROR;
}
*uFileSize = V_tell (dotFp);
break;
case V2magicNUMBER_1:
switch (magicNumber2) {
case V2magicNUMBER_2u:
*cType = NO_COMPRESSION;
*cFileSize = 0;
if (!SEEKv(dotFp,0L,vSEEK_END)) {
V_close (dotFp, NULL, NULL);
return CDF_READ_ERROR;
}
*uFileSize = V_tell (dotFp);
break;
case V2magicNUMBER_2c: {
struct CCRstruct CCR; struct CPRstruct CPR;
if (!sX(ReadCCR(dotFp,V2_CCR_OFFSET,
CCR_RECORD,&CCR,
CCR_NULL),&pStatus)) {
V_close (dotFp, NULL, NULL);
return pStatus;
}
if (CCR.uSize == 0) {
V_close (dotFp, NULL, NULL);
return EMPTY_COMPRESSED_CDF;
}
if (!sX(ReadCPR(dotFp,CCR.CPRoffset,
CPR_RECORD,&CPR,
CPR_NULL),&pStatus)) {
V_close (dotFp, NULL, NULL);
return pStatus;
}
*cType = (long) CPR.cType;
if (CPR.pCount > CDF_MAX_PARMS) {
V_close (dotFp, NULL, NULL);
return TOO_MANY_PARMS;
}
for (i = 0; i < CPR.pCount; i++) cParms[i] = (long) CPR.cParms[i];
if (!SEEKv(dotFp,0L,vSEEK_END)) {
V_close (dotFp, NULL, NULL);
return CDF_READ_ERROR;
}
*cFileSize = V_tell (dotFp);
*uFileSize = (long) CCR.uSize + MAGIC_NUMBERS_SIZE;
break;
}
default:
V_close (dotFp, NULL, NULL);
return NOT_A_CDF;
}
break;
default:
V_close (dotFp, NULL, NULL);
return NOT_A_CDF_OR_NOT_SUPPORTED;
}
V_close (dotFp, NULL, NULL);
break;
}
/****************************************************************************
* STATUS_TEXT_,
****************************************************************************/
case STATUS_TEXT_: {
char *textPtr;
textPtr = va_arg (Va->ap, char *);
CDFstatusText (Cur->status, textPtr);
break;
}
/****************************************************************************
* DATATYPE_SIZE_,
****************************************************************************/
case DATATYPE_SIZE_: {
long dataType = va_arg (Va->ap, long);
long *numBytes = va_arg (Va->ap, long *);
if (!ValidDataType((Int32)dataType)) return BAD_DATA_TYPE;
*numBytes = (long) CDFelemSize (dataType);
break;
}
/****************************************************************************
* rVARs_NUMDIMS_/zVAR_NUMDIMS_
* Note that inquiring the number of rVariable dimensions is allowed while
* in zMode.
****************************************************************************/
case rVARs_NUMDIMS_: {
struct CDFstruct *CDF;
long *numDims = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
*numDims = CDF->rNumDims;
break;
}
case zVAR_NUMDIMS_: {
struct CDFstruct *CDF;
long *numDimsP = va_arg (Va->ap, long *);
Logical zVar; Int32 offset, numDims;
SelectCDF (Cur->cdf, CDF)
if (!CURRENTvarSELECTED(CDF,TRUE)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,TRUE);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
if (!sX(CalcDimParms(CDF,offset,zVar,&numDims,NULL,NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
ASSIGNnotNULL (numDimsP, numDims)
break;
}
/****************************************************************************
* rVARs_DIMSIZES_/zVAR_DIMSIZES_
* Note that inquiring the rVariable dimension sizes is allowed while in
* zMode.
****************************************************************************/
case rVARs_DIMSIZES_: {
struct CDFstruct *CDF;
int dimN;
long *dimsize = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
for (dimN = 0; dimN < CDF->rNumDims; dimN++) {
dimsize[dimN] = CDF->rDimSizes[dimN];
}
break;
}
case zVAR_DIMSIZES_: {
struct CDFstruct *CDF; Logical zVar;
Int32 offset, numDims, dimSizes[CDF_MAX_DIMS];
long *dimSizesP = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
if (!CURRENTvarSELECTED(CDF,TRUE)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,TRUE);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
if (!sX(CalcDimParms(CDF,offset,zVar,&numDims,dimSizes,NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
ASSIGNnotNULLarray (dimSizesP, numDims, dimSizes)
break;
}
/****************************************************************************
* CDF_ENCODING_,
****************************************************************************/
case CDF_ENCODING_: {
struct CDFstruct *CDF;
long *encoding = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
*encoding = (long) CDF->encoding;
break;
}
/****************************************************************************
* CDF_MAJORITY_,
****************************************************************************/
case CDF_MAJORITY_: {
struct CDFstruct *CDF;
long *majority = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
*majority = BOO(CDF->rowMajor,ROW_MAJOR,COLUMN_MAJOR);
break;
}
/****************************************************************************
* CDF_FORMAT_,
****************************************************************************/
case CDF_FORMAT_: {
struct CDFstruct *CDF;
long *format = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
*format = BOO(CDF->singleFile,SINGLE_FILE,MULTI_FILE);
break;
}
/****************************************************************************
* CDF_CHECKSUM_,
****************************************************************************/
case CDF_CHECKSUM_: {
struct CDFstruct *CDF;
long *checksum = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
*checksum = CDF->checksum;
break;
}
/****************************************************************************
* CDF_COMPRESSION_
****************************************************************************/
case CDF_COMPRESSION_: {
long *cType = va_arg (Va->ap, long *); /* Compression type. */
long *cParms = va_arg (Va->ap, long *); /* Compression parameters. */
long *cPct = va_arg (Va->ap, long *); /* Compression percentage. */
struct CDFstruct *CDF; struct CCRstruct CCR; struct CPRstruct CPR;
int i; long cTotal, uTotal;
SelectCDF (Cur->cdf, CDF)
/**************************************************************************
* If multi-file or uncompressed...
**************************************************************************/
if (!CDF->singleFile || CDF->uDotFp == NULL) {
*cType = NO_COMPRESSION;
*cPct = 100;
break;
}
/**************************************************************************
* ...otherwise, read the CCR and CPR.
**************************************************************************/
if (!sX(ReadCCR(CDF->dotFp,V2_CCR_OFFSET,
CCR_RECORD,&CCR,
CCR_NULL),&pStatus)) return pStatus;
if (!sX(ReadCPR(CDF->dotFp,CCR.CPRoffset,
CPR_RECORD,&CPR,
CPR_NULL),&pStatus)) return pStatus;
*cType = CPR.cType;
if (CPR.pCount > CDF_MAX_PARMS) return TOO_MANY_PARMS;
for (i = 0; i < CPR.pCount; i++) cParms[i] = CPR.cParms[i];
/**************************************************************************
* Calculate the percentage. If the `uSize' field of the CCR is zero,
* then the compressed CDF is empty (and the percentage is unknown).
**************************************************************************/
if (CCR.uSize == 0)
*cPct = 0;
else {
cTotal = MAGIC_NUMBERS_SIZE + CCR.RecordSize + CPR.RecordSize;
uTotal = MAGIC_NUMBERS_SIZE + CCR.uSize;
*cPct = (100L * cTotal) / uTotal;
}
break;
}
/****************************************************************************
* CDF_COPYRIGHT_
****************************************************************************/
case CDF_COPYRIGHT_: {
struct CDFstruct *CDF;
char *copyRight = va_arg (Va->ap, char *);
SelectCDF (Cur->cdf, CDF)
if (!sX(ReadCDR(CDF->fp,CDF->CDRoffset,
CDR_COPYRIGHT,copyRight,
CDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
copyRight[CDF_COPYRIGHT_LEN] = NUL;
break;
}
/****************************************************************************
* LIB_COPYRIGHT_
****************************************************************************/
case LIB_COPYRIGHT_: {
char *copyRight = va_arg (Va->ap, char *);
CDFcopyRight (copyRight);
break;
}
/****************************************************************************
* CDF_NUMrVARS_/CDF_NUMzVARS_
* Inquire number of r/z variables. When in zMode, the number of
* rVariables is always zero (0). (Inquiring the number of rVariables
* while in zMode is one of the few legal rVariable operations).
****************************************************************************/
case CDF_NUMrVARS_:
case CDF_NUMzVARS_: {
Logical zOp = (Va->item == CDF_NUMzVARS_);
struct CDFstruct *CDF;
long *numVars = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
if (zModeON(CDF))
*numVars = BOO(zOp,CDF->NrVars + CDF->NzVars,0);
else
*numVars = BOO(zOp,CDF->NzVars,CDF->NrVars);
break;
}
/****************************************************************************
* CDF_NUMATTRS_,
****************************************************************************/
case CDF_NUMATTRS_: {
struct CDFstruct *CDF;
long *numAttrs = va_arg (Va->ap, long *);
Int32 tNumAttrs;
SelectCDF (Cur->cdf, CDF)
if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
GDR_NUMATTR,&tNumAttrs,
GDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*numAttrs = tNumAttrs;
break;
}
/****************************************************************************
* CDF_NUMgATTRS_/CDF_NUMvATTRS_
****************************************************************************/
case CDF_NUMvATTRS_:
case CDF_NUMgATTRS_: {
Logical gOp = (Va->item == CDF_NUMgATTRS_);
struct CDFstruct *CDF;
long *numAttrs = va_arg (Va->ap, long *);
Int32 totalAttrs, offset, scope;
int attrX;
SelectCDF (Cur->cdf, CDF)
*numAttrs = 0;
if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
GDR_NUMATTR,&totalAttrs,
GDR_ADRHEAD,&offset,
GDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
for (attrX = 0; attrX < totalAttrs; attrX++) {
CDF->fp->CurADRIndex = attrX;
if (!sX(ReadADR(CDF->fp,offset,
ADR_SCOPE,&scope,
ADR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if ((gOp && GLOBALscope(scope)) ||
(!gOp && VARIABLEscope(scope))) (*numAttrs)++;
if (!sX(ReadADR(CDF->fp,offset,
ADR_ADRNEXT,&offset,
ADR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
}
break;
}
/****************************************************************************
* rVARs_MAXREC_/zVARs_MAXREC_
* Maximum record number of all of the rVariables/zVariables. Note that
* inquiring the maximum rVariable record number is allowed while in zMode.
****************************************************************************/
case rVARs_MAXREC_: {
struct CDFstruct *CDF;
long *maxRec = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
if (zModeON(CDF))
*maxRec = NO_RECORD;
else
*maxRec = CDF->rMaxRec;
break;
}
case zVARs_MAXREC_: {
struct CDFstruct *CDF;
long *maxRec = va_arg (Va->ap, long *);
Int32 offset, tMaxRec;
SelectCDF (Cur->cdf, CDF)
/**************************************************************************
* If zMode is on, consider both rVariables and zVariables. If zMode is
* not on, only consider the zVariables. Because zVariables did not exist
* in CDF V2.0, the problem with the `VDRnext' offset in the last VDR does
* not have to be considered here.
**************************************************************************/
*maxRec = BOO(zModeON(CDF),CDF->rMaxRec,NO_RECORD);
if (!sX(ReadGDR(CDF->fp,CDF->GDRoffset,
GDR_zVDRHEAD,&offset,
GDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
while (offset != ZERO_OFFSET) {
if (!sX(ReadVDR(CDF,CDF->fp,offset,TRUE,
VDR_MAXREC,&tMaxRec,
VDR_VDRNEXT,&offset,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*maxRec = MAXIMUM (*maxRec, tMaxRec);
}
break;
}
/****************************************************************************
* CDF_VERSION_,
****************************************************************************/
case CDF_VERSION_: {
struct CDFstruct *CDF;
long *version = va_arg (Va->ap, long *);
Int32 tVersion;
SelectCDF (Cur->cdf, CDF)
if (!sX(ReadCDR(CDF->fp,CDF->CDRoffset,
CDR_VERSION,&tVersion,
CDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*version = tVersion;
break;
}
/****************************************************************************
* CDF_RELEASE_,
****************************************************************************/
case CDF_RELEASE_: {
struct CDFstruct *CDF;
long *release = va_arg (Va->ap, long *);
Int32 tRelease;
SelectCDF (Cur->cdf, CDF)
if (!sX(ReadCDR(CDF->fp,CDF->CDRoffset,
CDR_RELEASE,&tRelease,
CDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*release = tRelease;
break;
}
/****************************************************************************
* CDF_INCREMENT_,
****************************************************************************/
case CDF_INCREMENT_: {
struct CDFstruct *CDF;
long *increment = va_arg (Va->ap, long *);
Int32 tIncrement;
SelectCDF (Cur->cdf, CDF)
if (!sX(ReadCDR(CDF->fp,CDF->CDRoffset,
CDR_INCREMENT,&tIncrement,
CDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*increment = tIncrement;
break;
}
/****************************************************************************
* LIB_VERSION_,
****************************************************************************/
case LIB_VERSION_: {
long *version = va_arg (Va->ap, long *);
*version = CDF_LIBRARY_VERSION;
break;
}
/****************************************************************************
* LIB_RELEASE_,
****************************************************************************/
case LIB_RELEASE_: {
long *release = va_arg (Va->ap, long *);
*release = CDF_LIBRARY_RELEASE;
break;
}
/****************************************************************************
* LIB_INCREMENT_,
****************************************************************************/
case LIB_INCREMENT_: {
long *increment = va_arg (Va->ap, long *);
*increment = CDF_LIBRARY_INCREMENT;
break;
}
/****************************************************************************
* LIB_subINCREMENT_,
****************************************************************************/
case LIB_subINCREMENT_: {
char *subincrement = va_arg (Va->ap, char *);
*subincrement = CDF_LIBRARY_subINCREMENT;
break;
}
/****************************************************************************
* rVAR_NAME_/zVAR_NAME_
* Note that a temporary variable is used when reading the variable name.
* This is because the caller may have only allocated enough memory for the
* size name they expect (ie., less than CDF_VAR_NAME_LEN characters). Since
* the variable name is NUL-terminated in the CDF, only the actual characters
* of the name will be copied to the caller's buffer.
****************************************************************************/
case rVAR_NAME_:
case zVAR_NAME_: {
Logical zOp = (Va->item == zVAR_NAME_), zVar;
struct CDFstruct *CDF;
char *varName = va_arg (Va->ap, char *), tName[CDF_VAR_NAME_LEN+1];
Int32 offset;
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_NAME,tName,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
strcpyX (varName, tName, CDF_VAR_NAME_LEN);
break;
}
/****************************************************************************
* rVAR_DATATYPE_/zVAR_DATATYPE_
* If this for an rVarible named "EPOCH" in a CDF prior to CDF V2.1.1,
* then return the CDF_EPOCH data type if the actual data type is CDF_REAL8
* or CDF_DOUBLE. (The CDF_EPOCH data type was not introduced until CDF
* V2.1.1). Note that only rVariables were supported prior to CDF V2.3.
****************************************************************************/
case rVAR_DATATYPE_:
case zVAR_DATATYPE_: {
Logical zOp = (Va->item == zVAR_DATATYPE_), zVar;
struct CDFstruct *CDF;
long *dataType = va_arg (Va->ap, long *);
Int32 tDataType, offset;
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_DATATYPE,&tDataType,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (!zVar && CDF->fakeEPOCH) {
char varName[CDF_VAR_NAME_LEN+1];
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_NAME,varName,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (!strcmpITB(varName,"EPOCH") && FLOAT8dataType(tDataType)) {
tDataType = CDF_EPOCH;
} else if (!strcmpITB(varName,"EPOCH") && FLOAT16dataType(tDataType)) {
tDataType = CDF_EPOCH16;
}
}
*dataType = tDataType;
break;
}
/****************************************************************************
* rVAR_NUMELEMS_/zVAR_NUMELEMS_,
****************************************************************************/
case rVAR_NUMELEMS_:
case zVAR_NUMELEMS_: {
Logical zOp = (Va->item == zVAR_NUMELEMS_), zVar;
struct CDFstruct *CDF;
long *numElements = va_arg (Va->ap, long *);
Int32 offset, tNumElems;
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_NUMELEMS,&tNumElems,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*numElements = tNumElems;
break;
}
/****************************************************************************
* rVAR_RECVARY_/zVAR_RECVARY_,
****************************************************************************/
case rVAR_RECVARY_:
case zVAR_RECVARY_: {
Logical zOp = (Va->item == zVAR_RECVARY_), zVar;
struct CDFstruct *CDF;
long *recVary = va_arg (Va->ap, long *);
Int32 flags, offset;
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_FLAGS,&flags,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*recVary = BOO(RECvaryBITset(flags),VARY,NOVARY);
break;
}
/****************************************************************************
* rVAR_DIMVARYS_/zVAR_DIMVARYS_,
****************************************************************************/
case rVAR_DIMVARYS_:
case zVAR_DIMVARYS_: {
Logical zOp = (Va->item == zVAR_DIMVARYS_), zVar;
struct CDFstruct *CDF; Int32 offset, numDims, dimVarys[CDF_MAX_DIMS];
long *dimVarysP = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
if (!sX(CalcDimParms(CDF,offset,zVar,&numDims,NULL,dimVarys),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
ASSIGNnotNULLarray (dimVarysP, numDims, dimVarys)
break;
}
/****************************************************************************
* rVAR_MAXREC_/zVAR_MAXREC_,
****************************************************************************/
case rVAR_MAXREC_:
case zVAR_MAXREC_: {
Logical zOp = (Va->item == zVAR_MAXREC_), zVar;
struct CDFstruct *CDF; Int32 offset, tMaxRec;
long *maxRec = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_MAXREC,&tMaxRec,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*maxRec = (long) tMaxRec;
break;
}
/****************************************************************************
* rVAR_MAXallocREC_/zVAR_MAXallocREC_,
****************************************************************************/
case rVAR_MAXallocREC_:
case zVAR_MAXallocREC_: {
Logical zOp = (Va->item == zVAR_MAXallocREC_), zVar;
struct CDFstruct *CDF;
Int32 offset, maxRec, lastAllocatedRecN;
long *maxAllocated = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
/**************************************************************************
* If a single-file CDF, pass back the maximum record number allocated.
* If a multi-file CDF, pass back the maximum record number written (which
* will always be the maximum record allocated).
**************************************************************************/
if (CDF->singleFile) {
if (!sX(LastRecord(CDF,offset,zVar,&lastAllocatedRecN),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*maxAllocated = lastAllocatedRecN;
}
else {
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_MAXREC,&maxRec,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*maxAllocated = (long) maxRec;
}
break;
}
/****************************************************************************
* rVAR_NUMRECS_/zVAR_NUMRECS_,
****************************************************************************/
case rVAR_NUMRECS_:
case zVAR_NUMRECS_: {
Logical zOp = (Va->item == zVAR_NUMRECS_), zVar; struct VarStruct *Var;
struct CDFstruct *CDF; Int32 vdrOffset, nRecords; int vType;
Int32 tMaxRec;
long *nRecordsP = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) vdrOffset = CDF->CURzVarOffset;
else vdrOffset = CDF->CURrVarOffset;
if (zModeON(CDF))
if (CDF->CURzVarNum < CDF->NrVars)
Var = CDF->rVars[(int)CDF->CURzVarNum];
else
Var = CDF->zVars[(int)(CDF->CURzVarNum - CDF->NrVars)];
else
Var = BOO(zOp,CDF->zVars[(int)CDF->CURzVarNum],
CDF->rVars[(int)CDF->CURrVarNum]);
if (!sX(ReadVDR(CDF,CDF->fp,vdrOffset,zVar,
VDR_MAXREC,&tMaxRec,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (!sX(VariableType(CDF,vdrOffset,zVar,&vType),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
/**************************************************************************
* Depending on the variable type...
**************************************************************************/
switch (vType) {
case SPARSE_RECORDS_:
if (!sX(IndexingStatistics(CDF,vdrOffset,zVar,
NULL,NULL,NULL,
&nRecords,NULL),&pStatus)) return pStatus;
if (Var != NULL) {
if (Var->stage.areaOffset != NO_OFFSET &&
Var->stage.firstRec != NO_RECORD) {
Int32 tmp = (Var->stage.lastRec > tMaxRec ? tMaxRec : Var->stage.lastRec);
nRecords += (tmp - Var->stage.firstRec + 1);
}
}
break;
case COMPRESSED_:
case SPARSE_COMPRESSED_RECORDS_:
if (!sX(IndexingStatistics(CDF,vdrOffset,zVar,
NULL,NULL,NULL,
&nRecords,NULL),&pStatus)) return pStatus;
if (Var != NULL) {
if (Var->stage.areaOffset != NO_OFFSET &&
Var->stage.firstRec != NO_RECORD &&
Var->stage.dotOffset == NO_OFFSET) {
Int32 tmp = (Var->stage.lastRec > tMaxRec ? tMaxRec : Var->stage.lastRec);
nRecords += (tmp - Var->stage.firstRec + 1);
}
}
break;
case SPARSE_ARRAYS_:
case SPARSE_RECORDS_AND_ARRAYS_:
return CDF_INTERNAL_ERROR;
case STANDARD_:
case IN_MULTI_: {
Int32 maxRec;
if (!sX(ReadVDR(CDF,CDF->fp,vdrOffset,zVar,
VDR_MAXREC,&maxRec,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
nRecords = maxRec + 1;
break;
}
}
ASSIGNnotNULL (nRecordsP, nRecords)
break;
}
/****************************************************************************
* rVAR_NUMallocRECS_/zVAR_NUMallocRECS_,
****************************************************************************/
case rVAR_NUMallocRECS_:
case zVAR_NUMallocRECS_: {
Logical zOp = (Va->item == zVAR_NUMallocRECS_), zVar;
struct CDFstruct *CDF; Int32 offset, nAllocated; int vType;
long *nAllocatedP = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (!sX(VariableType(CDF,offset,zVar,&vType),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
/**************************************************************************
* Depending on the variable type...
**************************************************************************/
switch (vType) {
case STANDARD_:
case SPARSE_RECORDS_:
case COMPRESSED_:
case SPARSE_COMPRESSED_RECORDS_:
case SPARSE_ARRAYS_:
case SPARSE_RECORDS_AND_ARRAYS_:
if (!sX(IndexingStatistics(CDF,offset,
zVar,NULL,NULL,
&nAllocated,
NULL,NULL),&pStatus)) return pStatus;
break;
case IN_MULTI_: {
Int32 maxRec;
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_MAXREC,&maxRec,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
nAllocated = maxRec + 1;
break;
}
}
ASSIGNnotNULL (nAllocatedP, nAllocated)
break;
}
/****************************************************************************
* rVAR_ALLOCATEDFROM_/zVAR_ALLOCATEDFROM_
* Determines the next allocated record AT or AFTER `startRec' (meaning that
* `startRec' could be the record number returned).
****************************************************************************/
case rVAR_ALLOCATEDFROM_:
case zVAR_ALLOCATEDFROM_: {
Logical zOp = (Va->item == zVAR_ALLOCATEDFROM_), zVar, found;
struct CDFstruct *CDF; Int32 offset, nextRec;
Int32 startRec = (Int32) va_arg (Va->ap, long);
long *fromRec = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
if (startRec <= NO_RECORD) return BAD_REC_NUM;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
if (!sX(NextRecord(CDF,offset,zVar,startRec,&nextRec,&found),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (!found) return NO_SUCH_RECORD;
*fromRec = (long) nextRec;
break;
}
/****************************************************************************
* rVAR_ALLOCATEDTO_/zVAR_ALLOCATEDTO_
* Determines the last record (before the next unallocated record) allocated
* AT or AFTER `startRec'. This can span non-contiguous blocks of records.
****************************************************************************/
case rVAR_ALLOCATEDTO_:
case zVAR_ALLOCATEDTO_: {
Logical zOp = (Va->item == zVAR_ALLOCATEDTO_), zVar, found;
struct CDFstruct *CDF; Int32 vdrOffset, lastRec;
Int32 startRec = (Int32) va_arg (Va->ap, long);
long *toRec = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
if (startRec <= NO_RECORD) return BAD_REC_NUM;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) vdrOffset = CDF->CURzVarOffset;
else vdrOffset = CDF->CURrVarOffset;
/**************************************************************************
* Determine the last record in the block containing the starting record.
**************************************************************************/
if (!sX(SearchForRecord(CDF,vdrOffset,zVar,startRec,
NULL,&lastRec,NULL,&found),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (!found) return NO_SUCH_RECORD;
/**************************************************************************
* Keep searching until an unallocated record is encountered.
**************************************************************************/
while (found) {
Int32 nextRec = (Int32) (lastRec + 1);
if (!sX(SearchForRecord(CDF,vdrOffset,zVar,nextRec,
NULL,&lastRec,NULL,&found),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
}
/**************************************************************************
* Return the last allocated record detected.
**************************************************************************/
*toRec = (long) lastRec;
break;
}
/****************************************************************************
* rVAR_COMPRESSION_/zVAR_COMPRESSION_
****************************************************************************/
case rVAR_COMPRESSION_:
case zVAR_COMPRESSION_: {
Logical zOp = (Va->item == zVAR_COMPRESSION_), zVar;
struct CDFstruct *CDF; /* struct VarStruct *Var; */ struct CPRstruct CPR;
Int32 VDRoffset, PRoffset, flags; int parmN;
long *cType = va_arg (Va->ap, long *); /* Compression type. */
long *cParms = va_arg (Va->ap, long *); /* Compression parameters. */
long *cPct = va_arg (Va->ap, long *); /* Compression percentage. */
/**************************************************************************
* Select/validate/locate CDF and variable.
**************************************************************************/
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) VDRoffset = CDF->CURzVarOffset;
else VDRoffset = CDF->CURrVarOffset;
/**************************************************************************
* Read fields from VDR.
**************************************************************************/
if (!sX(ReadVDR(CDF,CDF->fp,VDRoffset,zVar,
VDR_FLAGS,&flags,
VDR_CPRorSPR,&PRoffset,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
/**************************************************************************
* If the compression bit is set, read the CPR.
**************************************************************************/
if (VARcompressionBITset(flags)) {
if (!sX(ReadCPR(CDF->fp,PRoffset,
CPR_RECORD,&CPR,
CPR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*cType = CPR.cType;
for (parmN = 0; parmN < CPR.pCount; parmN++) {
cParms[parmN] = CPR.cParms[parmN];
}
if (!sX(CalcCompressionPct(CDF,VDRoffset,zVar,cPct),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
}
else {
*cType = NO_COMPRESSION;
*cPct = 100;
}
break;
}
/****************************************************************************
* rVAR_SPARSEARRAYS_/zVAR_SPARSEARRAYS_
****************************************************************************/
case rVAR_SPARSEARRAYS_:
case zVAR_SPARSEARRAYS_: {
Logical zOp = (Va->item == zVAR_SPARSEARRAYS_), zVar;
struct CDFstruct *CDF; /* struct VarStruct *Var; */ struct SPRstruct SPR;
Int32 VDRoffset, PRoffset, flags; int parmN;
long *sArraysType = va_arg (Va->ap, long *); /* Sparseness type. */
long *sArraysParms = va_arg (Va->ap, long *); /* Sparseness parameters. */
long *sArraysPct = va_arg (Va->ap, long *); /* Sparseness percentage. */
/**************************************************************************
* Select/validate/locate CDF and variable.
**************************************************************************/
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) VDRoffset = CDF->CURzVarOffset;
else VDRoffset = CDF->CURrVarOffset;
/**************************************************************************
* Read fields from VDR.
**************************************************************************/
if (!sX(ReadVDR(CDF,CDF->fp,VDRoffset,zVar,
VDR_FLAGS,&flags,
VDR_CPRorSPR,&PRoffset,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
/**************************************************************************
* If the sparse arrays bit is set, read the SPR.
**************************************************************************/
if (SPARSEarraysBITset(flags)) {
if (!sX(ReadSPR(CDF->fp,PRoffset,
SPR_RECORD,&SPR,
SPR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*sArraysType = SPR.sArraysType;
for (parmN = 0; parmN < SPR.pCount; parmN++) {
sArraysParms[parmN] = SPR.sArraysParms[parmN];
}
*sArraysPct = 100;
}
else {
*sArraysType = NO_SPARSEARRAYS;
*sArraysPct = 100;
}
break;
}
/****************************************************************************
* rVAR_SPARSERECORDS_/zVAR_SPARSERECORDS_
****************************************************************************/
case rVAR_SPARSERECORDS_:
case zVAR_SPARSERECORDS_: {
Logical zOp = (Va->item == zVAR_SPARSERECORDS_), zVar;
struct CDFstruct *CDF; /* struct VarStruct *Var; */
Int32 VDRoffset, sRecords;
long *sRecordsType = va_arg (Va->ap, long *);
/**************************************************************************
* Select/validate/locate CDF and variable.
**************************************************************************/
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) VDRoffset = CDF->CURzVarOffset;
else VDRoffset = CDF->CURrVarOffset;
/**************************************************************************
* Read sparse records field from VDR.
**************************************************************************/
if (!sX(ReadVDR(CDF,CDF->fp,VDRoffset,zVar,
VDR_sRECORDS,&sRecords,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*sRecordsType = sRecords;
break;
}
/****************************************************************************
* rVAR_NUMBER_/zVAR_NUMBER_
* Determines the variable number for a specified variable name.
****************************************************************************/
case rVAR_NUMBER_:
case zVAR_NUMBER_: {
Logical zOp = (Va->item == zVAR_NUMBER_), zVar;
struct CDFstruct *CDF;
char *varName = va_arg (Va->ap, char *);
long *varNum = va_arg (Va->ap, long *);
Int32 varN, offset;
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
tStatus = FindVarByName (CDF, varName, &offset, &zVar, NULL);
switch (tStatus) {
case CDF_OK:
break;
case NO_SUCH_VAR:
return tStatus;
default:
if (!sX(tStatus,&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return tStatus;
}
}
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_NUM,&varN,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (zModeON(CDF))
*varNum = BOO(zVar,CDF->NrVars,0) + varN;
else
if (zOp)
if (zVar)
*varNum = varN;
else
return NO_SUCH_VAR; /* Wrong type of variable. */
else
if (zVar)
return NO_SUCH_VAR; /* Wrong type of variable. */
else
*varNum = varN;
break;
}
/****************************************************************************
* rVAR_BLOCKINGFACTOR_/zVAR_BLOCKINGFACTOR_,
****************************************************************************/
case rVAR_BLOCKINGFACTOR_:
case zVAR_BLOCKINGFACTOR_: {
Logical zOp = (Va->item == zVAR_BLOCKINGFACTOR_), zVar;
struct CDFstruct *CDF;
long *nExtendRecs = va_arg (Va->ap, long *);
Int32 tRecs, offset;
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_BLOCKING,&tRecs,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*nExtendRecs = tRecs;
break;
}
/****************************************************************************
* rVAR_nINDEXRECORDS_/zVAR_nINDEXRECORDS_,
* rVAR_nINDEXENTRIES_/zVAR_nINDEXENTRIES_,
* rVAR_nINDEXLEVELS_/zVAR_nINDEXLEVELS_,
****************************************************************************/
case rVAR_nINDEXRECORDS_:
case zVAR_nINDEXRECORDS_:
case rVAR_nINDEXENTRIES_:
case zVAR_nINDEXENTRIES_:
case rVAR_nINDEXLEVELS_:
case zVAR_nINDEXLEVELS_: {
Logical zOp = (Va->item == zVAR_nINDEXRECORDS_ ||
Va->item == zVAR_nINDEXENTRIES_ ||
Va->item == zVAR_nINDEXLEVELS_), zVar;
struct CDFstruct *CDF; Int32 offset, count;
long *countP = va_arg (Va->ap, long *);
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
/**************************************************************************
* If a multi-file CDF, pass back a count of zero (0) and an info/warning
* status code. If a single-file CDF, scan through the linked list of VXRs
* counting the parameter requested.
**************************************************************************/
if (!CDF->singleFile) {
count = 0;
sX (MULTI_FILE_FORMAT, &pStatus);
}
else {
switch (Va->item) {
case rVAR_nINDEXRECORDS_:
case zVAR_nINDEXRECORDS_:
if (!sX(IndexingStatistics(CDF,offset,zVar,
&count,NULL,NULL,
NULL,NULL),&pStatus)) return pStatus;
break;
case rVAR_nINDEXENTRIES_:
case zVAR_nINDEXENTRIES_:
if (!sX(IndexingStatistics(CDF,offset,zVar,
NULL,&count,NULL,
NULL,NULL),&pStatus)) return pStatus;
break;
case rVAR_nINDEXLEVELS_:
case zVAR_nINDEXLEVELS_:
if (!sX(IndexingStatistics(CDF,offset,zVar,
NULL,NULL,NULL,
NULL,&count),&pStatus)) return pStatus;
break;
}
}
ASSIGNnotNULL (countP, count)
break;
}
/****************************************************************************
* rVAR_PADVALUE_/zVAR_PADVALUE_
****************************************************************************/
case rVAR_PADVALUE_:
case zVAR_PADVALUE_: {
Logical zOp = (Va->item == zVAR_PADVALUE_), zVar;
struct CDFstruct *CDF;
void *padValue = va_arg (Va->ap, void *);
Int32 offset, dataType, numElems, flags;
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
zVar = CurrentVarMode(CDF,zOp);
if (zModeON(CDF) || zVar) offset = CDF->CURzVarOffset;
else offset = CDF->CURrVarOffset;
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_FLAGS,&flags,
VDR_DATATYPE,&dataType,
VDR_NUMELEMS,&numElems,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
/**********************************************************************
The length of the pad value for a CDF_CHAR variable is the
length of the variable (i.e. CHAR/162, etc.). If the length
of the pad value is greater than 16, it causes segmentation fault
for the IDL CDF interface routine.
***********************************************************************/
if (dataType == CDF_CHAR || dataType == CDF_UCHAR)
numElems = 1;
if (PADvalueBITset(flags)) {
if (!sX(ReadVDR(CDF,CDF->fp,offset,zVar,
VDR_PADVALUE,padValue,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (!sX(ConvertBuffer(CDF->encoding,CDF->decoding,
CDF->negToPosFp0,dataType,
numElems,padValue,padValue),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
}
else {
DefaultPadValue (dataType, numElems, padValue);
if (!sX(ConvertBuffer(HostEncoding(),CDF->decoding,
CDF->negToPosFp0,dataType,
numElems,padValue,padValue),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
sX (NO_PADVALUE_SPECIFIED, &pStatus);
}
break;
}
/****************************************************************************
* rVAR_DATA_/zVAR_DATA_,
****************************************************************************/
case rVAR_DATA_:
case zVAR_DATA_: {
Logical zOp = (Va->item == zVAR_DATA_);
struct CDFstruct *CDF; struct VarStruct *Var;
Int32 phyRecNum, offset; struct rdSTRUCT *rd;
char *value = va_arg (Va->ap, char *);
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
if (!sX(InitCurrentVar(CDF,zOp,&Var),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
rd = BOO(zModeON(CDF),&(Var->zRD),BOO(zOp,&(Var->zRD),&(CDF->rRD)));
if (!CDF->singleFile && Var->fp == NULL) {
if (!sX(OpenVar(CDF,Var),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
}
phyRecNum = BOO(Var->recVary,rd->recNumber,0);
offset = IndicesValueOffset(Var->numDims,
rd->dimIndices,
Var->dimVarys,
Var->nPhyDimValues) * Var->NvalueBytes;
if (!sX(ReadVarValues(CDF,Var,phyRecNum,
offset,INT32_ONE,value),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
Var->accessed_at = CDF->pseudo_clock++;
break;
}
/****************************************************************************
* rVAR_HYPERDATA_/zVAR_HYPERDATA_,
****************************************************************************/
case rVAR_HYPERDATA_:
case zVAR_HYPERDATA_: {
Logical zOp = (Va->item == zVAR_HYPERDATA_);
struct CDFstruct *CDF;
struct VarStruct *Var;
int dimN;
struct rdSTRUCT *rd;
#if LIMITof64K
long Nvalues, Nbytes;
#endif
char *buffer = va_arg (Va->ap, char *);
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
if (!sX(InitCurrentVar(CDF,zOp,&Var),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
rd = BOO(zModeON(CDF),&(Var->zRD),BOO(zOp,&(Var->zRD),&(CDF->rRD)));
for (dimN = 0; dimN < Var->numDims; dimN++) {
long maxIndex = rd->dimIndices[dimN] +
((rd->dimCounts[dimN] - 1) * rd->dimIntervals[dimN]);
if (maxIndex >= Var->dimSizes[dimN]) return BAD_DIM_INDEX;
}
#if LIMITof64K
Nvalues = rd->recCount;
for (dimN = 0; dimN < Var->numDims; dimN++) Nvalues *= rd->dimCounts[dimN];
Nbytes = Nvalues * Var->NvalueBytes;
if (TOObigIBMpc(Nbytes)) return IBM_PC_OVERFLOW;
#endif
if (!CDF->singleFile && Var->fp == NULL) {
if (!sX(OpenVar(CDF,Var),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
}
if (!sX(HyperRead(CDF,Var,rd,buffer),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
Var->accessed_at = CDF->pseudo_clock++;
break;
}
/****************************************************************************
* rVAR_SEQDATA_/zVAR_SEQDATA_,
****************************************************************************/
case rVAR_SEQDATA_:
case zVAR_SEQDATA_: {
Logical zOp = (Va->item == zVAR_SEQDATA_);
struct CDFstruct *CDF; struct VarStruct *Var; Int32 recNum, offset;
void *value = va_arg (Va->ap, char *);
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (!CURRENTvarSELECTED(CDF,zOp)) return NO_VAR_SELECTED;
if (!sX(InitCurrentVar(CDF,zOp,&Var),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (!CDF->singleFile && Var->fp == NULL) {
if (!sX(OpenVar(CDF,Var),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
}
recNum = Var->seqValueOffset / Var->NphyRecValues;
if (recNum > Var->maxRec) return END_OF_VAR;
offset = (Var->seqValueOffset % Var->NphyRecValues) * Var->NvalueBytes;
if (!sX(ReadVarValues(CDF,Var,recNum,offset,INT32_ONE,value),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
Var->seqValueOffset++;
Var->accessed_at = CDF->pseudo_clock++;
break;
}
/****************************************************************************
* rVARs_RECDATA_/zVARs_RECDATA_
* Read data records for up to all of the rVariables/zVariables.
****************************************************************************/
case rVARs_RECDATA_:
case zVARs_RECDATA_: {
Logical zOp = (Va->item == zVARs_RECDATA_), zVar;
struct VarStruct *Var; struct CDFstruct *CDF;
Int32 recNum, varNt; Byte *tBuffer; int varX;
long nVars = va_arg (Va->ap, long);
long *varNs = va_arg (Va->ap, long *);
void *buffer = va_arg (Va->ap, char *);
#if LIMITof64K
long nBytes;
#endif
SelectCDF (Cur->cdf, CDF)
if (BADzOP(CDF,!zOp)) return ILLEGAL_IN_zMODE;
if (nVars < 1) return BAD_NUM_VARS;
for (varX = 0; varX < nVars; varX++) {
if (!sX(VarIdentity(CDF,(Int32)varNs[varX],
zOp,&varNt,&zVar,NULL),&pStatus)) {
return pStatus;
}
if (!sX(InitVar(CDF,varNt,zVar,NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
}
#if LIMITof64K
for (varX = 0, nBytes = 0; varX < nVars; varX++) {
if (!sX(VarIdentity(CDF,varNs[varX],zOp,NULL,NULL,&Var),&pStatus)) {
return pStatus;
}
nBytes += Var->NphyRecBytes;
}
if (TOObigIBMpc(nBytes)) return IBM_PC_OVERFLOW;
#endif
for (varX = 0, tBuffer = buffer; varX < nVars; varX++) {
if (!sX(VarIdentity(CDF,(Int32)varNs[varX],
zOp,NULL,NULL,&Var),&pStatus)) {
return pStatus;
}
if (!CDF->singleFile && Var->fp == NULL) {
if (!sX(OpenVar(CDF,Var),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
}
recNum = BOO(Var->recVary,BOO(zOp,Var->zRD.recNumber,
CDF->rRD.recNumber),0);
if (!sX(ReadVarValues(CDF,Var,recNum,INT32_ZERO,
Var->NphyRecValues,tBuffer),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
tBuffer += (size_t) Var->NphyRecBytes;
Var->accessed_at = CDF->pseudo_clock++;
}
break;
}
/****************************************************************************
* ATTR_NAME_,
* Note that a temporary variable is used when reading the attribute name.
* This is because the caller may have only allocated enough memory for the
* size name they expect (ie., less than CDF_ATTR_NAME_LEN characters). Since
* the attribute name is NUL-terminated in the CDF, only the actual characters
* of the name will be copied to the caller's buffer.
****************************************************************************/
case ATTR_NAME_: {
struct CDFstruct *CDF;
char *attrName = va_arg (Va->ap, char *), tName[CDF_ATTR_NAME_LEN+1];
SelectCDF (Cur->cdf, CDF)
if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
ADR_NAME,tName,
ADR_NULL),&pStatus)){
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
strcpyX (attrName, tName, CDF_ATTR_NAME_LEN);
break;
}
/****************************************************************************
* ATTR_NUMBER_,
****************************************************************************/
case ATTR_NUMBER_: {
struct CDFstruct *CDF;
char *attrName = va_arg (Va->ap, char *);
long *attrNum = va_arg (Va->ap, long *);
Int32 attrNumT, offset;
SelectCDF (Cur->cdf, CDF)
tStatus = FindAttrByName (CDF, attrName, &offset);
switch (tStatus) {
case CDF_OK:
break;
case NO_SUCH_ATTR:
return tStatus;
default:
if (!sX(tStatus,&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return tStatus;
}
}
if (!sX(ReadADR(CDF->fp,offset,
ADR_NUM,&attrNumT,
ADR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*attrNum = attrNumT;
break;
}
/****************************************************************************
* ATTR_SCOPE_,
****************************************************************************/
case ATTR_SCOPE_: {
struct CDFstruct *CDF;
long *scope = va_arg (Va->ap, long *);
Int32 tScope;
SelectCDF (Cur->cdf, CDF)
if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
ADR_SCOPE,&tScope,
ADR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
*scope = DEFINITEscope(tScope);
break;
}
/****************************************************************************
* ATTR_MAXgENTRY_/ATTR_MAXrENTRY_/ATTR_MAXzENTRY_
* ATTR_NUMgENTRIES_/ATTR_NUMrENTRIES_/ATTR_NUMzENTRIES_
****************************************************************************/
case ATTR_MAXgENTRY_:
case ATTR_NUMgENTRIES_:
case ATTR_MAXrENTRY_:
case ATTR_NUMrENTRIES_:
case ATTR_MAXzENTRY_:
case ATTR_NUMzENTRIES_: {
Logical maxOp = ONEof3(Va->item,ATTR_MAXgENTRY_,
ATTR_MAXrENTRY_,
ATTR_MAXzENTRY_);
int entryType = BOO(maxOp,E3p(Va->item,ATTR_MAXgENTRY_,
ATTR_MAXrENTRY_,
ATTR_MAXzENTRY_),
E3p(Va->item,ATTR_NUMgENTRIES_,
ATTR_NUMrENTRIES_,
ATTR_NUMzENTRIES_));
struct CDFstruct *CDF;
long *value = va_arg (Va->ap, long *);
Int32 scope, gr, z;
SelectCDF (Cur->cdf, CDF)
if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
ADR_SCOPE,&scope,
ADR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (GLOBALscope(scope)) {
if (entryType != gENTRYt) return ILLEGAL_FOR_SCOPE;
}
else {
if (entryType == gENTRYt) return ILLEGAL_FOR_SCOPE;
}
if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
BOO(maxOp,ADR_MAXgrENTRY,ADR_NgrENTRIES),&gr,
BOO(maxOp,ADR_MAXzENTRY,ADR_NzENTRIES),&z,
ADR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (GLOBALscope(scope))
*value = (long) gr;
else
if (zModeON(CDF))
if (entryType == rENTRYt)
*value = (long) BOO(maxOp,NO_ENTRY,0);
/* Never any rEntries in zMode. */
else
*value = (long) BOO(maxOp,BOO(z > NO_ENTRY,CDF->NrVars+z,gr),gr+z);
else
*value = (long) E3(entryType,BOO(maxOp,NO_ENTRY,0),gr,z);
break;
}
/****************************************************************************
* gENTRY_DATATYPE_/rENTRY_DATATYPE_/zENTRY_DATATYPE_
* gENTRY_NUMELEMS_/rENTRY_NUMELEMS_/zENTRY_NUMELEMS_
* If this CDF is prior to CDF V2.1.1, the current attribute is named
* "VALIDMIN", "VALIDMAX", "SCALEMIN", or "SCALEMAX", this is a true rEntry,
* and the rEntry corresponds to an rVariable named "EPOCH", then return
* the CDF_EPOCH data type if the actual data type is CDF_REAL8 or CDF_DOUBLE.
* (The CDF_EPOCH data type was not introduced until CDF V2.1.1). Note that
* only rVariables were supported prior to CDF V2.3.
****************************************************************************/
case gENTRY_DATATYPE_:
case gENTRY_NUMELEMS_:
case rENTRY_DATATYPE_:
case rENTRY_NUMELEMS_:
case zENTRY_DATATYPE_:
case zENTRY_NUMELEMS_: {
Logical dataOp = ONEof3(Va->item,gENTRY_DATATYPE_,
rENTRY_DATATYPE_,
zENTRY_DATATYPE_);
int entryType = BOO(dataOp,E3p(Va->item,gENTRY_DATATYPE_,
rENTRY_DATATYPE_,
zENTRY_DATATYPE_),
E3p(Va->item,gENTRY_NUMELEMS_,
rENTRY_NUMELEMS_,
zENTRY_NUMELEMS_));
struct CDFstruct *CDF;
long *value = va_arg (Va->ap, long *);
Int32 tValue, eOffset;
SelectCDF (Cur->cdf, CDF)
if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
if (E3(entryType,
CDF->CURgrEntryNum,
CDF->CURgrEntryNum,
CDF->CURzEntryNum) == RESERVED_ENTRYNUM) return NO_ENTRY_SELECTED;
if (!sX(CheckEntryOp(CDF,entryType),&pStatus)) return pStatus;
eOffset = E3(entryType,CDF->CURgrEntryOffset,
CDF->CURgrEntryOffset,
CDF->CURzEntryOffset);
if (eOffset == RESERVED_ENTRYOFFSET) return NO_SUCH_ENTRY;
if (!sX(ReadAEDR(CDF->fp,eOffset,
BOO(dataOp,AEDR_DATATYPE,AEDR_NUMELEMS),&tValue,
AEDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (dataOp && CDF->fakeEPOCH) {
char aName[CDF_ATTR_NAME_LEN+1];
if (!sX(ReadADR(CDF->fp,CDF->CURattrOffset,
ADR_NAME,aName,
ADR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (!strcmpITB(aName,"VALIDMIN") || !strcmpITB(aName,"VALIDMAX") ||
!strcmpITB(aName,"SCALEMIN") || !strcmpITB(aName,"SCALEMAX")) {
Int32 vOffset; char vName[CDF_VAR_NAME_LEN+1];
tStatus = FindVarByNumber (CDF, E3(entryType, CDF->CURgrEntryNum,
CDF->CURgrEntryNum,
CDF->CURzEntryNum),
FALSE, &vOffset);
switch (tStatus) {
case NO_SUCH_VAR:
break;
default:
if (!sX(tStatus,&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return tStatus;
}
if (!sX(ReadVDR(CDF,CDF->fp,vOffset,FALSE,
VDR_NAME,vName,
VDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (!strcmpITB(vName,"EPOCH") &&
FLOAT8dataType(tValue)) tValue = CDF_EPOCH;
if (!strcmpITB(vName,"EPOCH") &&
FLOAT16dataType(tValue)) tValue = CDF_EPOCH16;
break;
}
}
}
*value = tValue;
break;
}
/****************************************************************************
* gENTRY_DATA_/rENTRY_DATA_/zENTRY_DATA_,
****************************************************************************/
case gENTRY_DATA_:
case rENTRY_DATA_:
case zENTRY_DATA_: {
int entryType = E3p(Va->item,gENTRY_DATA_,rENTRY_DATA_,zENTRY_DATA_);
struct CDFstruct *CDF;
Int32 offset, dataType, numElems;
void *value = va_arg (Va->ap, void *);
SelectCDF (Cur->cdf, CDF)
if (!CURRENTattrSELECTED(CDF)) return NO_ATTR_SELECTED;
if (E3(entryType,
CDF->CURgrEntryNum,
CDF->CURgrEntryNum,
CDF->CURzEntryNum) == RESERVED_ENTRYNUM) return NO_ENTRY_SELECTED;
if (!sX(CheckEntryOp(CDF,entryType),&pStatus)) return pStatus;
offset = E3(entryType,CDF->CURgrEntryOffset,
CDF->CURgrEntryOffset,
CDF->CURzEntryOffset);
if (offset == RESERVED_ENTRYOFFSET) return NO_SUCH_ENTRY;
if (!sX(ReadAEDR(CDF->fp,offset,
AEDR_DATATYPE,&dataType,
AEDR_NUMELEMS,&numElems,
AEDR_VALUE,value,
AEDR_NULL),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
if (!sX(ConvertBuffer(CDF->encoding,CDF->decoding,
CDF->negToPosFp0,dataType,
numElems,value,value),&pStatus)) {
AbortAccess (CDF, UPDATE, noDELETE);
return pStatus;
}
break;
}
/****************************************************************************
* Unknown item, must be the next function.
****************************************************************************/
default: {
Va->fnc = Va->item;
break;
}
}
return pStatus;
}
syntax highlighted by Code2HTML, v. 0.9.1