/** * @internal Find all user-defined types for a location. This finds * all user-defined types in a group. * * @param ncid File and group ID. * @param ntypes Pointer that gets the number of user-defined * types. Ignored if NULL * @param typeids Array that gets the typeids. Ignored if NULL. * * @return ::NC_NOERR No error. * @return ::NC_EBADID Bad ncid. * @author Ed Hartnett */ int NC4_inq_typeids(int ncid, int *ntypes, int *typeids) { NC_GRP_INFO_T *grp; NC_FILE_INFO_T *h5; NC_TYPE_INFO_T *type; int num = 0; int retval; LOG((2, "nc_inq_typeids: ncid 0x%x", ncid)); /* Find info for this file and group, and set pointer to each. */ if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) return retval; assert(h5 && grp); /* Count types. */ if (grp->type) { int i; for(i=0;i<ncindexsize(grp->type);i++) { if((type = (NC_TYPE_INFO_T*)ncindexith(grp->type,i)) == NULL) continue; if (typeids) typeids[num] = type->hdr.id; num++; } } /* Give the count to the user. */ if (ntypes) *ntypes = num; return NC_NOERR; }
/** * @internal Netcdf-4 files might have more than one unlimited * dimension, but return the first one anyway. * * @note that this code is inconsistent with nc_inq * * @param ncid File and group ID. * @param unlimdimidp Pointer that gets ID of first unlimited * dimension, or -1. * * @return ::NC_NOERR No error. * @return ::NC_EBADID Bad ncid. * @author Ed Hartnett */ int NC4_inq_unlimdim(int ncid, int *unlimdimidp) { NC *nc; NC_GRP_INFO_T *grp, *g; NC_FILE_INFO_T *h5; NC_DIM_INFO_T *dim; int found = 0; int retval; int i; LOG((2, "%s: called", __func__)); if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) return retval; assert(h5 && nc && grp); if (unlimdimidp) { /* According to netcdf-3 manual, return -1 if there is no unlimited dimension. */ *unlimdimidp = -1; for (g = grp; g && !found; g = g->parent) { for(i=0;i<ncindexsize(grp->dim);i++) { dim = (NC_DIM_INFO_T*)ncindexith(grp->dim,i); if(dim == NULL) continue; if (dim->unlimited) { *unlimdimidp = dim->hdr.id; found++; break; } } } } return NC_NOERR; }
/** * @internal Returns an array of unlimited dimension ids.The user can * get the number of unlimited dimensions by first calling this with * NULL for the second pointer. * * @param ncid File and group ID. * @param nunlimdimsp Pointer that gets the number of unlimited * dimensions. Ignored if NULL. * @param unlimdimidsp Pointer that gets arrray of unlimited dimension * ID. Ignored if NULL. * * @return ::NC_NOERR No error. * @return ::NC_EBADID Bad ncid. * @author Ed Hartnett, Dennis Heimbigner */ int NC4_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp) { NC_DIM_INFO_T *dim; NC_GRP_INFO_T *grp; NC *nc; NC_FILE_INFO_T *h5; int num_unlim = 0; int retval; int i; LOG((2, "%s: ncid 0x%x", __func__, ncid)); /* Find info for this file and group, and set pointer to each. */ if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) return retval; assert(h5 && nc && grp); /* Get our dim info. */ assert(h5); { for(i=0;i<ncindexsize(grp->dim);i++) { dim = (NC_DIM_INFO_T*)ncindexith(grp->dim,i); if(dim == NULL) continue; if (dim->unlimited) { if (unlimdimidsp) unlimdimidsp[num_unlim] = dim->hdr.id; num_unlim++; } } } /* Give the number if the user wants it. */ if (nunlimdimsp) *nunlimdimsp = num_unlim; return NC_NOERR; }
/** * @internal Delete an att. Rub it out. Push the button on * it. Liquidate it. Bump it off. Take it for a one-way * ride. Terminate it. * * @param ncid File and group ID. * @param varid Variable ID. * @param name Name of attribute to delete. * * @return ::NC_NOERR No error. * @return ::NC_EBADID Bad ncid. * @return ::NC_ENOTATT Attribute not found. * @return ::NC_EINVAL No name provided. * @return ::NC_EPERM File is read only. * @return ::NC_ENOTINDEFINE Classic model not in define mode. * @return ::NC_EINTERNAL Could not rebuild list. * @author Ed Hartnett, Dennis Heimbigner */ int NC4_del_att(int ncid, int varid, const char *name) { NC_GRP_INFO_T *grp; NC_VAR_INFO_T *var; NC_FILE_INFO_T *h5; NC_ATT_INFO_T *att; NCindex* attlist = NULL; hid_t locid = 0; int i; size_t deletedid; int retval; /* Name must be provided. */ if (!name) return NC_EINVAL; LOG((2, "nc_del_att: ncid 0x%x varid %d name %s", ncid, varid, name)); /* Find info for this file, group, and h5 info. */ if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) return retval; assert(h5 && grp); /* If the file is read-only, return an error. */ if (h5->no_write) return NC_EPERM; /* If file is not in define mode, return error for classic model * files, otherwise switch to define mode. */ if (!(h5->flags & NC_INDEF)) { if (h5->cmode & NC_CLASSIC_MODEL) return NC_ENOTINDEFINE; if ((retval = NC4_redef(ncid))) return retval; } /* Get either the global or a variable attribute list. */ if ((retval = getattlist(grp, varid, &var, &attlist))) return retval; /* Determine the location id in the HDF5 file. */ if (varid == NC_GLOBAL) locid = ((NC_HDF5_GRP_INFO_T *)(grp->format_grp_info))->hdf_grpid; else if (var->created) locid = var->hdf_datasetid; /* Now find the attribute by name. */ if (!(att = (NC_ATT_INFO_T*)ncindexlookup(attlist, name))) return NC_ENOTATT; /* Delete it from the HDF5 file, if it's been created. */ if (att->created) { assert(locid); if (H5Adelete(locid, att->hdr.name) < 0) return NC_EATTMETA; } deletedid = att->hdr.id; /* Remove this attribute in this list */ if ((retval = nc4_att_list_del(attlist, att))) return retval; /* Renumber all attributes with higher indices. */ for (i = 0; i < ncindexsize(attlist); i++) { NC_ATT_INFO_T *a; if (!(a = (NC_ATT_INFO_T *)ncindexith(attlist, i))) continue; if (a->hdr.id > deletedid) a->hdr.id--; } /* Rebuild the index. */ if (!ncindexrebuild(attlist)) return NC_EINTERNAL; return NC_NOERR; }