/** * @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; }
/* Find all dimids for a location. This finds all dimensions in a * group, with or without any of its parents, depending on last * parameter. */ int NC4_inq_dimids(int ncid, int *ndims, int *dimids, int include_parents) { NC_GRP_INFO_T *grp, *g; NC_HDF5_FILE_INFO_T *h5; NC_DIM_INFO_T *dim; int d, num = 0; int retval; LOG((2, "nc_inq_dimids: ncid 0x%x include_parents: %d", ncid, include_parents)); /* Find info for this file and group, and set pointer to each. */ if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) return retval; if (!h5) { /* If this is a netcdf-3 file, then the dimids are going to be 0 * thru ndims-1, so just provide them. */ if ((retval = nc_inq(ncid, &num, NULL, NULL, NULL))) return retval; if (dimids) for (d = 0; d < num; d++) dimids[d] = d; } else { /* First count them. */ for (dim = grp->dim; dim; dim = dim->next) num++; if (include_parents) for (g = grp->parent; g; g = g->parent) for (dim = g->dim; dim; dim = dim->next) num++; /* If the user wants the dimension ids, get them. */ if (dimids) { int n = 0; /* Get dimension ids from this group. */ for (dim = grp->dim; dim; dim = dim->next) dimids[n++] = dim->dimid; /* Get dimension ids from parent groups. */ if (include_parents) for (g = grp->parent; g; g = g->parent) for (dim = g->dim; dim; dim = dim->next) dimids[n++] = dim->dimid; qsort(dimids, num, sizeof(int), int_cmp); } } /* If the user wants the number of dims, give it. */ if (ndims) *ndims = num; return NC_NOERR; }