/*****************************************************************************e
*
*  NSSDC/CDF                      Quick Start Test Program(C# interface).
*
*  Version 1.0,15-Oct-09,Mike Liu
*
*  Modification history:
*
*   V1.0   15-Oct-09,M Liu     Original version(for CDF V3.3).
*                              Using pointers (&) to pass arguments for 
*                              retrieving data fields and values to C# APIs.
*
******************************************************************************/

using System;
using System.Runtime.InteropServices;
using CDF;

public class Qst2cs : CDFAPIs {

unsafe public static void Main() {
  void* id;
  int status;

  int N_DIMS = 2;
  int DIM_0_SIZE = 2;
  int DIM_1_SIZE = 3;

  int zN_DIMSa = 1;
  int zDIM_0_SIZEa = 5;
  int zNUM_ELEMSa = 8;

  int    dim_n;
  int    encoding = IBMPC_ENCODING;
  int    actual_encoding = IBMPC_ENCODING;
  int    majority = ROW_MAJOR;
  int    numDims = N_DIMS;
  int[]  dimSizes = new int[2] { 2,3 };
  int    zNumDimsA = zN_DIMSa;
  int[]  zDimSizesA = new int[1] { 5 };
  int    var1DataType = CDF_INT2;
  int    var1DataTypeNew = CDF_UINT2;
  int    var2DataType = CDF_REAL4;
  int    var3DataType = CDF_CHAR;
  int    var3DataTypeNew = CDF_UCHAR;
  int    var1DataType_out,var2DataType_out,var3DataType_out;
  int    var1NumElements = 1;
  int    var2NumElements = 1;
  int    var3NumElements = zNUM_ELEMSa;
  int    var3NumElementsNew = zNUM_ELEMSa;
  int    var1NumElements_out,var2NumElements_out,var3NumElements_out;
  int    var1Num_out,var2Num_out,var3Num_out,varNum_out1,varNum_out2;
  short[,] var1Values = new short[2,3] {{1,2,3},{4,5,6}};
  float[,] var2Values = new float[2,3] {{1.0F,2.0F,3.0F},
                                        {4.0F,5.0F,6.0F}};
  short[,] var1Values_out = new short[2,3];
  float[,] var2Values_out = new float[2,3];
  string[] var3Values = new string[5] {
          "11111111","22222222","33333333","44444444","55555555"};
  short  var1Value_out;
  float  var2Value_out;
  string var3Value_out;
  int    recNum = 0;
  int    recNumOut;
  int    recStart = 2;
  int    recCount = 1;
  int    recInterval = 1;
  int[]  indices = new int[2];
  int[]  counts = new int[2] { 2,3 };
  int[]  intervals = new int[2] { 1,1 };
  int[]  zIndicesA = new int[1];
  int[]  zCounts = new int[1] { 5 };
  int[]  zIntervals = new int[1] { 1 };
  short[,] var1Buffer_out = new short[2,3];
  float[,] var2Buffer_out = new float[2,3];
//  string[] var3Buffer_out = new string[5];
  string[] var3Buffer_out;
  int    attrNum_out;
  int    entryNum = 2;
  int    maxEntry_out;
  int    attrScope = GLOBAL_SCOPE;
  int    attrScope2 = VARIABLE_SCOPE;
  int    attrScope3 = VARIABLE_SCOPE;
  int    attrScope_out;
  int    entryDataType = CDF_INT2;
  int    entryDataTypeNew = CDF_UINT2;
  int    entryDataType_out;
  int    entryNumElems = 1;
  int    entryNumElems_out;
  short  entryValue = 1;
  short  entryValue_out;
  int    encoding_out;
  int    majority_out;
  int[]  dimSizes_out = new int[2];
  int    zNumDimsA_out;
  int[]  zDimSizesA_out = new int[1];
  int    maxRec_out;
  int    numAttrs_out;
  int    version_out;
  int    release_out;
  int    increment_out;
  string subincrement_out;
  int    numDimsX,encodingX,majorityX,maxrRecX,nrVarsX,nAttrsX;
  int    numDimsY,encodingY,majorityY,maxrRecY,nrVarsY,nzVarsY,
         nAttrsY,maxzRecY;
  int[]  dimSizesX = new int[2],dimSizesY = new int[2];
  int    x0,x1;
  int    var1RecVariance = VARY;
  int    var1RecVarianceNew = NOVARY;
  int    var2RecVariance = VARY;
  int    var3RecVariance = VARY;
  int    var3RecVarianceNew = NOVARY;
  int    var1RecVariance_out,var2RecVariance_out,var3RecVariance_out;
  int[]  var1DimVariances = new int[2] { VARY,VARY };
  int[]  var1DimVariancesNew = new int[2] { NOVARY,NOVARY };
  int[]  var2DimVariances = new int[2] { VARY,VARY };
  int[]  var3DimVariances = new int[1] { VARY };
  int[]  var3DimVariancesNew = new int[1] { NOVARY };
  int[]  var1DimVariances_out = new int[2],
         var2DimVariances_out = new int[2],
         var3DimVariances_out = new int[1];
  string var1Name = "VAR1a";
  string var2Name = "VAR2a";
  string var3Name = "zVARa1";
  string new_var1Name = "VAR1b";
  string new_var2Name = "VAR2b";
  string new_var3Name = "zVARa2";
  string var1Name_out,
         var2Name_out,
         var3Name_out;
  string attrName = "ATTR1";
  string attrName2 = "ATTR2";
  string attrName3 = "ATTR3";
  string new_attrName = "ATTR1a";
  string attrName_out;
  string CopyrightText;
  string errorText;
  byte   zEntryValue1 = 4;
  byte   zEntryValue1Out;
  double zEntryValue2 = 4.0;
  double zEntryValue2Out;
  int    numZvars,maxGentry,numGentries,
         maxZentry,numZentries,numGattrs,numVattrs;
  int    cacheOut1,cacheOut2,cacheOut3;
  short  pad1 = -999;
  float  pad2 = -8.0F;
  string pad3 = "********";
  short  pad1out;
  float  pad2out;
  string pad3out;
  int    blockingfactor1 = 3;
  int    blockingfactor2 = 4;
  int    blockingfactor3 = 5;
  int    blockingfactorOut1,blockingfactorOut2,blockingfactorOut3;
  int[]  indicesOut = new int[10],
         countsOut = new int[10],
         intervalsOut = new int[10];
  int    formatOut;
  int    maxAllocOut1,maxAllocOut2,maxAllocOut3;
  int    maxRecOut1,maxRecOut2,maxRecOut3,maxRecOut;
  int    allocRecs1 = 10;
  int    allocRecs2 = 15;
  int    allocRecs3 = 8;
  int[]  varNs1 = new int[1] {0},varNs2 = new int[1] {2};
  string[] varsRecBuffer2 = new string[5] {
          "%%%%%%%%","%%%%%%%%","%%%%%%%%","%%%%%%%%","%%%%%%%%"
        };
  string[] varsRecBuffer2Out = new string[5];

/******************************************************************************
* Display title.
******************************************************************************/

Console.WriteLine("Testing C#-CDF Interface... using pointers");

/******************************************************************************
* Create CDF.
******************************************************************************/

id =(void*) 0;
try {
status = CDFcreate("TEST",numDims,dimSizes,encoding,majority,&id);
} catch(CDFException ex) {
  int stat = ex.CDFgetCurrentStatus();
  if(stat < CDF_OK) {
    id = null;
    if(stat == CDF_EXISTS) {
      status = CDFopen("TEST",&id);
      if(status < CDF_OK) QuitCDF("1.0",status,id);

      status = CDFdeleteCDF(id);
      if(status < CDF_OK) QuitCDF("1.1",status,id);

      status = CDFcreate("TEST",numDims,dimSizes,encoding,majority,&id);
      if(status < CDF_OK) QuitCDF("1.2",status,id);
      status = CDFsetFormat(id,MULTI_FILE);
      if(status < CDF_OK) QuitCDF("1.3",status,id);
    } else
      QuitCDF("1.4",stat,id);
  }
}

try {
status = CDFsetFormat(id,MULTI_FILE);

/******************************************************************************
* Create variables and set/confirm cache sizes,etc.
******************************************************************************/

status = CDFcreatezVar(id,var1Name,var1DataType,var1NumElements,
                       numDims,dimSizes,var1RecVariance,
                       var1DimVariances,&var1Num_out);

status = CDFputzVarPadValue(id,var1Num_out,&pad1);

status = CDFcreatezVar(id,var2Name,var2DataType,var2NumElements,
                       numDims,dimSizes,var2RecVariance,
                       var2DimVariances,&var2Num_out);

status = CDFputzVarPadValue(id,var2Num_out,&pad2);

status = CDFcreatezVar(id,var3Name,var3DataType,var3NumElements,
		       zNumDimsA,zDimSizesA,var3RecVariance,
		       var3DimVariances,&var3Num_out);

status = CDFputzVarPadValue(id,var3Num_out,pad3);

status = CDFsetzVarsCacheSize(id,5);

status = CDFgetzVarCacheSize(id,0,&cacheOut1);

status = CDFgetzVarPadValue(id,0,&pad1out);

status = CDFgetzVarCacheSize(id,1,&cacheOut2); 

status = CDFgetzVarPadValue(id,1,&pad2out); 

status = CDFgetzVarCacheSize(id,2,&cacheOut3); 

status = CDFgetzVarPadValue(id,2,out pad3out);

if(cacheOut1 != 5) QuitCDF("2.14",status,id);
if(cacheOut2 != 5) QuitCDF("2.15",status,id);
if(cacheOut3 != 5) QuitCDF("2.16",status,id);
if(pad1out != pad1) QuitCDF("2.17",status,id);
if(pad2out != pad2) QuitCDF("2.18",status,id);
if(String.Compare(pad3out,pad3) != 0) QuitCDF("2.19",status,id);

status = CDFsetzVarCacheSize(id,0,4);

status = CDFsetzVarCacheSize(id,2,8);

status = CDFgetzVarCacheSize(id,0,&cacheOut1);

status = CDFgetzVarCacheSize(id,1,&cacheOut2);

status = CDFgetzVarCacheSize(id,2,&cacheOut3);

if(cacheOut1 != 4) QuitCDF("2.25",status,id);
if(cacheOut2 != 5) QuitCDF("2.26",status,id);
if(cacheOut3 != 8) QuitCDF("2.27",status,id);

/******************************************************************************
* Modify variables.
******************************************************************************/

status = CDFsetzVarDataSpec(id,0,var1DataTypeNew);

status = CDFsetzVarRecVariance(id,0,var1RecVarianceNew);

status = CDFsetzVarDimVariances(id,0,var1DimVariancesNew);

status = CDFsetzVarInitialRecs(id,0,1);

status = CDFsetzVarDataSpec(id,2,var3DataTypeNew);

status = CDFsetzVarRecVariance(id,2,var3RecVarianceNew);

status = CDFsetzVarDimVariances(id,2,var3DimVariancesNew);

status = CDFsetzVarInitialRecs(id,2,1);

/******************************************************************************
* Close CDF.
******************************************************************************/

status = CDFcloseCDF(id);

/******************************************************************************
* Reopen CDF.
******************************************************************************/

status = CDFopen("TEST",&id);

status = CDFsetDecoding(id,HOST_DECODING);

/******************************************************************************
* Delete CDF.
******************************************************************************/

status = CDFdeleteCDF(id);

/******************************************************************************
* Create CDF again(previous delete will allow this).
******************************************************************************/

status = CDFcreateCDF("TEST",&id);

status = CDFsetEncoding(id,IBMPC_ENCODING);

status = CDFsetMajority(id,ROW_MAJOR);

status = CDFsetFormat(id,SINGLE_FILE);

status = CDFsetDecoding(id,HOST_DECODING);

/******************************************************************************
* Create variables.
******************************************************************************/

status = CDFcreatezVar(id,var1Name,var1DataType,var1NumElements,
                       numDims,dimSizes,var1RecVariance,
                       var1DimVariances,&var1Num_out);

status = CDFsetzVarAllocRecords(id,var1Num_out,allocRecs1);

status = CDFsetzVarBlockingFactor (id,var1Num_out,blockingfactor1);

status = CDFcreatezVar(id,var2Name,var2DataType,var2NumElements,
                       numDims,dimSizes,var2RecVariance,
                       var2DimVariances,&var2Num_out);

status = CDFsetzVarAllocRecords(id,var2Num_out,allocRecs2);

status = CDFsetzVarBlockingFactor (id,var2Num_out,blockingfactor2);

status = CDFcreatezVar(id,var3Name,var3DataType,var3NumElements,
                       zNumDimsA,zDimSizesA,var3RecVariance,
                       var3DimVariances,&var3Num_out);

status = CDFsetzVarAllocRecords(id,var3Num_out,allocRecs3);

status = CDFsetzVarBlockingFactor (id,var3Num_out,blockingfactor3);

/******************************************************************************
* PUT to variables.
******************************************************************************/

for(x0 = 0; x0 < DIM_0_SIZE; x0++)
   for(x1 = 0; x1 < DIM_1_SIZE; x1++) {
      indices[0] = x0;
      indices[1] = x1;
      fixed(void* pvalue = &var1Values[x0,x1]) {
        status = CDFputzVarData(id,var1Num_out,recNum,indices,pvalue);
      }
      if(status < CDF_OK) QuitCDF("9.0",status,id);

      fixed(void* pvalue = &var2Values[x0,x1]) {
        status = CDFputzVarData(id,var2Num_out,recNum,indices,pvalue);
      }
      if(status < CDF_OK) QuitCDF("9.1",status,id);
   }

for(x0 = 0; x0 < zDIM_0_SIZEa; x0++) {
   zIndicesA[0] = x0;
   status = CDFputzVarData(id,var3Num_out,recNum,zIndicesA,var3Values[x0]);
   if(status < CDF_OK) QuitCDF("9.2",status,id);
}

/******************************************************************************
* GET from the variables.
******************************************************************************/

for(x0 = 0; x0 < DIM_0_SIZE; x0++)
   for(x1 = 0; x1 < DIM_1_SIZE; x1++) {
      indices[0] = x0;
      indices[1] = x1;
      status = CDFgetzVarData(id,var1Num_out,recNum,indices,&var1Value_out);
      if(status < CDF_OK) QuitCDF("10.0",status,id);

      status = CDFgetzVarData(id,var2Num_out,recNum,indices,&var2Value_out);
      if(status < CDF_OK) QuitCDF("10.1",status,id);

      if(var1Value_out != var1Values[x0,x1]) QuitCDF("10.2",status,id);
      if(var2Value_out != var2Values[x0,x1]) QuitCDF("10.3",status,id);
   }

fixed(void* pvalue = var1Values_out) {
  status = CDFgetzVarRecordData(id,var1Num_out,recNum,pvalue);
}
fixed(void* pvalue = var2Values_out) {
  status = CDFgetzVarRecordData(id,var2Num_out,recNum,pvalue);
}

for(x0 = 0; x0 < DIM_0_SIZE; x0++)
   for(x1 = 0; x1 < DIM_1_SIZE; x1++) {
      if(var1Values_out[x0,x1] != var1Values[x0,x1]) 
        QuitCDF("10.2a",status,id);
      if(var2Values_out[x0,x1] != var2Values[x0,x1]) 
        QuitCDF("10.3a",status,id);
   }

for(x0 = 0; x0 < zDIM_0_SIZEa; x0++) {
   zIndicesA[0] = x0;
   status = CDFgetzVarData(id,var3Num_out,recNum,zIndicesA,out var3Value_out);
   if(status < CDF_OK) QuitCDF("10.4",status,id);

   if(String.Compare(var3Value_out,var3Values[x0]) != 0)
     QuitCDF("10.5",status,id);
}

/******************************************************************************
* HyperPUT to the variables.
******************************************************************************/

for(x0 = 0; x0 < DIM_0_SIZE; x0++)
   for(x1 = 0; x1 < DIM_1_SIZE; x1++) {
      var1Values[x0,x1] =(short) -var1Values[x0,x1];
      var2Values[x0,x1] = -var2Values[x0,x1];
   }

indices[0] = 0;
indices[1] = 0;
fixed(void* pvalues = var1Values) {
  status = CDFhyperPutzVarData(id,var1Num_out,recStart,recCount,
                               recInterval,indices,counts,intervals,pvalues); 
}
fixed(void* pvalues = var2Values) {
  status = CDFhyperPutzVarData(id,var2Num_out,recStart,recCount,
                               recInterval,indices,counts,intervals,pvalues); 
}

for(x0 = 0; x0 < zDIM_0_SIZEa; x0++) {
   var3Values[x0] = new string((char)('2'+x0),zNUM_ELEMSa);
}

zIndicesA[0] = 0;

status = CDFhyperPutzVarData(id,var3Num_out,recStart,recCount,
                             recInterval,zIndicesA,zCounts,
                             zIntervals,var3Values); 

/******************************************************************************
* HyperGET from variables.
******************************************************************************/
fixed(void* pvalues = var1Buffer_out) {
  status = CDFhyperGetzVarData(id,var1Num_out,recStart,recCount,
                               recInterval,indices,counts,intervals,pvalues);
}
fixed(void* pvalues = var2Buffer_out) {
  status = CDFhyperGetzVarData(id,var2Num_out,recStart,recCount,
                               recInterval,indices,counts,intervals,pvalues);
}

for(x0 = 0; x0 < DIM_0_SIZE; x0++)
   for(x1 = 0; x1 < DIM_1_SIZE; x1++) {
      if(var1Buffer_out[x0,x1] != var1Values[x0,x1])
	QuitCDF("12.2",status,id);
      if(var2Buffer_out[x0,x1] != var2Values[x0,x1])
	QuitCDF("12.3",status,id);
   }

status = CDFhyperGetzVarData(id,var3Num_out,recStart,recCount,
                             recInterval,zIndicesA,zCounts,
                             zIntervals,out var3Buffer_out);

for(x0 = 0; x0 < zDIM_0_SIZEa; x0++)
   if(String.Compare(((string[])var3Buffer_out)[x0],var3Values[x0]) != 0)
	QuitCDF("12.5",status,id);

/******************************************************************************
* Set/confirm sequential access position for a zVariable(and read/write a
* value).
******************************************************************************/

status = CDFsetzVarSeqPos(id,var3Num_out,recStart,zIndicesA);

status = CDFgetzVarSeqData(id,var3Num_out,out var3Value_out);

status = CDFputzVarSeqData(id,var3Num_out,var3Value_out);

fixed(int* ptr = indicesOut) {
  status = CDFgetzVarSeqPos(id,var3Num_out,&recNumOut,ptr);
}

if(recNumOut != recStart) QuitCDF("14.4",status,id);
if(indicesOut[0] != zIndicesA[0] + 2) QuitCDF("14.5",status,id);

/******************************************************************************
* Create attributes.
******************************************************************************/

status = CDFcreateAttr(id,attrName,attrScope,&attrNum_out);

status = CDFcreateAttr(id,attrName2,attrScope2,&attrNum_out);

status = CDFcreateAttr(id,attrName3,attrScope3,&attrNum_out);

/******************************************************************************
* PUT to attributes.
******************************************************************************/

status = CDFputAttrgEntry(id,0,entryNum,entryDataType,
                          entryNumElems,&entryValue);

status = CDFputAttrzEntry(id,1,CDFgetVarNum(id,var1Name),
                          CDF_BYTE,1,&zEntryValue1);

status = CDFputAttrzEntry(id,2,CDFgetVarNum(id,var2Name),
                          CDF_REAL8,1,&zEntryValue2);

/******************************************************************************
* GET from attributes.
******************************************************************************/

status = CDFgetAttrgEntry(id,0,entryNum,&entryValue_out);

status = CDFgetAttrzEntry(id,1,CDFgetVarNum(id,var1Name),&zEntryValue1Out);

status = CDFgetAttrzEntry(id,2,CDFgetVarNum(id,var2Name),&zEntryValue2Out);

if(entryValue_out != entryValue) QuitCDF("19.6",status,id);
if(zEntryValue1 != zEntryValue1Out) QuitCDF("19.7",status,id);
if(zEntryValue2 != zEntryValue2Out) QuitCDF("19.8",status,id);

/******************************************************************************
* Confirm existence of variables/attributes/entries.
******************************************************************************/

status = CDFconfirmzVarExistence(id,var3Name);
if(status < CDF_OK) QuitCDF("20.1",status,id);

status = CDFconfirmzVarExistence(id,var1Name);
if(status < CDF_OK) QuitCDF("20.2",status,id);

status = CDFconfirmAttrExistence(id,attrName3);
if(status < CDF_OK) QuitCDF("20.3",status,id);

status = CDFconfirmgEntryExistence(id,0,entryNum);
if(status < CDF_OK) QuitCDF("20.4",status,id);

status = CDFconfirmzEntryExistence(id,1,CDFgetVarNum(id,var1Name));
if(status < CDF_OK) QuitCDF("20.5",status,id);

/******************************************************************************
* Get CDF documentation.
******************************************************************************/

status = CDFgetLibraryVersion(&version_out,&release_out,
                              &increment_out,out subincrement_out);
Console.WriteLine("CDF Version: "+version_out+"."+release_out+"."+
		  increment_out+
		  (String.Compare(subincrement_out," ")==0?"":("_"+subincrement_out)));

status = CDFgetLibraryCopyright(out CopyrightText);

/******************************************************************************
* Inquire CDF.
******************************************************************************/

status = CDFgetFormat(id,&formatOut);

status = CDFgetEncoding(id,&encoding_out);

status = CDFgetMajority(id,&majority_out);

status = CDFgetzVarsMaxWrittenRecNum(id,&maxRec_out);

status = CDFgetNumzVars(id,&numZvars);

status = CDFgetNumAttributes(id,&numAttrs_out);

if(formatOut != SINGLE_FILE) QuitCDF("22.9",status,id);
if(encoding_out != actual_encoding) QuitCDF("22.12",status,id);
if(majority_out != majority) QuitCDF("22.13",status,id);
if(maxRec_out != 2) QuitCDF("22.14",status,id);
if(numZvars != 3) QuitCDF("22.16",status,id);
if(numAttrs_out != 3) QuitCDF("22.17",status,id);

/******************************************************************************
* Inquire numbers.
******************************************************************************/

attrNum_out = CDFgetAttrNum(id,attrName3);

varNum_out1 = CDFgetVarNum(id,var2Name);

varNum_out2 = CDFgetVarNum(id,var3Name);

if(attrNum_out != 2) QuitCDF("23.3",status,id);
if(varNum_out1 != 1) QuitCDF("23.4",status,id);
if(varNum_out2 != 2) QuitCDF("23.5",status,id);

/******************************************************************************
* Rename variables.
******************************************************************************/

status = CDFrenamezVar(id,CDFgetVarNum(id,var1Name),new_var1Name);

status = CDFrenamezVar(id,CDFgetVarNum(id,var2Name),new_var2Name);

status = CDFrenamezVar(id,CDFgetVarNum(id,var3Name),new_var3Name);

/******************************************************************************
* Inquire variables.
******************************************************************************/

status = CDFgetzVarName(id,var1Num_out,out var1Name_out);

status = CDFgetzVarDataType(id,var1Num_out,&var1DataType_out);

status = CDFgetzVarNumElements(id,var1Num_out,&var1NumElements_out);

status = CDFgetzVarRecVariance(id,var1Num_out,&var1RecVariance_out);

fixed(int* pvalues = var1DimVariances_out) {
  status = CDFgetzVarDimVariances(id,var1Num_out,pvalues);
}

status = CDFgetzVarBlockingFactor(id,var1Num_out,&blockingfactorOut1);

status = CDFgetzVarMaxAllocRecNum(id,var1Num_out,&maxAllocOut1);

status = CDFgetzVarMaxWrittenRecNum(id,var1Num_out,&maxRecOut1);

if(String.Compare(var1Name_out,new_var1Name) != 0) 
  QuitCDF("26.11",status,id);
if(var1DataType_out != var1DataType) QuitCDF("26.12",status,id);
if(var1NumElements_out != var1NumElements) QuitCDF("26.13",status,id);
if(var1RecVariance_out != var1RecVariance) QuitCDF("26.14",status,id);
if(var1Num_out != 0) QuitCDF("26.15",status,id);
if(blockingfactorOut1 != blockingfactor1) QuitCDF("26.16",status,id);
if(maxAllocOut1 + 1 != allocRecs1) QuitCDF("26.17",status,id);
if(maxRecOut1 != 2) QuitCDF("26.18",status,id);

for(dim_n = 0; dim_n < numDims; dim_n++) {
   if(var1DimVariances_out[dim_n] != var1DimVariances[dim_n]) {
     QuitCDF("26.19",status,id);
   }
}

status = CDFgetzVarName(id,var2Num_out,out var2Name_out);

status = CDFgetzVarDataType(id,var2Num_out,&var2DataType_out);

status = CDFgetzVarNumElements(id,var2Num_out,&var2NumElements_out);

status = CDFgetzVarRecVariance(id,var2Num_out,&var2RecVariance_out);

fixed(int* pvalues = var2DimVariances_out) {
  status = CDFgetzVarDimVariances(id,var2Num_out,pvalues);
}

status = CDFgetzVarBlockingFactor(id,var2Num_out,&blockingfactorOut2);

status = CDFgetzVarMaxAllocRecNum(id,var2Num_out,&maxAllocOut2);

status = CDFgetzVarMaxWrittenRecNum(id,var2Num_out,&maxRecOut2);

if(String.Compare(var2Name_out,new_var2Name) != 0) 
  QuitCDF("26.31",status,id);
if(var2DataType_out != var2DataType) QuitCDF("26.32",status,id);
if(var2NumElements_out != var2NumElements) QuitCDF("26.33",status,id);
if(var2RecVariance_out != var2RecVariance) QuitCDF("26.34",status,id);
if(var2Num_out != 1) QuitCDF("26.35",status,id);
if(blockingfactorOut2 != blockingfactor2) QuitCDF("26.36",status,id);
if(maxAllocOut2 + 1 != allocRecs2) QuitCDF("26.37",status,id);
if(maxRecOut2 != 2) QuitCDF("26.38",status,id);


for(dim_n = 0; dim_n < numDims; dim_n++) {
   if(var2DimVariances_out[dim_n] != var2DimVariances[dim_n]) {
     QuitCDF("26.39",status,id);
   }
}

status = CDFgetzVarName(id,var3Num_out,out var3Name_out);

status = CDFgetzVarDataType(id,var3Num_out,&var3DataType_out);

status = CDFgetzVarNumElements(id,var3Num_out,&var3NumElements_out);

status = CDFgetzVarRecVariance(id,var3Num_out,&var3RecVariance_out);

fixed(int* pvalues = var3DimVariances_out) {
  status = CDFgetzVarDimVariances(id,var3Num_out,pvalues);
}

status = CDFgetzVarNumDims(id,var3Num_out,&zNumDimsA_out);

fixed(int* pvalues = zDimSizesA_out) {
status = CDFgetzVarDimSizes(id,var3Num_out,pvalues);
}

status = CDFgetzVarBlockingFactor(id,var3Num_out,&blockingfactorOut3);

status = CDFgetzVarMaxAllocRecNum(id,var3Num_out,&maxAllocOut3);

status = CDFgetzVarMaxWrittenRecNum(id,var3Num_out,&maxRecOut3);

if(String.Compare(var3Name_out,new_var3Name) != 0) 
  QuitCDF("26.53",status,id);
if(var3DataType_out != var3DataType) QuitCDF("26.54",status,id);
if(var3NumElements_out != var3NumElements) QuitCDF("26.55",status,id);
if(var3RecVariance_out != var3RecVariance) QuitCDF("26.56",status,id);
if(zNumDimsA_out != zNumDimsA) QuitCDF("26.57",status,id);
if(var3Num_out != 2) QuitCDF("26.58",status,id);
if(blockingfactorOut3 != blockingfactor3) QuitCDF("26.59",status,id);
if(maxAllocOut3 + 1 != allocRecs3) QuitCDF("26.60",status,id);
if(maxRecOut3 != 2) QuitCDF("26.61",status,id);

for(dim_n = 0; dim_n < zNumDimsA; dim_n++) {
   if(zDimSizesA_out[dim_n] != zDimSizesA[dim_n]) {
     QuitCDF("26.62",status,id);
   }
   if(var3DimVariances_out[dim_n] != var3DimVariances[dim_n]) {
     QuitCDF("26.63",status,id);
   }
}

/******************************************************************************
* Rename attribute.
******************************************************************************/

status = CDFrenameAttr(id,CDFgetAttrNum(id,attrName),new_attrName);

/******************************************************************************
* Inquire attribute.
******************************************************************************/

status = CDFgetAttrName(id,CDFgetAttrNum(id,new_attrName),out attrName_out);

status = CDFgetAttrScope(id,CDFgetAttrNum(id,new_attrName),&attrScope_out);

status = CDFgetAttrMaxgEntry(id,CDFgetAttrNum(id,new_attrName),&maxEntry_out);

if(String.Compare(attrName_out,new_attrName) != 0) 
  QuitCDF("28.4",status,id);
if(attrScope_out != attrScope) QuitCDF("28.5",status,id);
if(maxEntry_out != entryNum) QuitCDF("28.6",status,id);

/******************************************************************************
* Inquire attribute entries.
******************************************************************************/

status = CDFgetAttrgEntryDataType(id,0,entryNum,&entryDataType_out);

status = CDFgetAttrgEntryNumElements(id,0,entryNum,&entryNumElems_out);

if(entryDataType_out != entryDataType) QuitCDF("29.2",status,id);
if(entryNumElems_out != entryNumElems) QuitCDF("29.3",status,id);

status = CDFgetAttrzEntryDataType(id,1,0,&entryDataType_out);

status = CDFgetAttrzEntryNumElements(id,1,0,&entryNumElems_out);

if(entryDataType_out != CDF_BYTE) QuitCDF("29.6",status,id);
if(entryNumElems_out != 1) QuitCDF("29.7",status,id);

status = CDFgetAttrzEntryDataType(id,2,1,&entryDataType_out);

status = CDFgetAttrzEntryNumElements(id,2,1,&entryNumElems_out);

if(entryDataType_out != CDF_REAL8) QuitCDF("29.10",status,id);
if(entryNumElems_out != 1) QuitCDF("29.11",status,id);

/******************************************************************************
* Get error text.
******************************************************************************/

status = CDFgetStatusText(CDF_OK,out errorText);

/******************************************************************************
* Select zMode and inquire CDF.
******************************************************************************/

status = CDFsetzMode(id,zMODEon2);

status = CDFgetNumgAttributes(id,&numGattrs);

status = CDFgetNumvAttributes(id,&numVattrs);

status = CDFgetNumzVars(id,&numZvars);

status = CDFgetAttrMaxgEntry(id,0,&maxGentry);

status = CDFgetNumAttrgEntries(id,0,&numGentries);

status = CDFgetzVarsMaxWrittenRecNum(id,&maxRecOut);

status = CDFgetAttrMaxzEntry(id,1,&maxZentry);

status = CDFgetNumAttrzEntries(id,1,&numZentries);

status = CDFsetzMode(id,zMODEoff);

fixed(int* ptr = dimSizesX) {
status = CDFinquire(id,&numDimsX,ptr,&encodingX,&majorityX,&maxrRecX,
                    &nrVarsX,&nAttrsX);
}

fixed(int* ptr = dimSizesY) {
status = CDFinquireCDF(id,&numDimsY,ptr,&encodingY,&majorityY,
                       &maxrRecY,&nrVarsY,&maxzRecY,&nzVarsY,&nAttrsY);
}

if(numGattrs != 1) QuitCDF("31.13",status,id);
if(numVattrs != 2) QuitCDF("31.14",status,id);
if(numZvars != 3) QuitCDF("31.16",status,id);
if(maxGentry != entryNum) QuitCDF("31.17",status,id);
if(numGentries != 1) QuitCDF("31.18",status,id);
if(maxZentry != 0) QuitCDF("31.21",status,id);
if(numZentries != 1) QuitCDF("31.22",status,id);
if(maxRecOut != 2) QuitCDF("31.23",status,id);
if(numDimsX != numDimsY || numDimsX != 0) QuitCDF("31.24",status,id);
if(encodingX != encodingY || encodingX != IBMPC_ENCODING) 
  QuitCDF("31.25",status,id);
if(majorityX != majorityY || majorityX != ROW_MAJOR) 
  QuitCDF("31.26",status,id);
/* if(maxrRecX != maxrRecY || maxrRecX != 0) QuitCDF("31.27",status,id); */
if(nrVarsX != nrVarsY || nrVarsX != 0) QuitCDF("31.28",status,id);
if(nAttrsX != nAttrsY || nAttrsX != 3) QuitCDF("31.29",status,id);
if(nzVarsY != 3) QuitCDF("31.30",status,id);
if(maxzRecY != 2) QuitCDF("31.31",status,id);

/******************************************************************************
* Attempt to close variables.
******************************************************************************/

status = CDFclosezVar(id,0);
if(status != SINGLE_FILE_FORMAT) QuitCDF("32.0",status,id);

status = CDFclosezVar(id,2);
if(status != SINGLE_FILE_FORMAT) QuitCDF("32.1",status,id);

/******************************************************************************
* Modify entries/attribute.
******************************************************************************/

status = CDFsetAttrgEntryDataSpec(id,0,entryNum,entryDataTypeNew);

status = CDFsetAttrzEntryDataSpec(id,1,CDFgetVarNum(id,new_var1Name),CDF_UINT1);

status = CDFsetAttrzEntryDataSpec(id,2,CDFgetVarNum(id,new_var2Name),CDF_EPOCH);

status = CDFsetAttrScope(id,0,VARIABLE_SCOPE);

status = CDFsetAttrScope(id,0,GLOBAL_SCOPE);

/******************************************************************************
* Delete entries/attribute/variables.
******************************************************************************/

status = CDFdeleteAttrgEntry(id,0,entryNum);

status = CDFdeleteAttrzEntry(id,1,0);

status = CDFdeleteAttrzEntry(id,2,1);

status = CDFdeleteAttr(id,CDFgetAttrNum(id,new_attrName));

status = CDFdeletezVar(id,CDFgetVarNum(id,new_var1Name));

status = CDFdeletezVar(id,CDFgetVarNum(id,new_var3Name));

/******************************************************************************
* Close CDF.
******************************************************************************/

status = CDFcloseCDF(id);  

int cTypeo;
int[] cParmso = new int[1];
long cSizeo,uSizeo;
fixed(int* pcParmso = cParmso) {
  status = CDFgetCompressionInfo("TEST",&cTypeo,pcParmso,&cSizeo,&uSizeo);
}
Console.WriteLine("Compression:"+CDFUtils.CDFgetStringCompressionType(cTypeo)+
                  "."+cParmso[0]+
                  " File size: compressed:"+cSizeo+" uncompressed:"+uSizeo);

/******************************************************************************
* Successful completion.
******************************************************************************/
} catch(CDFException ex) {
  Console.WriteLine("Error... "+ex);
} finally {
  try {
    status = CDFselect(id);
    status = CDFcloseCDF(id);
  } catch(CDFException ex) {}
}

}


/******************************************************************************
* QuitCDF.
******************************************************************************/

unsafe static void QuitCDF(string where, int status, void* id)
{
  string text;
  Console.WriteLine("Aborting at "+where);
  if(status < 0) {
    status = CDFgetStatusText(status,out text); 
    Console.WriteLine(" "+text);
  }
  status = CDFcloseCDF(id);
  Console.WriteLine("...test aborted.");
  System.Environment.Exit(1);
}

}

