1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
|
/* 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 HDF5, or a HDF5 backend for netCDF, depending on your
* point of view.
*
* This file handles HDF5 groups.
*
* @author Ed Hartnett
*/
#include "config.h"
#include "hdf5internal.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 Ed Hartnett
*/
int
NC4_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 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;
assert(h5);
/* 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(h5, grp, norm_name, &g)))
return retval;
if (!(g->format_grp_info = calloc(1, sizeof(NC_HDF5_GRP_INFO_T))))
return NC_ENOMEM;
/* 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 HDF5 function returned error.
* @return ::NC_ENOMEM Out of memory.
* @author Ed Hartnett
*/
int
NC4_rename_grp(int grpid, const char *name)
{
NC_GRP_INFO_T *grp;
NC_HDF5_GRP_INFO_T *hdf5_grp;
NC_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;
assert(h5 && grp && grp->format_grp_info);
/* Get HDF5-specific group info. */
hdf5_grp = (NC_HDF5_GRP_INFO_T *)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 ((retval = nc4_check_name(name, norm_name)))
return retval;
/* 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 ((retval = nc4_check_dup_name(grp->parent, 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 (hdf5_grp->hdf_grpid)
{
NC_HDF5_GRP_INFO_T *parent_hdf5_grp;
parent_hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->parent->format_grp_info;
/* Close the group */
if (H5Gclose(hdf5_grp->hdf_grpid) < 0)
return NC_EHDFERR;
hdf5_grp->hdf_grpid = 0;
/* Attempt to rename & re-open the group, if the parent group is open */
if (parent_hdf5_grp->hdf_grpid)
{
/* Rename the group. */
if (H5Lmove(parent_hdf5_grp->hdf_grpid, grp->hdr.name,
parent_hdf5_grp->hdf_grpid, name, H5P_DEFAULT,
H5P_DEFAULT) < 0)
return NC_EHDFERR;
/* Reopen the group, with the new name. */
if ((hdf5_grp->hdf_grpid = H5Gopen2(parent_hdf5_grp->hdf_grpid, name,
H5P_DEFAULT)) < 0)
return NC_EHDFERR;
}
}
/* 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;
}
|