/* Rename a dimension, for those who like to prevaricate. */ int NC4_rename_dim(int ncid, int dimid, const char *name) { NC_FILE_INFO_T *nc; NC_GRP_INFO_T *grp; NC_HDF5_FILE_INFO_T *h5; NC_DIM_INFO_T *dim; char norm_name[NC_MAX_NAME + 1]; int retval; if (!name) return NC_EINVAL; LOG((2, "nc_rename_dim: ncid 0x%x dimid %d name %s", ncid, dimid, name)); /* 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(nc); #ifdef USE_PNETCDF /* Take care of files created/opened with parallel-netcdf library. */ if (nc->pnetcdf_file) return ncmpi_rename_dim(nc->int_ncid, dimid, name); #endif /* USE_PNETCDF */ /* Handle netcdf-3 cases. */ assert(h5); assert(h5 && grp); /* Trying to write to a read-only file? No way, Jose! */ if (h5->no_write) return NC_EPERM; /* Make sure this is a valid netcdf name. */ if ((retval = nc4_check_name(name, norm_name))) return retval; /* Make sure the new name is not already in use in this group. */ for (dim = grp->dim; dim; dim = dim->next) if (!strncmp(dim->name, norm_name, NC_MAX_NAME)) return NC_ENAMEINUSE; /* Find the dim. */ for (dim = grp->dim; dim; dim = dim->next) if (dim->dimid == dimid) break; if (!dim) return NC_EBADDIM; /* If not in define mode, switch to it, unless the new name is * shorter. (This is in accordance with the v3 interface.) */ /* if (!(h5->flags & NC_INDEF) && strlen(name) > strlen(dim->name)) */ /* { */ /* if (h5->cmode & NC_CLASSIC_MODEL) */ /* return NC_ENOTINDEFINE; */ /* if ((retval = nc_redef(ncid))) */ /* return retval; */ /* } */ /* Save the old name, we'll need it to rename this object when we * sync to HDF5 file. But if there already is an old_name saved, * just stick with what we've got, since the user might be renaming * the crap out of this thing, without ever syncing with the * file. When the sync does take place, we only need the original * name of the dim, not any of the intermediate ones. If the user * could just make up his mind, we could all get on to writing some * data... */ if (!dim->old_name) { if (!(dim->old_name = malloc((strlen(dim->name) + 1) * sizeof(char)))) return NC_ENOMEM; strcpy(dim->old_name, dim->name); } /* Give the dimension its new name in metadata. UTF8 normalization * has been done. */ free(dim->name); if (!(dim->name = malloc((strlen(norm_name) + 1) * sizeof(char)))) return NC_ENOMEM; strcpy(dim->name, norm_name); return NC_NOERR; }
/* Rename a dimension, for those who like to prevaricate. */ int NC4_rename_dim(int ncid, int dimid, const char *name) { NC *nc; NC_GRP_INFO_T *grp; NC_HDF5_FILE_INFO_T *h5; NC_DIM_INFO_T *dim, *tmp_dim; char norm_name[NC_MAX_NAME + 1]; int retval; if (!name) return NC_EINVAL; LOG((2, "%s: ncid 0x%x dimid %d name %s", __func__, ncid, dimid, name)); /* 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(nc); assert(h5 && grp); /* Trying to write to a read-only file? No way, Jose! */ 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_rename_dim(nc->int_ncid, dimid, name); #endif /* USE_PNETCDF */ /* Make sure this is a valid netcdf name. */ if ((retval = nc4_check_name(name, norm_name))) return retval; /* Check if name is in use, and retain a pointer to the correct dim */ tmp_dim = NULL; for (dim = grp->dim; dim; dim = dim->l.next) { if (!strncmp(dim->name, norm_name, NC_MAX_NAME)) return NC_ENAMEINUSE; if (dim->dimid == dimid) tmp_dim = dim; } if (!tmp_dim) return NC_EBADDIM; dim = tmp_dim; /* Check for renaming dimension w/o variable */ if (dim->hdf_dimscaleid) { /* Sanity check */ assert(!dim->coord_var); /* Close the HDF5 dataset */ if (H5Dclose(dim->hdf_dimscaleid) < 0) return NC_EHDFERR; dim->hdf_dimscaleid = 0; /* Now delete the dataset (it will be recreated later, if necessary) */ if (H5Gunlink(grp->hdf_grpid, dim->name) < 0) return NC_EDIMMETA; } /* Give the dimension its new name in metadata. UTF8 normalization * has been done. */ if(dim->name) free(dim->name); if (!(dim->name = malloc((strlen(norm_name) + 1) * sizeof(char)))) return NC_ENOMEM; strcpy(dim->name, norm_name); /* Check if dimension was a coordinate variable, but names are different now */ if (dim->coord_var && strcmp(dim->name, dim->coord_var->name)) { /* Break up the coordinate variable */ if ((retval = nc4_break_coord_var(grp, dim->coord_var, dim))) return retval; } /* Check if dimension should become a coordinate variable */ if (!dim->coord_var) { NC_VAR_INFO_T *var; /* Attempt to find a variable with the same name as the dimension in * the current group. */ if ((retval = nc4_find_var(grp, dim->name, &var))) return retval; /* Check if we found a variable and the variable has the dimension in * index 0. */ if (var && var->dim[0] == dim) { /* Sanity check */ assert(var->dimids[0] == dim->dimid); /* Reform the coordinate variable */ if ((retval = nc4_reform_coord_var(grp, var, dim))) return retval; } } return NC_NOERR; }