cdfvarinfo.c 9.46 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];
  char   msg[100];
  int dummy, i;
  char          *cPtr;
  signed char   *scPtr;
  short         *sPtr;
  int           *iPtr;
  float         *fPtr;
  double        *dPtr;
  
  
    if (argc <= 2) 
       exit(0);                   /* CDF input file name not specified */
    else {
        strcpy(fileName, argv[1]);       /* Get the input file name */
	strcpy(varName, argv[2]);   
    }	
	
   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) { 
	  
	                    printf("%s %d %d ", cdf_str_datatype(var.datatype), var.dimensionality, var.numRecs);
			    for (i = 0; i < var.dimensionality; i++) printf("%d ",var.dimSizes[i]);
			    printf("\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_");
			          if (attrScope == GLOBAL_SCOPE) continue;
//printf("\n%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);	
//				      printf(" %s",  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);				     
				      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);				      
				      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);
				     
				      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";
    }
}