/* This internal function adds a new user defined type to the metadata * of a group of an open file. */ static int add_user_type(int ncid, size_t size, const char *name, nc_type base_typeid, nc_type type_class, nc_type *typeidp) { NC_HDF5_FILE_INFO_T *h5; NC_GRP_INFO_T *grp; char norm_name[NC_MAX_NAME + 1]; int retval; /* Check and normalize the name. */ if ((retval = nc4_check_name(name, norm_name))) return retval; LOG((2, "add_user_type: ncid 0x%x size %d name %s base_typeid %d ", ncid, size, norm_name, base_typeid)); /* Find group metadata. */ if ((retval = nc4_find_grp_h5(ncid, &grp, &h5))) return retval; /* Only netcdf-4 files! */ if (!h5) return NC_ENOTNC4; /* Turn on define mode if it is not on. */ if (!(h5->cmode & NC_INDEF)) if ((retval = nc_redef(ncid))) return retval; /* No size is provided for vlens or enums, get it from the base type. */ if (type_class == NC_VLEN || type_class == NC_ENUM) { if ((retval = nc4_get_typelen_mem(grp->file->nc4_info, base_typeid, 0, &size))) return retval; } else if (size <= 0) return NC_EINVAL; /* Check that this name is not in use as a var, grp, or type. */ if ((retval = nc4_check_dup_name(grp, norm_name))) return retval; /* Add to our list of types. */ if ((retval = nc4_type_list_add(&(grp->type), grp->file->nc4_info->next_typeid, size, norm_name, type_class, base_typeid))) return retval; /* Return the typeid to the user. */ if (typeidp) *typeidp = grp->file->nc4_info->next_typeid; grp->file->nc4_info->next_typeid++; return NC_NOERR; }
/* Create a group. It's ncid is returned in the new_ncid pointer. */ int NC4_def_grp(int parent_ncid, const char *name, int *new_ncid) { NC_GRP_INFO_T *grp, *g; NC_HDF5_FILE_INFO_T *h5; char norm_name[NC_MAX_NAME + 1]; int retval; LOG((2, "%s: parent_ncid 0x%x name %s", __func__, parent_ncid, name)); /* Find info for this file and group, and set pointer to each. */ if ((retval = nc4_find_grp_h5(parent_ncid, &grp, &h5))) return retval; if (!h5) return NC_ENOTNC4; /* Check and normalize the name. */ if ((retval = nc4_check_name(name, norm_name))) return retval; /* Check that this name is not in use as a var, grp, or type. */ if ((retval = nc4_check_dup_name(grp, norm_name))) return retval; /* No groups in netcdf-3! */ if (h5->cmode & NC_CLASSIC_MODEL) return NC_ESTRICTNC3; /* If it's not in define mode, switch to define mode. */ if (!(h5->flags & NC_INDEF)) if ((retval = NC4_redef(parent_ncid))) return retval; /* Update internal lists to reflect new group. The actual HDF5 * group creation will be done when metadata is written by a * sync. */ if ((retval = nc4_grp_list_add(&(grp->children), h5->next_nc_grpid, grp, grp->nc4_info->controller, norm_name, &g))) return retval; if (new_ncid) *new_ncid = grp->nc4_info->controller->ext_ncid | h5->next_nc_grpid; h5->next_nc_grpid++; return NC_NOERR; }
/* Rename a group. */ int NC4_rename_grp(int grpid, const char *name) { NC_GRP_INFO_T *grp, *g; NC_HDF5_FILE_INFO_T *h5; char norm_name[NC_MAX_NAME + 1]; int retval; LOG((2, "nc_rename_grp: grpid 0x%x name %s", grpid, name)); /* Find info for this file and group, and set pointer to each. */ if ((retval = nc4_find_grp_h5(grpid, &grp, &h5))) return retval; if (!h5) return NC_ENOTNC4; if (h5->no_write) return NC_EPERM; /* attempt to write to a read-only file */ /* Do not allow renaming the root group */ if(grp->parent == NULL) return NC_EBADGRPID; /* Check and normalize the name. */ if ((retval = nc4_check_name(name, norm_name))) return retval; /* Check that this name is not in use as a var, grp, or type. */ if ((retval = nc4_check_dup_name(grp, norm_name))) return retval; /* If it's not in define mode, switch to define mode. */ if (!(h5->flags & NC_INDEF)) if ((retval = NC4_redef(grpid))) return retval; /* Rename the group, if it exists in the file */ if (grp->hdf_grpid) { /* Close the group */ if (H5Gclose(grp->hdf_grpid) < 0) return NC_EHDFERR; grp->hdf_grpid = 0; /* Attempt to rename & re-open the group, if the parent group is open */ if (grp->parent->hdf_grpid) { /* Rename the group */ if (H5Gmove(grp->parent->hdf_grpid, grp->name, name) < 0) return NC_EHDFERR; /* Reopen the group, with the new name */ if ((grp->hdf_grpid = H5Gopen2(grp->parent->hdf_grpid, name, H5P_DEFAULT)) < 0) return NC_EHDFERR; } } /* Give the group its new name in metadata. UTF8 normalization * has been done. */ free(grp->name); if (!(grp->name = malloc((strlen(norm_name) + 1) * sizeof(char)))) return NC_ENOMEM; strcpy(grp->name, norm_name); return NC_NOERR; }