/* * copy a user-defined enum type in the group igrp to the group ogrp */ static int copy_enum_type(int igrp, nc_type itype, int ogrp) { int stat = NC_NOERR; nc_type otype; nc_type basetype; size_t basesize; size_t nmembers; char name[NC_MAX_NAME]; int i; NC_CHECK(nc_inq_enum(igrp, itype, name, &basetype, &basesize, &nmembers)); NC_CHECK(nc_def_enum(ogrp, basetype, name, &otype)); for(i = 0; i < nmembers; i++) { /* insert enum members */ char ename[NC_MAX_NAME]; long long val; /* large enough to hold any integer type */ NC_CHECK(nc_inq_enum_member(igrp, itype, i, ename, &val)); NC_CHECK(nc_insert_enum(ogrp, otype, ename, &val)); } return stat; }
/* Generate type definitions */ static void genbin_deftype(Symbol* tsym) { int i,stat; ASSERT(tsym->objectclass == NC_TYPE); switch (tsym->subclass) { case NC_PRIM: break; /* these are already taken care of*/ case NC_OPAQUE: stat = nc_def_opaque(tsym->container->ncid, tsym->typ.size, tsym->name, &tsym->ncid); check_err(stat,__LINE__,__FILE__); break; case NC_ENUM: { Bytebuffer* datum; Datalist* ecdl; stat = nc_def_enum(tsym->container->ncid, tsym->typ.basetype->typ.typecode, tsym->name, &tsym->ncid); check_err(stat,__LINE__,__FILE__); datum = bbNew(); ecdl = builddatalist(1); dlextend(ecdl); /* make room for one constant*/ ecdl->length = 1; for(i=0;i<listlength(tsym->subnodes);i++) { Symbol* econst = (Symbol*)listget(tsym->subnodes,i); ASSERT(econst->subclass == NC_ECONST); generator_reset(bin_generator,NULL); bbClear(datum); generate_basetype(econst->typ.basetype,&econst->typ.econst,datum,NULL,bin_generator); stat = nc_insert_enum(tsym->container->ncid, tsym->ncid, econst->name, bbContents(datum)); check_err(stat,__LINE__,__FILE__); } bbFree(datum); dlfree(&ecdl); } break; case NC_VLEN: stat = nc_def_vlen(tsym->container->ncid, tsym->name, tsym->typ.basetype->ncid, &tsym->ncid); check_err(stat,__LINE__,__FILE__); break; case NC_COMPOUND: stat = nc_def_compound(tsym->container->ncid, tsym->typ.size, tsym->name, &tsym->ncid); check_err(stat,__LINE__,__FILE__); for(i=0;i<listlength(tsym->subnodes);i++) { Symbol* efield = (Symbol*)listget(tsym->subnodes,i); ASSERT(efield->subclass == NC_FIELD); if(efield->typ.dimset.ndims == 0){ stat = nc_insert_compound( tsym->container->ncid, tsym->ncid, efield->name, efield->typ.offset, efield->typ.basetype->ncid); } else { int j; int dimsizes[NC_MAX_VAR_DIMS]; /* Generate the field dimension constants*/ for(j=0;j<efield->typ.dimset.ndims;j++) { unsigned int size = efield->typ.dimset.dimsyms[j]->dim.declsize; dimsizes[j] = size; } stat = nc_insert_array_compound( tsym->container->ncid, tsym->ncid, efield->name, efield->typ.offset, efield->typ.basetype->ncid, efield->typ.dimset.ndims, dimsizes); } check_err(stat,__LINE__,__FILE__); } break; default: panic("definectype: unexpected type subclass"); } }
int main(int argc, char **argv) { printf("\n*** Testing UTF-8 names.\n"); printf("*** creating UTF-8 names in classic model netcdf files..."); { int ncid, varid, dimids[NDIMS]; int f; for (f = NC_FORMAT_CLASSIC; f < NC_FORMAT_NETCDF4_CLASSIC; f++) { if (nc_set_default_format(f, NULL)) ERR; if (nc_create(FILE_NAME, NC_CLOBBER, &ncid)) ERR; /* Define various netcdf objects with a Unicode UTF-8 encoded name * that must be normalized. Where possible, also use the utf8 * string as the value. The name will be normalized, but not the * value. */ if (nc_def_dim(ncid, name_utf8, NX, &dimids[0])) ERR; if (nc_def_var(ncid, name_utf8, NC_CHAR, NDIMS, dimids, &varid)) ERR; if (nc_put_att_text(ncid, varid, name_utf8, sizeof(name_utf8), name_utf8)) ERR; if (nc_enddef(ncid)) ERR; /* Write var data. */ if (nc_put_var_text(ncid, varid, name_utf8)) ERR; /* Check the file. */ check_classic_file(ncid); if (nc_close(ncid)) ERR; /* Reopen the file and check again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; check_classic_file(ncid); if (nc_close(ncid)) ERR; } /* next format */ } SUMMARIZE_ERR; #define DIM1_NAME "d1" #define VAR1_NAME "v1" #define ATT1_NAME "a1" printf("*** renaming to UTF-8 names in classic model netcdf files..."); { int ncid, varid, dimids[NDIMS]; int f; for (f = NC_FORMAT_CLASSIC; f < NC_FORMAT_NETCDF4_CLASSIC; f++) { if (nc_set_default_format(f, NULL)) ERR; if (nc_create(FILE_NAME, NC_CLOBBER, &ncid)) ERR; /* Create objects. */ if (nc_def_dim(ncid, DIM1_NAME, NX, &dimids[0])) ERR; if (nc_rename_dim(ncid, 0, name_utf8)) ERR; if (nc_def_var(ncid, name_utf8, NC_CHAR, NDIMS, dimids, &varid)) ERR; if (nc_put_att_text(ncid, varid, ATT1_NAME, sizeof(name_utf8), name_utf8)) ERR; if (nc_rename_att(ncid, 0, ATT1_NAME, name_utf8)) ERR; if (nc_enddef(ncid)) ERR; /* Write var data. */ if (nc_put_var_text(ncid, varid, name_utf8)) ERR; /* Check the file. */ check_classic_file(ncid); if (nc_close(ncid)) ERR; /* Reopen the file and check again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; check_classic_file(ncid); if (nc_close(ncid)) ERR; } /* next format */ } SUMMARIZE_ERR; printf("*** creating UTF-8 names in netcdf-4 file..."); { int ncid, varid, grpid, comp_typeid, enum_typeid, grpid2, grpid3; int dimids[NDIMS]; char my_int = ENUM_VALUE; if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR; /* Define various netcdf objects with a Unicode UTF-8 encoded name * that must be normalized. Where possible, also use the utf8 * string as the value. The name will be normalized, but not the * value. */ if (nc_def_grp(ncid, name_utf8, &grpid)) ERR; if (nc_def_dim(grpid, name_utf8, NX, &dimids[0])) ERR; if (nc_def_var(grpid, name_utf8, NC_CHAR, NDIMS, dimids, &varid)) ERR; if (nc_put_att_text(grpid, varid, name_utf8, sizeof(name_utf8), name_utf8)) ERR; if (nc_def_grp(grpid, "tmp", &grpid2)) ERR; if (nc_def_enum(grpid2, NC_BYTE, name_utf8, &enum_typeid)) ERR; if (nc_insert_enum(grpid2, enum_typeid, name_utf8, &my_int)) ERR; if (nc_def_grp(grpid2, "tmp", &grpid3)) ERR; if (nc_def_compound(grpid3, sizeof(struct comp), name_utf8, &comp_typeid)) ERR; if (nc_insert_compound(grpid3, comp_typeid, name_utf8, offsetof(struct comp, i), NC_INT)) ERR; /* Write var data. */ if (nc_put_var_text(grpid, varid, name_utf8)) ERR; /* Check the file. */ check_nc4_file(ncid); if (nc_close(ncid)) ERR; /* Reopen the file and check again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; check_nc4_file(ncid); if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; printf("*** ensuring UTF-8 normaization is applied in rename..."); { int ncid, varid; char name_in[NC_MAX_NAME + 1]; if (nc_create(FILE_NAME, NC_NETCDF4 | NC_CLOBBER, &ncid)) ERR; if (nc_def_var(ncid, BORING_NAME, NC_CHAR, 0, NULL, &varid)) ERR; if (nc_rename_var(ncid, varid, name_utf8)) ERR; if (nc_inq_varname(ncid, 0, name_in)) ERR; if (!strcmp(name_in, norm_utf8)) ERR; if (nc_close(ncid)) ERR; /* Reopen the file and check again. */ if (nc_open(FILE_NAME, NC_NOWRITE, &ncid)) ERR; if (nc_inq_varname(ncid, 0, name_in)) ERR; if (!strcmp(name_in, norm_utf8)) ERR; if (nc_close(ncid)) ERR; } SUMMARIZE_ERR; FINAL_RESULTS; }
int main() {/* create tst_diskless2.nc */ int stat; /* return status */ int ncid; /* netCDF id */ /* group ids */ int root_grp; int g_grp; int h_grp; /* type ids */ int enum_t_typ; int opaque_t_typ; int vlen_t_typ; int g_cmpd_t_typ; /* dimension ids */ int lat_dim; int lon_dim; int time_dim; /* dimension lengths */ size_t lat_len = 10; size_t lon_len = 5; size_t time_len = NC_UNLIMITED; /* variable ids */ int lat_id; int lon_id; int time_id; int Z_id; int t_id; int p_id; int rh_id; int country_id; int tag_id; int h_compoundvar_id; /* rank (number of dimensions) for each variable */ # define RANK_lat 1 # define RANK_lon 1 # define RANK_time 1 # define RANK_Z 3 # define RANK_t 3 # define RANK_p 3 # define RANK_rh 3 # define RANK_country 3 # define RANK_tag 0 # define RANK_h_compoundvar 0 /* variable shapes */ int lat_dims[RANK_lat]; int lon_dims[RANK_lon]; int time_dims[RANK_time]; int Z_dims[RANK_Z]; int t_dims[RANK_t]; int p_dims[RANK_p]; int rh_dims[RANK_rh]; int country_dims[RANK_country]; /* enter define mode */ stat = nc_create("tst_diskless2.nc", NC_DISKLESS|NC_WRITE|NC_CLOBBER|NC_NETCDF4, &ncid); check_err(stat,__LINE__,__FILE__); root_grp = ncid; stat = nc_def_grp(root_grp, "g", &g_grp); check_err(stat,__LINE__,__FILE__); stat = nc_def_grp(root_grp, "h", &h_grp); check_err(stat,__LINE__,__FILE__); { unsigned char econst; stat = nc_def_enum(root_grp, NC_UBYTE, "enum_t", &enum_t_typ); check_err(stat,__LINE__,__FILE__); econst = 0; stat = nc_insert_enum(root_grp, enum_t_typ, "Clear", &econst); check_err(stat,__LINE__,__FILE__); econst = 1; stat = nc_insert_enum(root_grp, enum_t_typ, "Cumulonimbus", &econst); check_err(stat,__LINE__,__FILE__); econst = 2; stat = nc_insert_enum(root_grp, enum_t_typ, "Stratus", &econst); check_err(stat,__LINE__,__FILE__); } stat = nc_def_opaque(root_grp, 11, "opaque_t", &opaque_t_typ); check_err(stat,__LINE__,__FILE__); stat = nc_def_vlen(root_grp, "vlen_t", NC_INT, &vlen_t_typ); check_err(stat,__LINE__,__FILE__); stat = nc_def_compound(g_grp, sizeof(g_cmpd_t), "cmpd_t", &g_cmpd_t_typ); check_err(stat,__LINE__,__FILE__); { stat = nc_insert_compound(g_grp, g_cmpd_t_typ, "f1", NC_COMPOUND_OFFSET(g_cmpd_t,f1), vlen_t_typ); check_err(stat,__LINE__,__FILE__); stat = nc_insert_compound(g_grp, g_cmpd_t_typ, "f2", NC_COMPOUND_OFFSET(g_cmpd_t,f2), enum_t_typ); check_err(stat,__LINE__,__FILE__); } /* define dimensions */ stat = nc_def_dim(root_grp, "lat", lat_len, &lat_dim); check_err(stat,__LINE__,__FILE__); stat = nc_def_dim(root_grp, "lon", lon_len, &lon_dim); check_err(stat,__LINE__,__FILE__); stat = nc_def_dim(root_grp, "time", time_len, &time_dim); check_err(stat,__LINE__,__FILE__); /* define variables */ lat_dims[0] = lat_dim; stat = nc_def_var(root_grp, "lat", NC_INT, RANK_lat, lat_dims, &lat_id); check_err(stat,__LINE__,__FILE__); lon_dims[0] = lon_dim; stat = nc_def_var(root_grp, "lon", NC_INT, RANK_lon, lon_dims, &lon_id); check_err(stat,__LINE__,__FILE__); time_dims[0] = time_dim; stat = nc_def_var(root_grp, "time", NC_INT, RANK_time, time_dims, &time_id); check_err(stat,__LINE__,__FILE__); Z_dims[0] = time_dim; Z_dims[1] = lat_dim; Z_dims[2] = lon_dim; stat = nc_def_var(root_grp, "Z", NC_FLOAT, RANK_Z, Z_dims, &Z_id); check_err(stat,__LINE__,__FILE__); t_dims[0] = time_dim; t_dims[1] = lat_dim; t_dims[2] = lon_dim; stat = nc_def_var(root_grp, "t", NC_FLOAT, RANK_t, t_dims, &t_id); check_err(stat,__LINE__,__FILE__); p_dims[0] = time_dim; p_dims[1] = lat_dim; p_dims[2] = lon_dim; stat = nc_def_var(root_grp, "p", NC_DOUBLE, RANK_p, p_dims, &p_id); check_err(stat,__LINE__,__FILE__); rh_dims[0] = time_dim; rh_dims[1] = lat_dim; rh_dims[2] = lon_dim; stat = nc_def_var(root_grp, "rh", NC_INT, RANK_rh, rh_dims, &rh_id); check_err(stat,__LINE__,__FILE__); country_dims[0] = time_dim; country_dims[1] = lat_dim; country_dims[2] = lon_dim; stat = nc_def_var(root_grp, "country", NC_STRING, RANK_country, country_dims, &country_id); check_err(stat,__LINE__,__FILE__); stat = nc_def_var(root_grp, "tag", NC_UBYTE, RANK_tag, 0, &tag_id); check_err(stat,__LINE__,__FILE__); stat = nc_def_var(h_grp, "compoundvar", g_cmpd_t_typ, RANK_h_compoundvar, 0, &h_compoundvar_id); check_err(stat,__LINE__,__FILE__); /* assign global attributes */ { static const int vlen_2[] = {17, 18, 19} ; static const vlen_t globalatt_att[1] = {{3, (void*)vlen_2}} ; stat = nc_put_att(root_grp, NC_GLOBAL, "globalatt", vlen_t_typ, 1, globalatt_att); check_err(stat,__LINE__,__FILE__); } /* assign per-variable attributes */ { stat = nc_put_att_text(root_grp, lat_id, "long_name", 8, "latitude"); check_err(stat,__LINE__,__FILE__); } { stat = nc_put_att_text(root_grp, lat_id, "units", 13, "degrees_north"); check_err(stat,__LINE__,__FILE__); } { stat = nc_put_att_text(root_grp, lon_id, "long_name", 9, "longitude"); check_err(stat,__LINE__,__FILE__); } { stat = nc_put_att_text(root_grp, lon_id, "units", 12, "degrees_east"); check_err(stat,__LINE__,__FILE__); } { stat = nc_put_att_text(root_grp, time_id, "units", 31, "seconds since 1992-1-1 00:00:00"); check_err(stat,__LINE__,__FILE__); } { static const char* Z_units_att[1] = {"geopotential meters"} ; stat = nc_put_att_string(root_grp, Z_id, "units", 1, Z_units_att); check_err(stat,__LINE__,__FILE__); } { static const float Z_valid_range_att[2] = {((float)0), ((float)5000)} ; stat = nc_put_att_float(root_grp, Z_id, "valid_range", NC_FLOAT, 2, Z_valid_range_att); check_err(stat,__LINE__,__FILE__); } { static const double p_FillValue_att[1] = {((double)-9999)} ; stat = nc_put_att_double(root_grp, p_id, "_FillValue", NC_DOUBLE, 1, p_FillValue_att); check_err(stat,__LINE__,__FILE__); } { static const int rh_FillValue_att[1] = {-1} ; stat = nc_put_att_int(root_grp, rh_id, "_FillValue", NC_INT, 1, rh_FillValue_att); check_err(stat,__LINE__,__FILE__); } /* leave define mode */ stat = nc_enddef (root_grp); check_err(stat,__LINE__,__FILE__); /* assign variable data */ { int lat_data[10] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90} ; size_t lat_startset[1] = {0} ; size_t lat_countset[1] = {10}; stat = nc_put_vara(root_grp, lat_id, lat_startset, lat_countset, lat_data); check_err(stat,__LINE__,__FILE__); } { int lon_data[5] = {-140, -118, -96, -84, -52} ; size_t lon_startset[1] = {0} ; size_t lon_countset[1] = {5}; stat = nc_put_vara(root_grp, lon_id, lon_startset, lon_countset, lon_data); check_err(stat,__LINE__,__FILE__); } { static const int vlen_10[] = {3, 4, 5} ; size_t zero = 0; static g_cmpd_t h_compoundvar_data[1] = {{{3, (void*)vlen_10}, 2}}; stat = nc_put_var1(h_grp, h_compoundvar_id, &zero, h_compoundvar_data); check_err(stat,__LINE__,__FILE__); } stat = nc_close(root_grp); check_err(stat,__LINE__,__FILE__); return 0; }