/* This is part of the netCDF package. Copyright 2005 University Corporation for Atmospheric Research/Unidata See COPYRIGHT file for conditions of use. See www.unidata.ucar.edu for more info. Create a test file with array member of compound type and nested compound data for ncdump to read. $Id: tst_comp2.c,v 1.4 2008/10/20 01:48:08 ed Exp $ */ #include #include #include #define FILE9_NAME "tst_comp2.nc" #define TYPE_NAME "vecmat_t" #define DIM_NAME "n" #define DIM_LEN 3 #define VAR_NAME "obs" #define VAR_RANK 1 #define ATT_NAME "_FillValue" #define ATT_LEN 1 int main(int argc, char **argv) { int ncid; int dimid, varid; nc_type typeid; char name_in[NC_MAX_NAME+1]; int i, j, k; int var_dims[VAR_RANK]; #define VEC_LEN 3 #define MAT_DIM0 2 #define MAT_DIM1 3 #define MON_LEN 3 #define NFIELDS 4 /* number of fields in struct and compound type */ struct vecmat_t { char dow; char mon[MON_LEN]; short vec[VEC_LEN]; float mat[MAT_DIM0][MAT_DIM1]; }; struct vecmat_t data[DIM_LEN] = { { 'S', "jan", {1, 2, 3}, {{4, 5, 6}, {7, 8, 9}} }, { 'M', "feb", {11, 12, 13}, {{4.25, 5.25, 6.25}, {7.25, 8.25, 9.25}} }, { 'T', "mar", {21, 22, 23}, {{4.5, 5.5, 6.5}, {7.5, 8.5, 9.5}} } }; struct vecmat_t missing_val = { '?', "---", {-1, -2, -3}, {{-4.0f, -5.0f, -6.0f}, {-7.0f, -8.0f, -9.0f}} }; struct vecmat_t val_in; size_t size_in; size_t nfields_in; nc_type class_in; int vec_sizes[] = {VEC_LEN}; int mat_sizes[] = {MAT_DIM0, MAT_DIM1}; int mon_sizes[] = {MON_LEN}; printf("\n*** Testing compound types some more.\n"); printf("*** creating another compound test file %s...", FILE9_NAME); if (nc_create(FILE9_NAME, NC_CLOBBER | NC_NETCDF4, &ncid)) ERR; /* Create a compound type. */ if (nc_def_compound(ncid, sizeof(struct vecmat_t), TYPE_NAME, &typeid)) ERR; if (nc_insert_compound(ncid, typeid, "day", NC_COMPOUND_OFFSET(struct vecmat_t, dow), NC_CHAR)) ERR; if (nc_insert_array_compound(ncid, typeid, "mnth", NC_COMPOUND_OFFSET(struct vecmat_t, mon), NC_CHAR, 1, mon_sizes)) ERR; if (nc_insert_array_compound(ncid, typeid, "vect", NC_COMPOUND_OFFSET(struct vecmat_t, vec), NC_SHORT, 1, vec_sizes)) ERR; if (nc_insert_array_compound(ncid, typeid, "matr", NC_COMPOUND_OFFSET(struct vecmat_t, mat), NC_FLOAT, 2, mat_sizes)) ERR; /* Declare a dimension for number of obs */ if (nc_def_dim(ncid, DIM_NAME, DIM_LEN, &dimid)) ERR; /* Declare a variable of the compound type */ var_dims[0] = dimid; if (nc_def_var(ncid, VAR_NAME, typeid, VAR_RANK, var_dims, &varid)) ERR; /* Create and write a variable attribute of the compound type */ if (nc_put_att(ncid, varid, ATT_NAME, typeid, ATT_LEN, (void *) &missing_val)) ERR; if (nc_enddef(ncid)) ERR; /* Store data, writing all values in one call */ if(nc_put_var(ncid, varid, data)) ERR; /* Write the file. */ if (nc_close(ncid)) ERR; /* Check it out. */ /* Reopen the file. */ if (nc_open(FILE9_NAME, NC_NOWRITE, &ncid)) ERR; /* Get info with the generic inquire for user-defined types */ if (nc_inq_user_type(ncid, typeid, name_in, NULL, NULL, NULL, &class_in)) ERR; if (strcmp(name_in, TYPE_NAME) || class_in != NC_COMPOUND) ERR; /* Get the same info with the compound-specific inquire function */ if (nc_inq_compound(ncid, typeid, name_in, &size_in, &nfields_in)) ERR; if (strcmp(name_in, TYPE_NAME) || size_in != sizeof(struct vecmat_t) || nfields_in != NFIELDS) ERR; if (nc_inq_varid(ncid, VAR_NAME, &varid)) ERR; /* Read in attribute value and check it */ if (nc_get_att(ncid, varid, ATT_NAME, &val_in)) ERR; for(i=0; i < VEC_LEN; i++) { if (val_in.vec[i] != missing_val.vec[i]) ERR; } for(i=0; i < MAT_DIM0; i++) { for(j=0; j < MAT_DIM1; j++) { if (val_in.mat[i][j] != missing_val.mat[i][j]) ERR; } } for(i=0; i < MON_LEN; i++) { if (val_in.mon[i] != missing_val.mon[i]) ERR; } /* Read in each value and check */ for (k = 0; k < DIM_LEN; k++) { size_t index[VAR_RANK]; index[0] = k; if (nc_get_var1(ncid, varid, index, (void *) &val_in)) ERR; if (val_in.dow != data[k].dow) ERR; for(i=0; i < MON_LEN; i++) { if (val_in.mon[i] != data[k].mon[i]) ERR; } for(i=0; i < VEC_LEN; i++) { if (val_in.vec[i] != data[k].vec[i]) ERR; } for(i=0; i < MAT_DIM0; i++) { for(j=0; j < MAT_DIM1; j++) { if (val_in.mat[i][j] != data[k].mat[i][j]) ERR; } } } if (nc_close(ncid)) ERR; SUMMARIZE_ERR; FINAL_RESULTS; }