cdfvar_attr.c 8.25 KB
/**
*  @file cdfvarinfo.c
*  @version $Id: cdfvarinfo.c,v 1.1 2010/08/31 10:32:55 budnik Exp $
*  @brief  
*/


#include <stdio.h>
#include <stdlib.h>
#include <cdf.h>
#include <string.h>

#define MAX_FILE_NAME_LEN  120  

void cdf_status_handler (CDFstatus, char *); 
char * cdf_str_datatype (long);

typedef struct cdfvar {           /* CDF variable structure */
	char name[CDF_VAR_NAME_LEN+1];   
	long datatype;                   
	long numElements;                /* string length for CDF_CHAR, 1 otherwise */
	long dimensionality;             /* variable dimensionality                 */
	long dimSizes[CDF_MAX_DIMS];     /* variable dimension sizes                */
	long recVariance;                /* record variance                         */
	long numRecs;                    /* # of records this variable contains     */
} CDFvar;

int main(int argc, char *argv[])
{
  
	CDFvar var;
	CDFid    id;                     /* CDF file ID      */ 
	CDFstatus   status;              /* CDF status code */

	long nZvars, nAttrs, attrId, attrScope, varId, datatype, numElements; 
	char attrName[CDF_ATTR_NAME_LEN+1];
	char fileName[MAX_FILE_NAME_LEN], varName[CDF_VAR_NAME_LEN+1], attName[CDF_ATTR_NAME_LEN+1];
	char msg[100];
	int dummy, i;
	char          *cPtr;
	signed char   *scPtr;
	short         *sPtr;
	int           *iPtr;
	float         *fPtr;
	double        *dPtr;
  
  
	if (argc <= 3) 
		exit(0);                          /* CDF input file name not specified */
	else {
		strcpy(fileName, argv[1]);       /* Get the input file name */
		strcpy(varName, argv[2]);
		strcpy(attName, argv[3]);
	}

	status = CDFlib (OPEN_, CDF_, fileName, &id,  NULL_);   
		
	if (status != CDF_OK)  {
			strcpy(msg, "OPEN_, CDF_, ");       
			strcat(msg, fileName);
			cdf_status_handler (status, msg);
	}
 
 /*---------------------------------------------------------------------------
 *   This routine retrievs the following information:
 *
 *      nAttr - number of attributes (including global and variable)
 *      nZvars - number of zVariables
 *
 *   CDF file can have both rVariables (old style) and zVariables (new style)
 *   simultaneously.  zVariable is a superset of rVariable, and it is a lot
 *   more efficient and offers all the functionality a rVariable offers and 
 *   more.  Treat all CDF variables as zVariables.
 *--------------------------------------------------------------------------*/ 
 
	status = CDFlib (SELECT_, CDF_zMODE_, zMODEon2,
							GET_, CDF_NUMATTRS_,  &nAttrs, 
							CDF_NUMzVARS_,  &nZvars, 
							NULL_);
	if (status != CDF_OK) cdf_status_handler(status, "GET_, CDF_FILEINFO_");
  
	// printf(" nAttrs %d Zvars %d\n",nAttrs, nZvars);   
	//  printf ("Attributes:\n");
  
	for (attrId = 0; attrId < nAttrs; attrId++) {
		status = CDFlib (SELECT_, ATTR_, attrId,
								GET_, ATTR_NAME_, attrName,  ATTR_SCOPE_, &attrScope,
								NULL_);
		
		if (status != CDF_OK) cdf_status_handler (status, "SELECT_, ATTR_");     
		//    printf("Attr %d  %s  %d\n", attrId, attrName, attrScope); 
		}
    
	//   printf ("Variables:\n"); 
	for (varId=0; varId < nZvars; varId++) 
	{      
		status = CDFlib (SELECT_,zVAR_, varId,
								GET_, zVAR_NAME_, var.name,
								zVAR_DATATYPE_, &var.datatype,
								zVAR_NUMELEMS_, &var.numElements,
								zVAR_NUMDIMS_, &var.dimensionality,
								zVAR_DIMSIZES_, var.dimSizes,
								zVAR_NUMRECS_, &var.numRecs,
								zVAR_RECVARY_, &var.recVariance,
								NULL_);   
		if (status != CDF_OK) cdf_status_handler (status, "GET_, zVARS_");
   
		if (strcmp(var.name, varName) == 0) 
		{  
			for (attrId = 0; attrId < nAttrs; attrId++) {   
				status = CDFlib (SELECT_, ATTR_, attrId,
										GET_,    ATTR_NAME_, attrName, ATTR_SCOPE_, &attrScope,
										NULL_);
 
				if (status != CDF_OK) cdf_status_handler (status, "SELECT_, ATTR_");
				if (attrScope == GLOBAL_SCOPE) continue;
				if (strcasecmp(attrName, attName) != 0) continue;
				
				// printf("%d %s ", attrId, attrName);
				
				status = CDFlib (SELECT_, zENTRY_, varId,
										GET_,    zENTRY_DATATYPE_, &datatype,
										zENTRY_NUMELEMS_, &numElements,
										NULL_);
				//printf("%d %s", numElements,cdf_str_datatype(datatype));						
				if (status == NO_SUCH_ENTRY) continue;    

				if (status != CDF_OK) cdf_status_handler (status,"GET_ATTR_INFO_");
 
				switch (datatype) 
				{
					case CDF_CHAR:
						cPtr = (char *) malloc(numElements * sizeof(char) + 1);
						
						status = CDFlib (GET_, zENTRY_DATA_, cPtr, NULL_);
						if (status != CDF_OK) cdf_status_handler (status, msg);
						strcpy(&cPtr[numElements],"\0"); 
						printf("%s\n", cPtr);       
						free(cPtr);
					break;

					case CDF_BYTE:
					case CDF_INT1:
						scPtr = (signed char *) malloc (sizeof(signed char) * numElements);				     
						status = CDFlib (GET_, zENTRY_DATA_, scPtr, NULL_);
						if (status != CDF_OK) cdf_status_handler (status, msg);				     	     
						free (scPtr);
					break;

					case CDF_INT2:
					case CDF_UCHAR:
					case CDF_UINT1:
						sPtr = (short *) malloc (sizeof(short) * numElements);				     
						status = CDFlib (GET_, zENTRY_DATA_, sPtr, NULL_);
						if (status != CDF_OK) cdf_status_handler (status, msg);
						free (sPtr);
					break;

					case CDF_INT4:
					case CDF_UINT2:
						iPtr = (int *) malloc (sizeof(int) * numElements);				    
						status = CDFlib (GET_, zENTRY_DATA_, iPtr, NULL_);
						if (status != CDF_OK) cdf_status_handler (status, msg);		
						printf("%d\n",  *iPtr); 
						free (iPtr);
					break;

					case CDF_FLOAT:
					case CDF_REAL4:
						fPtr = (float *) malloc (sizeof(float) * numElements);				     
						status = CDFlib (GET_, zENTRY_DATA_, fPtr, NULL_);
						if (status != CDF_OK) cdf_status_handler (status, msg);
						printf("%8.1e\n",  *fPtr); 
						free (fPtr);
					break;

					case CDF_DOUBLE:
					case CDF_REAL8:
					case CDF_UINT4:
						dPtr = (double *) malloc (sizeof(double) * numElements);
						
						status = CDFlib (GET_, zENTRY_DATA_, dPtr, NULL_);
						if (status != CDF_OK) cdf_status_handler (status, msg);
						printf("%8.1e\n",  *dPtr); 
						free (dPtr);
					break;

					case CDF_EPOCH:       /* 8-byte real number */ 
						dPtr = (double *) malloc (sizeof(double) * numElements);
						
						status = CDFlib (GET_, zENTRY_DATA_, dPtr, NULL_);
						if (status != CDF_OK) cdf_status_handler (status, msg);
						
						free (dPtr);
					break;

					case CDF_EPOCH16:       /* 16-byte real number */
						dPtr = (double *) malloc (sizeof(double) * numElements * 2);				     
						status = CDFlib (GET_, zENTRY_DATA_, dPtr, NULL_);
						if (status != CDF_OK) cdf_status_handler (status, msg);				      
						free (dPtr);
					break;

					default:
						printf ("** Error in get_cdf_attribute: bad data type");
				}    
			}
			break;  
		}
	}
               
	/* Close the CDF file */
	status = CDFlib (CLOSE_, CDF_, NULL_);   
     
}


void cdf_status_handler (CDFstatus status, char *source)
{
	char  message[CDF_STATUSTEXT_LEN+1];

	CDFerror (status, message);              /* Get the appropriate message */

	if (status < CDF_WARN) {
			printf ("An error has occurred, halting...\n");
			printf ("%s\n", message);
			printf ("** Error source: %s\n", source);
			exit (status);
	}
	else if (status < CDF_OK) {
			printf ("Warning, function may not have compeleted as expected...\n");
			printf ("%s\n", message);
	}
	else if (status > CDF_OK) {
			printf ("Function compeleted successfully, but be advised that...\n");
			printf ("%s\n", message);
	}   
}

/*--------------------------------------------------------------------------
 *  This routine returns the string representation of the given CDF 
 *  datatype.
 *--------------------------------------------------------------------------*/
char *  cdf_str_datatype (long type)
{
	switch (type) {
	case CDF_BYTE:
		return "CDF_BYTE";

	case CDF_INT1:
		return "CDF_INT1";

	case CDF_CHAR:
		return "CDF_CHAR";

	case CDF_INT2:
		return "CDF_INT2";

	case CDF_UCHAR:
		return "CDF_UCHAR";

	case CDF_UINT1:
		return "CDF_UINT1";

	case CDF_INT4:
		return "CDF_INT4";

	case CDF_UINT2:
		return "CDF_UINT2";

	case CDF_FLOAT:
		return "CDF_FLOAT";

	case CDF_REAL4:
		return "CDF_REAL4";

	case CDF_DOUBLE:
		return "CDF_DOUBLE";

	case CDF_REAL8:
		return "CDF_REAL8";

	case CDF_UINT4:
		return "CDF_UINT4";

	case CDF_EPOCH:
		return "CDF_EPOCH";

	case CDF_EPOCH16:
		return "CDF_EPOCH16";
	}
}