netcdf-c/ncdump/tst_comp2.c
2024-01-15 15:46:13 +00:00

176 lines
4.8 KiB
C

/* This is part of the netCDF package. Copyright 2018 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 <nc_tests.h>
#include "err_macros.h"
#include <netcdf.h>
#include <string.h>
#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;
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 (size_t 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;
}