/* * copy a user-defined compound type in the group igrp to the group ogrp */ static int copy_compound_type(int igrp, nc_type itype, int ogrp) { int stat = NC_NOERR; char name[NC_MAX_NAME]; size_t size; size_t nfields; nc_type otype; int fid; NC_CHECK(nc_inq_compound(igrp, itype, name, &size, &nfields)); NC_CHECK(nc_def_compound(ogrp, size, name, &otype)); for (fid = 0; fid < nfields; fid++) { char fname[NC_MAX_NAME]; char ftypename[NC_MAX_NAME]; size_t foff; nc_type iftype, oftype; int fndims; NC_CHECK(nc_inq_compound_field(igrp, itype, fid, fname, &foff, &iftype, &fndims, NULL)); /* type ids in source don't necessarily correspond to same * typeids in destination, so look up destination typeid by using * field type name */ NC_CHECK(nc_inq_type(igrp, iftype, ftypename, NULL)); NC_CHECK(nc_inq_typeid(ogrp, ftypename, &oftype)); if(fndims == 0) { NC_CHECK(nc_insert_compound(ogrp, otype, fname, foff, oftype)); } else { /* field is array type */ int *fdimsizes; fdimsizes = (int *) emalloc((fndims + 1) * sizeof(int)); stat = nc_inq_compound_field(igrp, itype, fid, NULL, NULL, NULL, NULL, fdimsizes); NC_CHECK(nc_insert_array_compound(ogrp, otype, fname, foff, oftype, fndims, fdimsizes)); free(fdimsizes); } } return stat; }
int nc_inq_compound_nfields(int ncid, nc_type xtype, size_t *nfieldsp) { return nc_inq_compound(ncid,xtype,NULL,NULL,nfieldsp); }
int nc_inq_compound_size(int ncid, nc_type xtype, size_t *sizep) { return nc_inq_compound(ncid,xtype,NULL,sizep,NULL); }
int nc_inq_compound_name(int ncid, nc_type xtype, char *name) { return nc_inq_compound(ncid,xtype,name,NULL,NULL); }
/* Given an ncid, check the file to make sure it has all the objects I * expect. */ int check_nc4_file(int ncid) { int varid, dimid, attnum, grpid, grpid2, grpid3, numgrps; int numtypes, enum_typeid, comp_typeid; int class_in; size_t att_len, size_in, num_mem, nfields_in; nc_type att_type, base_type_in; char name_in[NC_MAX_NAME + 1], strings_in[NC_MAX_NAME + 1], value; /* Check the group. */ if (nc_inq_grps(ncid, &numgrps, &grpid)) ERR; if (numgrps != 1) ERR; name_in[0] = 0; if (nc_inq_grpname(grpid, name_in)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8))) ERR; /* Check the variable. */ if (nc_inq_varid(grpid, name_utf8, &varid)) ERR; if (nc_inq_varname(grpid, varid, name_in)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8))) ERR; if (nc_inq_varid(grpid, norm_utf8, &varid)) ERR; name_in[0] = 0; if (nc_inq_varname(grpid, varid, name_in)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8))) ERR; if (nc_get_var(grpid, varid, strings_in)) ERR; if (strncmp(name_utf8, strings_in, sizeof(name_utf8))) ERR; strings_in[0] = '\0'; /* Reset my string buffer. */ /* Check the dimension. */ if (nc_inq_dimid(grpid, name_utf8, &dimid)) ERR; if (nc_inq_dimname(grpid, dimid, name_in)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8))) ERR; if (nc_inq_dimid(grpid, norm_utf8, &dimid)) ERR; if (nc_inq_dimname(grpid, dimid, name_in)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8))) ERR; /* Check the attribute. We don't normalize data or attribute * values, so get exactly what was put for the value, but * normalized values for names. */ if (nc_inq_attid(grpid, varid, norm_utf8, &attnum)) ERR; if (attnum) ERR; attnum = 99; /* Reset. */ if (nc_inq_attid(grpid, varid, name_utf8, &attnum)) ERR; if (attnum) ERR; if (nc_inq_att(grpid, varid, norm_utf8, &att_type, &att_len)) ERR; if (att_type != NC_CHAR || att_len != sizeof(name_utf8)) ERR; if (nc_get_att_text(grpid, varid, norm_utf8, strings_in)) ERR; if (strncmp(name_utf8, strings_in, sizeof(name_utf8))) ERR; /* Check the enum type. */ if (nc_inq_grps(grpid, &numgrps, &grpid2)) ERR; if (numgrps != 1) ERR; if (nc_inq_typeids(grpid2, &numtypes, &enum_typeid)) ERR; if (numtypes != 1) ERR; if (nc_inq_user_type(grpid2, enum_typeid, name_in, &size_in, &base_type_in, &nfields_in, &class_in)) ERR; if (strncmp(norm_utf8, name_in, strlen(norm_utf8)) || size_in != 1 || base_type_in != NC_BYTE || nfields_in != 1 || class_in != NC_ENUM) ERR; name_in[0] = size_in = base_type_in = 0; if (nc_inq_enum(grpid2, enum_typeid, name_in, &base_type_in, &size_in, &num_mem)) ERR; if (strncmp(norm_utf8, name_in, strlen(norm_utf8)) || size_in != 1 || base_type_in != NC_BYTE || num_mem != 1) ERR; if (nc_inq_enum_member(grpid2, enum_typeid, 0, name_in, &value)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8)) || value != ENUM_VALUE) ERR; /* Check the compound type. */ if (nc_inq_grps(grpid2, &numgrps, &grpid3)) ERR; if (numgrps != 1) ERR; if (nc_inq_typeids(grpid3, &numtypes, &comp_typeid)) ERR; if (numtypes != 1) ERR; name_in[0] = 0; if (nc_inq_user_type(grpid3, comp_typeid, name_in, &size_in, &base_type_in, &nfields_in, &class_in)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8)) || size_in != sizeof(struct comp) || base_type_in != NC_NAT || nfields_in != 1 || class_in != NC_COMPOUND) ERR; size_in = nfields_in = 999; if (nc_inq_compound(grpid3, comp_typeid, name_in, &size_in, &nfields_in)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8)) || size_in != sizeof(struct comp) || nfields_in != 1) ERR; name_in[0] = 0; if (nc_inq_compound_fieldname(grpid3, comp_typeid, 0, name_in)) ERR; if (strncmp(norm_utf8, name_in, sizeof(norm_utf8))) ERR; return NC_NOERR; }
static int NC_meta_create_type1(int ncid, nc_type xtype, MetaNode* root, MetaNode** typenodep) { int ncstat = NC_NOERR; int i; MetaNode* node; nc_meta metatype = NC_NAT; /* Determine the top-level type for xtype */ ncstat = mapnctype(ncid,xtype,&metatype); if(ncstat != NC_NOERR) goto done; node = NC_meta_alloc(metatype); node->ncid = ncid; node->xtype = xtype; switch (node->nodeclass) { case NC_ATOMIC: ncstat = nc_inq_type(ncid,xtype,node->name,&node->size); if(ncstat != NC_NOERR) goto fail; break; case NC_OPAQUE: ncstat = nc_inq_opaque(ncid,xtype,node->name,&node->size); if(ncstat != NC_NOERR) goto fail; break; case NC_ENUM: ncstat = nc_inq_enum(ncid,xtype,node->name,&node->basetype, &node->size,&node->nelems); if(ncstat != NC_NOERR) goto fail; /* Now, create and fill in the enum constants */ node->econsts = (struct MetaEconst*)calloc(node->nelems, sizeof(struct MetaEconst)); if(node->econsts == NULL) {ncstat = NC_ENOMEM;goto fail;} for(i=0;i<node->nelems;i++) { struct MetaEconst* econst = node->consts+i; ncstat = nc_inq_enum_member(ncid,xtype,i, econst->name, (void*)econst->value); if(ncstat != NC_NOERR) goto fail; } break; case NC_COMPOUND: ncstat = nc_inq_compound(ncid,xtype,node->name,&node->size, &node->nelems); if(ncstat != NC_NOERR) goto fail; /* Now, create and fill in the fields */ node->compound.fields = nc_meta_allocn(NC_FIELD,node->nelems); if(node->compound.fields == NULL) {ncstat = NC_ENOMEM;goto fail;} for(i=0;i<node->nelems;i++) { MetaNode* field = node->compound.fields+i; nc_type basetype; ncstat = nc_inq_compound_field(ncid,xtype,i, field->name, &field->offset, &basetype, &field->ndims, field->dims); if(ncstat != NC_NOERR) goto fail; /* create basetype */ ncstat = NC_meta_create_type(ncid,basetype,root,&field->basetype); if(ncstat != NC_NOERR) goto fail; } break; case NC_VLEN: { nc_type basetype; ncstat = nc_inq_vlen(ncid,xtype,node->name,&node->size,&basetype); if(ncstat != NC_NOERR) goto fail; /* create basetype */ ncstat = NC_meta_create_type(ncid,basetype,root,&node->basetype); if(ncstat != NC_NOERR) goto fail; } break; case NC_GROUP: { nc_type* typeids; ncstat = nc_inq_typeids(ncid,&node->nelems,NULL); if(ncstat != NC_NOERR) goto fail; typeids = (nc_type*)calloc(node->nelems,sizeof(nc_type)); if(typeids == NULL) {ncstat = NC_ENOMEM; goto fail;} ncstat = nc_inq_typeids(ncid,&node->nelems,typeids); if(ncstat != NC_NOERR) goto fail; break; default: abort(); } } static int mapnctype(int ncid, nc_type xtype, nc_meta* metatypep) { int ncstat = NC_NOERR; if(metatypep == NULL) goto done; if(xtype <= NC_MAX_ATOMIC_TYPE) goto done; ncstat = nc_inq_user_type(ncid,xtype,NULL,NULL,NULL,NULL,metatypep); done: return ncstat; }