netcdf-c/nc_test4/tst_compounds3.c
2018-12-06 15:27:32 -07:00

199 lines
7.3 KiB
C

/* This is part of the netCDF package.
Copyright 2018 University Corporation for Atmospheric Research/Unidata
See COPYRIGHT file for conditions of use.
Test netcdf-4 compound type feature, even more.
$Id: tst_compounds3.c,v 1.8 2010/05/25 13:53:04 ed Exp $
*/
#include <config.h>
#include <stdlib.h>
#include <nc_tests.h>
#include "err_macros.h"
#define FILE_NAME "tst_compounds3.nc"
#define S1_PACKED_NAME "s1_packed_compound_type_with_boring_name"
#define S1_NAME "s1_compound_type_unwhimsiclaly_named"
#define I_NAME "i_of_little_quirkiness"
#define J_NAME "j_with_no_originality"
#define DIM_NAME "intentionally_unimaginatevely_named_dimension"
#define DIM_LEN 1
#define VAR_NAME "deliberately_boring_variable"
typedef struct g1_c_t {
float x;
double y;
} g1_c_t;
typedef struct g2_d_t {
g1_c_t s1;
} g2_d_t;
int
main(int argc, char **argv)
{
printf("\n*** Testing netcdf-4 compound types even more.\n");
printf("*** testing compound variable create from packed struct...");
{
int ncid, typeid, varid;
size_t nfields;
int dimid;
int ndims, nvars, natts, unlimdimid;
char name_in[NC_MAX_NAME + 1];
size_t size;
nc_type xtype, field_xtype;
int dimids[] = {0};
int field_ndims, field_sizes[NC_TESTS_MAX_DIMS];
size_t offset;
int i;
struct s1_packed
{
short i;
long long j;
};
/* This packing extension works with GNU compilers... */
/* } __attribute__ ((__packed__));*/
struct s1
{
short i;
long long j;
};
struct s1_packed *data;
struct s1 *data_in;
if (!(data = calloc(sizeof(struct s1_packed), DIM_LEN))) ERR;
if (!(data_in = calloc(sizeof(struct s1), DIM_LEN))) ERR;
/* Create some phony data. */
for (i = 0; i < DIM_LEN; i++)
{
data[i].i = 100;
data[i].j = 1000000000000LL;
}
/* Create a file with a compound type. Write a little data. */
if (nc_create(FILE_NAME, NC_NETCDF4, &ncid)) ERR;
if (nc_def_compound(ncid, sizeof(struct s1_packed), S1_PACKED_NAME, &typeid)) ERR;
if (nc_inq_compound(ncid, typeid, name_in, &size, &nfields)) ERR;
if (size != sizeof(struct s1_packed) || strcmp(name_in, S1_PACKED_NAME) || nfields) ERR;
if (nc_insert_compound(ncid, typeid, I_NAME, NC_COMPOUND_OFFSET(struct s1_packed, i),
NC_SHORT)) ERR;
if (nc_insert_compound(ncid, typeid, J_NAME, NC_COMPOUND_OFFSET(struct s1_packed, j),
NC_INT64)) ERR;
if (nc_def_dim(ncid, DIM_NAME, DIM_LEN, &dimid)) ERR;
if (nc_def_var(ncid, VAR_NAME, typeid, 1, dimids, &varid)) ERR;
if (nc_put_var(ncid, varid, data)) ERR;
if (nc_close(ncid)) ERR;
/* Open the file and take a peek. */
if (nc_open(FILE_NAME, NC_WRITE, &ncid)) ERR;
if (nc_inq(ncid, &ndims, &nvars, &natts, &unlimdimid)) ERR;
if (ndims != 1 || nvars != 1 || natts != 0 || unlimdimid != -1) ERR;
/* Check the var and its type. */
if (nc_inq_var(ncid, 0, name_in, &xtype, &ndims, dimids, &natts)) ERR;
if (strcmp(name_in, VAR_NAME) || ndims != 1 || natts != 0 || dimids[0] != 0) ERR;
if (nc_inq_compound(ncid, xtype, name_in, &size, &nfields)) ERR;
if (nfields != 2 || size != sizeof(struct s1) || strcmp(name_in, S1_PACKED_NAME)) ERR;
if (nc_inq_compound_field(ncid, xtype, 0, name_in, &offset, &field_xtype, &field_ndims, field_sizes)) ERR;
if (field_ndims) ERR;
if (strcmp(name_in, I_NAME) || offset != NC_COMPOUND_OFFSET(struct s1, i) ||
(field_xtype != NC_SHORT || field_ndims != 0)) ERR;
if (nc_inq_compound_field(ncid, xtype, 1, name_in, &offset, &field_xtype, &field_ndims,
field_sizes)) ERR;
if (strcmp(name_in, J_NAME) || offset != NC_COMPOUND_OFFSET(struct s1, j) ||
field_xtype != NC_INT64) ERR;
/* Now check the data. */
if (nc_get_var(ncid, varid, data_in)) ERR;
for (i = 0; i < DIM_LEN; i++)
if (data[i].i != data_in[i].i || data[i].j != data_in[i].j) ERR;
if (nc_close(ncid)) ERR;
free(data);
free(data_in);
}
SUMMARIZE_ERR;
printf("*** testing compound attribute with Dennis...");
{
#define GROUP1_NAME "g1"
#define GROUP2_NAME "g2"
#define TYPE1_NAME "t1"
#define TYPE2_NAME "t2"
#define ATT_NAME "a1"
#define ATT_LEN 1
int root_grp, g1_grp, g2_grp;
int g1_c_t_typ, g2_d_t_typ, type1id, type2id;
char name_in[NC_MAX_NAME + 1], full_name[NC_MAX_NAME + 1];
size_t size_in;
g2_d_t *a1_att, *a1_att_in;
int i;
if (!(a1_att = calloc(sizeof(g2_d_t), ATT_LEN))) ERR;
if (!(a1_att_in = calloc(sizeof(g2_d_t), ATT_LEN))) ERR;
for (i = 0; i < ATT_LEN; i++)
{
a1_att[i].s1.x = 13.3;
a1_att[i].s1.y = 13.3;
}
/* Create a file with two groups, define a type in each group,
* and write an att of that type in the root group. */
if (nc_create(FILE_NAME, NC_NETCDF4, &root_grp)) ERR;
if (nc_def_grp(root_grp, GROUP1_NAME, &g1_grp)) ERR;
if (nc_def_grp(root_grp, GROUP2_NAME, &g2_grp)) ERR;
if (nc_def_compound(g1_grp, sizeof(g1_c_t), TYPE1_NAME, &g1_c_t_typ)) ERR;
if (nc_insert_compound(g1_grp, g1_c_t_typ, "x", NC_COMPOUND_OFFSET(g1_c_t,x), NC_FLOAT)) ERR;
if (nc_insert_compound(g1_grp, g1_c_t_typ, "y", NC_COMPOUND_OFFSET(g1_c_t,y), NC_DOUBLE)) ERR;
if (nc_def_compound(g2_grp, sizeof(g2_d_t), TYPE2_NAME, &g2_d_t_typ)) ERR;
if (nc_insert_compound(g2_grp, g2_d_t_typ, "s1", NC_COMPOUND_OFFSET(g2_d_t,s1), g1_c_t_typ)) ERR;
if (nc_put_att(root_grp, NC_GLOBAL, ATT_NAME, g2_d_t_typ, ATT_LEN, a1_att)) ERR;
if (nc_close(root_grp)) ERR;
/* Check the file. */
if (nc_open(FILE_NAME, NC_WRITE, &root_grp)) ERR;
/* Check the attribute. */
if (nc_get_att(root_grp, NC_GLOBAL, ATT_NAME, a1_att_in)) ERR;
if (a1_att_in[0].s1.x != a1_att[0].s1.x ||
a1_att_in[0].s1.y != a1_att[0].s1.y) ERR;
/* Check the type in grp1. */
if (nc_inq_grp_ncid(root_grp, GROUP1_NAME, &g1_grp)) ERR;
if (nc_inq_typeid(g1_grp, TYPE1_NAME, &type1id)) ERR;
if (nc_inq_type(g1_grp, type1id, name_in, &size_in)) ERR;
if (strcmp(name_in, TYPE1_NAME) || size_in != sizeof(g1_c_t)) ERR;
/* Check the type in grp2. */
if (nc_inq_grp_ncid(root_grp, GROUP2_NAME, &g2_grp)) ERR;
if (nc_inq_typeid(g2_grp, TYPE2_NAME, &type2id)) ERR;
if (nc_inq_type(g2_grp, type2id, name_in, &size_in)) ERR;
if (strcmp(name_in, TYPE2_NAME) || size_in != sizeof(g2_d_t)) ERR;
/* This fails because it's not a fully-qualified name. */
sprintf(full_name, "%s/%s", GROUP2_NAME, TYPE2_NAME);
if (nc_inq_typeid(root_grp, full_name, &type2id) != NC_EINVAL) ERR;
/* Check the type using it's full name. */
sprintf(full_name, "/%s/%s", GROUP2_NAME, TYPE2_NAME);
/* if (nc_inq_typeid(root_grp, full_name, &type2id)) ERR; */
/* if (nc_inq_type(g2_grp, type2id, name_in, &size_in)) ERR; */
/* if (strcmp(name_in, TYPE2_NAME) || size_in != sizeof(g2_d_t)) ERR; */
/* Check that a type in grp1 can be identified in grp2 */
type1id = -1;
if (nc_inq_typeid(g2_grp, TYPE1_NAME, &type1id)) ERR;
if (nc_inq_type(g2_grp, type1id, name_in, &size_in)) ERR;
if (strcmp(name_in, TYPE1_NAME) || size_in != sizeof(g1_c_t)) ERR;
/* We are done! */
if (nc_close(root_grp)) ERR;
free(a1_att);
free(a1_att_in);
}
SUMMARIZE_ERR;
FINAL_RESULTS;
}