/** * @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; }
/* 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. Drop the bomb on it. You get the idea. Ed Hartnett, 10/1/3 */ int NC4_del_att(int ncid, int varid, const char *name) { NC *nc; NC_GRP_INFO_T *grp; NC_HDF5_FILE_INFO_T *h5; NC_ATT_INFO_T *att, *natt; NC_VAR_INFO_T *var; NC_ATT_INFO_T **attlist = NULL; hid_t locid = 0, datasetid = 0; int retval = NC_NOERR; if (!name) return NC_EINVAL; LOG((2, "nc_del_att: ncid 0x%x varid %d name %s", ncid, varid, name)); /* Find metadata for this file. */ if ((retval = nc4_find_nc_grp_h5(ncid, &nc, &grp, &h5))) return retval; assert(h5 && grp); /* If the file is read-only, return an error. */ if (h5->no_write) return NC_EPERM; #if 0 /*def USE_PNETCDF*/ /* Take care of files created/opened with parallel-netcdf library. */ if (h5->pnetcdf_file) return ncmpi_del_att(nc->int_ncid, varid, name); #endif /* USE_PNETCDF */ /* If it's not in define mode, forget it. */ if (!(h5->flags & NC_INDEF)) { if (h5->cmode & NC_CLASSIC_MODEL) return NC_ENOTINDEFINE; if ((retval = NC4_redef(ncid))) BAIL(retval); } /* Get either the global or a variable attribute list. Also figure out the HDF5 location it's attached to. */ if (varid == NC_GLOBAL) { attlist = &grp->att; locid = grp->hdf_grpid; } else { for(var = grp->var; var; var = var->l.next) { if (var->varid == varid) { attlist = &var->att; break; } } if (!var) return NC_ENOTVAR; if (var->created) locid = var->hdf_datasetid; } /* Now find the attribute by name or number. */ for (att = *attlist; att; att = att->l.next) if (!strcmp(att->name, name)) break; /* If att is NULL, we couldn't find the attribute. */ if (!att) BAIL_QUIET(NC_ENOTATT); /* Delete it from the HDF5 file, if it's been created. */ if (att->created) { assert(locid); if(H5Adelete(locid, att->name) < 0) BAIL(NC_EATTMETA); } /* Renumber all following attributes. */ for (natt = att->l.next; natt; natt = natt->l.next) natt->attnum--; /* Delete this attribute from this list. */ if ((retval = nc4_att_list_del(attlist, att))) BAIL(retval); exit: if (datasetid > 0) H5Dclose(datasetid); return retval; }