/* Copyright 2005-2018, University Corporation for Atmospheric * Research. See COPYRIGHT file for copying and redistribution * conditions. */ /** * @file @internal This file is part of netcdf-4, a netCDF-like * interface for NCZ, or a ZARR backend for netCDF, depending on your * point of view. * * This file handles ZARR groups. * * @author Dennis Heimbigner, Ed Hartnett */ #include "zincludes.h" /** * @internal Create a group. Its ncid is returned in the new_ncid * pointer. * * @param parent_ncid Parent group. * @param name Name of new group. * @param new_ncid Pointer that gets ncid for new group. * * @return ::NC_NOERR No error. * @return ::NC_EBADID Bad ncid. * @return ::NC_ESTRICTNC3 Classic model in use for this file. * @return ::NC_ENOTNC4 Not a netCDF-4 file. * @author Dennis Heimbigner, Ed Hartnett */ int NCZ_def_grp(int parent_ncid, const char *name, int *new_ncid) { NC_GRP_INFO_T *grp, *g; NC_FILE_INFO_T *h5; char norm_name[NC_MAX_NAME + 1]; int stat; 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 ((stat = nc4_find_grp_h5(parent_ncid, &grp, &h5))) return stat; assert(h5); /* Check and normalize the name. */ if ((stat = nc4_check_name(name, norm_name))) return stat; /* Check that this name is not in use as a var, grp, or type. */ if ((stat = nc4_check_dup_name(grp, norm_name))) return stat; /* 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 ((stat = NCZ_redef(parent_ncid))) return stat; /* Update internal lists to reflect new group. The actual NCZ * group creation will be done when metadata is written by a * sync. */ if ((stat = nc4_grp_list_add(h5, grp, norm_name, &g))) return stat; if (!(g->format_grp_info = calloc(1, sizeof(NCZ_GRP_INFO_T)))) return NC_ENOMEM; ((NCZ_GRP_INFO_T*)g->format_grp_info)->common.file = h5; /* For new groups, there are no atts to read from file. */ g->atts_read = 1; /* Return the ncid to the user. */ if (new_ncid) *new_ncid = grp->nc4_info->controller->ext_ncid | g->hdr.id; return NC_NOERR; } /** * @internal Rename a group. * * @param grpid Group ID. * @param name New name for group. * * @return ::NC_NOERR No error. * @return ::NC_EBADID Bad ncid. * @return ::NC_ENOTNC4 Not a netCDF-4 file. * @return ::NC_EPERM File opened read-only. * @return ::NC_EBADGRPID Renaming root forbidden. * @return ::NC_EHDFERR ZARR function returned error. * @return ::NC_ENOMEM Out of memory. * @author Dennis Heimbigner, Ed Hartnett */ int NCZ_rename_grp(int grpid, const char *name) { NC_GRP_INFO_T *grp; NC_FILE_INFO_T *h5; char norm_name[NC_MAX_NAME + 1]; int stat; 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 ((stat = nc4_find_grp_h5(grpid, &grp, &h5))) return stat; assert(h5 && grp && grp->format_grp_info); 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 ((stat = nc4_check_name(name, norm_name))) return stat; /* Check that this name is not in use as a var, grp, or type in the * parent group (i.e. the group that grp is in). */ if ((stat = nc4_check_dup_name(grp->parent, norm_name))) return stat; /* If it's not in define mode, switch to define mode. */ if (!(h5->flags & NC_INDEF)) if ((stat = NCZ_redef(grpid))) return stat; #ifdef LOOK /* Rename the group, if it exists in the file */ if (zgrp->hdf_grpid) { ZGRP_INFO_T *parent_zgrp; parent_zgrp = (ZGRP_INFO_T *)grp->parent->format_grp_info; /* Close the group */ if (H5Gclose(zgrp->hdf_grpid) < 0) return NC_EHDFERR; zgrp->hdf_grpid = 0; /* Attempt to rename & re-open the group, if the parent group is open */ if (parent_zgrp->hdf_grpid) { /* Rename the group. */ if (H5Lmove(parent_zgrp->hdf_grpid, grp->hdr.name, parent_zgrp->hdf_grpid, name, H5P_DEFAULT, H5P_DEFAULT) < 0) return NC_EHDFERR; /* Reopen the group, with the new name. */ if ((zgrp->hdf_grpid = H5Gopen2(parent_zgrp->hdf_grpid, name, H5P_DEFAULT)) < 0) return NC_EHDFERR; } } #endif /* Give the group its new name in metadata. UTF8 normalization * has been done. */ free(grp->hdr.name); if (!(grp->hdr.name = strdup(norm_name))) return NC_ENOMEM; /* rebuild index. */ if(!ncindexrebuild(grp->parent->children)) return NC_EINTERNAL; return NC_NOERR; }