/* * copy a user-defined variable length type in the group igrp to the * group ogrp */ static int copy_vlen_type(int igrp, nc_type itype, int ogrp) { int stat = NC_NOERR; nc_type ibasetype; nc_type obasetype; /* base type in target group */ char name[NC_MAX_NAME]; size_t size; char basename[NC_MAX_NAME]; size_t basesize; nc_type vlen_type; NC_CHECK(nc_inq_vlen(igrp, itype, name, &size, &ibasetype)); /* to get base type id in target group, use name of base type in * source group */ NC_CHECK(nc_inq_type(igrp, ibasetype, basename, &basesize)); stat = nc_inq_typeid(ogrp, basename, &obasetype); /* if no such type, create it now */ if(stat == NC_EBADTYPE) { NC_CHECK(copy_type(igrp, ibasetype, ogrp)); stat = nc_inq_typeid(ogrp, basename, &obasetype); } NC_CHECK(stat); /* Now we know base type exists in output and we know its type id */ NC_CHECK(nc_def_vlen(ogrp, name, obasetype, &vlen_type)); return stat; }
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; }