mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-12-21 08:39:46 +08:00
176 lines
4.7 KiB
C
176 lines
4.7 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, 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;
|
|
}
|