1 /* This is part of the netCDF package. Copyright 2005 University
2    Corporation for Atmospheric Research/Unidata See COPYRIGHT file for
3    conditions of use. See www.unidata.ucar.edu for more info.
4 
5    Create a test file with an enum type and enum data for ncdump to read.
6 
7    $Id: tst_enum_data.c,v 1.8 2008/10/20 01:48:08 ed Exp $
8 */
9 
10 #include <nc_tests.h>
11 #include "err_macros.h"
12 #include <netcdf.h>
13 
14 #define FILE2_NAME "tst_enum_data.nc"
15 #define TYPE2_NAME "cloud_class_t"
16 #define DIM2_NAME "station"
17 #define DIM2_LEN 5
18 #define VAR2_NAME "primary_cloud"
19 #define VAR2_RANK 1
20 #define ATT2_NAME "_FillValue"
21 #define ATT2_LEN  1
22 
23 int
main(int argc,char ** argv)24 main(int argc, char **argv)
25 {
26    int ncid;
27    int dimid, varid;
28    nc_type typeid;
29    int num_members;
30    char name_in[NC_MAX_NAME+1];
31    nc_type base_nc_type_in;
32    size_t nfields_in, base_size_in, num_members_in;
33    int class_in;
34    unsigned char value_in;
35 
36    int i;
37 
38    enum clouds {		/* a C enumeration */
39        CLEAR=0,
40        CUMULONIMBUS=1,
41        STRATUS=2,
42        STRATOCUMULUS=3,
43        CUMULUS=4,
44        ALTOSTRATUS=5,
45        NIMBOSTRATUS=6,
46        ALTOCUMULUS=7,
47        CIRROSTRATUS=8,
48        CIRROCUMULUS=9,
49        CIRRUS=10,
50        MISSING=255};
51 
52    struct {
53        char *name;
54        unsigned char value;
55    } cloud_types[] = {
56        {"Clear", CLEAR},
57        {"Cumulonimbus", CUMULONIMBUS},
58        {"Stratus", STRATUS},
59        {"Stratocumulus", STRATOCUMULUS},
60        {"Cumulus", CUMULUS},
61        {"Altostratus", ALTOSTRATUS},
62        {"Nimbostratus", NIMBOSTRATUS},
63        {"Altocumulus", ALTOCUMULUS},
64        {"Cirrostratus", CIRROSTRATUS},
65        {"Cirrocumulus", CIRROCUMULUS},
66        {"Cirrus", CIRRUS},
67        {"Missing", MISSING}
68    };
69    int var_dims[VAR2_RANK];
70    unsigned char att_val;
71    unsigned char cloud_data[DIM2_LEN] = {
72        CLEAR, STRATUS, CLEAR, CUMULONIMBUS, MISSING};
73    unsigned char cloud_data_in[DIM2_LEN];
74 
75    printf("\n*** Testing enums.\n");
76    printf("*** creating enum test file %s...", FILE2_NAME);
77    /*nc_set_log_level(3);*/
78    if (nc_create(FILE2_NAME, NC_CLOBBER | NC_NETCDF4, &ncid)) ERR;
79 
80    /* Create an enum type. */
81    if (nc_def_enum(ncid, NC_UBYTE, TYPE2_NAME, &typeid)) ERR;
82    num_members = (sizeof cloud_types) / (sizeof cloud_types[0]);
83    for (i = 0; i < num_members; i++) {
84        if (nc_insert_enum(ncid, typeid, cloud_types[i].name,
85 			  &cloud_types[i].value))
86 			  ERR;
87    }
88    /* Declare a station dimension */
89    if (nc_def_dim(ncid, DIM2_NAME, DIM2_LEN, &dimid)) ERR;
90    /* Declare a variable of the enum type */
91    var_dims[0] = dimid;
92    if (nc_def_var(ncid, VAR2_NAME, typeid, VAR2_RANK, var_dims, &varid)) ERR;
93    /* Create and write a variable attribute of the enum type */
94    att_val = MISSING;
95    if (nc_put_att(ncid, varid, ATT2_NAME, typeid, ATT2_LEN, &att_val)) ERR;
96    if (nc_enddef(ncid)) ERR;
97    /* Store some data of the enum type */
98    if(nc_put_var(ncid, varid, cloud_data)) ERR;
99    /* Write the file. */
100    if (nc_close(ncid)) ERR;
101 
102    /* Check it out. */
103 
104    /* Reopen the file. */
105    if (nc_open(FILE2_NAME, NC_NOWRITE, &ncid)) ERR;
106 
107    if (nc_inq_user_type(ncid, typeid, name_in, &base_size_in, &base_nc_type_in,
108 			   &nfields_in, &class_in)) ERR;
109    if (strcmp(name_in, TYPE2_NAME) ||
110        base_size_in != sizeof(unsigned char) ||
111        base_nc_type_in != NC_UBYTE ||
112        nfields_in != num_members ||
113        class_in != NC_ENUM) ERR;
114    if (nc_inq_enum(ncid, typeid, name_in,
115 		   &base_nc_type_in, &base_size_in, &num_members_in)) ERR;
116    if (strcmp(name_in, TYPE2_NAME) ||
117        base_nc_type_in !=  NC_UBYTE ||
118        num_members_in != num_members) ERR;
119    for (i = 0; i < num_members; i++)
120    {
121        if (nc_inq_enum_member(ncid, typeid, i, name_in, &value_in)) ERR;
122        if (strcmp(name_in, cloud_types[i].name) ||
123 	   value_in != cloud_types[i].value) ERR;
124        if (nc_inq_enum_ident(ncid, typeid, cloud_types[i].value,
125 			     name_in)) ERR;
126        if (strcmp(name_in, cloud_types[i].name)) ERR;
127    }
128    if (nc_inq_varid(ncid, VAR2_NAME, &varid)) ERR;
129 
130    if (nc_get_att(ncid, varid, ATT2_NAME, &value_in)) ERR;
131    if (value_in != MISSING) ERR;
132 
133    if(nc_get_var(ncid, varid, cloud_data_in)) ERR;
134    for (i = 0; i < DIM2_LEN; i++) {
135        if (cloud_data_in[i] != cloud_data[i]) ERR;
136    }
137 
138    if (nc_close(ncid)) ERR;
139 
140 
141    SUMMARIZE_ERR;
142    FINAL_RESULTS;
143 }
144