Coverage Report

Created: 2026-03-30 09:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gdal/netcdf-c-4.7.4/libhdf5/hdf5grp.c
Line
Count
Source
1
/* Copyright 2005-2018, University Corporation for Atmospheric
2
 * Research. See COPYRIGHT file for copying and redistribution
3
 * conditions. */
4
/**
5
 * @file @internal This file is part of netcdf-4, a netCDF-like
6
 * interface for HDF5, or a HDF5 backend for netCDF, depending on your
7
 * point of view.
8
 *
9
 * This file handles HDF5 groups.
10
 *
11
 * @author Ed Hartnett
12
 */
13
14
#include "config.h"
15
#include "hdf5internal.h"
16
17
/**
18
 * @internal Create a group. Its ncid is returned in the new_ncid
19
 * pointer.
20
 *
21
 * @param parent_ncid Parent group.
22
 * @param name Name of new group.
23
 * @param new_ncid Pointer that gets ncid for new group.
24
 *
25
 * @return ::NC_NOERR No error.
26
 * @return ::NC_EBADID Bad ncid.
27
 * @return ::NC_ESTRICTNC3 Classic model in use for this file.
28
 * @return ::NC_ENOTNC4 Not a netCDF-4 file.
29
 * @author Ed Hartnett
30
 */
31
int
32
NC4_def_grp(int parent_ncid, const char *name, int *new_ncid)
33
0
{
34
0
    NC_GRP_INFO_T *grp, *g;
35
0
    NC_FILE_INFO_T *h5;
36
0
    char norm_name[NC_MAX_NAME + 1];
37
0
    int retval;
38
39
0
    LOG((2, "%s: parent_ncid 0x%x name %s", __func__, parent_ncid, name));
40
41
    /* Find info for this file and group, and set pointer to each. */
42
0
    if ((retval = nc4_find_grp_h5(parent_ncid, &grp, &h5)))
43
0
        return retval;
44
0
    assert(h5);
45
46
    /* Check and normalize the name. */
47
0
    if ((retval = nc4_check_name(name, norm_name)))
48
0
        return retval;
49
50
    /* Check that this name is not in use as a var, grp, or type. */
51
0
    if ((retval = nc4_check_dup_name(grp, norm_name)))
52
0
        return retval;
53
54
    /* No groups in netcdf-3! */
55
0
    if (h5->cmode & NC_CLASSIC_MODEL)
56
0
        return NC_ESTRICTNC3;
57
58
    /* If it's not in define mode, switch to define mode. */
59
0
    if (!(h5->flags & NC_INDEF))
60
0
        if ((retval = NC4_redef(parent_ncid)))
61
0
            return retval;
62
63
    /* Update internal lists to reflect new group. The actual HDF5
64
     * group creation will be done when metadata is written by a
65
     * sync. */
66
0
    if ((retval = nc4_grp_list_add(h5, grp, norm_name, &g)))
67
0
        return retval;
68
0
    if (!(g->format_grp_info = calloc(1, sizeof(NC_HDF5_GRP_INFO_T))))
69
0
        return NC_ENOMEM;
70
71
    /* For new groups, there are no atts to read from file. */
72
0
    g->atts_read = 1;
73
74
    /* Return the ncid to the user. */
75
0
    if (new_ncid)
76
0
        *new_ncid = grp->nc4_info->controller->ext_ncid | g->hdr.id;
77
78
0
    return NC_NOERR;
79
0
}
80
81
/**
82
 * @internal Rename a group.
83
 *
84
 * @param grpid Group ID.
85
 * @param name New name for group.
86
 *
87
 * @return ::NC_NOERR No error.
88
 * @return ::NC_EBADID Bad ncid.
89
 * @return ::NC_ENOTNC4 Not a netCDF-4 file.
90
 * @return ::NC_EPERM File opened read-only.
91
 * @return ::NC_EBADGRPID Renaming root forbidden.
92
 * @return ::NC_EHDFERR HDF5 function returned error.
93
 * @return ::NC_ENOMEM Out of memory.
94
 * @author Ed Hartnett
95
 */
96
int
97
NC4_rename_grp(int grpid, const char *name)
98
0
{
99
0
    NC_GRP_INFO_T *grp;
100
0
    NC_HDF5_GRP_INFO_T *hdf5_grp;
101
0
    NC_FILE_INFO_T *h5;
102
0
    char norm_name[NC_MAX_NAME + 1];
103
0
    int retval;
104
105
0
    LOG((2, "nc_rename_grp: grpid 0x%x name %s", grpid, name));
106
107
    /* Find info for this file and group, and set pointer to each. */
108
0
    if ((retval = nc4_find_grp_h5(grpid, &grp, &h5)))
109
0
        return retval;
110
0
    assert(h5 && grp && grp->format_grp_info);
111
112
    /* Get HDF5-specific group info. */
113
0
    hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->format_grp_info;
114
115
0
    if (h5->no_write)
116
0
        return NC_EPERM; /* attempt to write to a read-only file */
117
118
    /* Do not allow renaming the root group */
119
0
    if (grp->parent == NULL)
120
0
        return NC_EBADGRPID;
121
122
    /* Check and normalize the name. */
123
0
    if ((retval = nc4_check_name(name, norm_name)))
124
0
        return retval;
125
126
    /* Check that this name is not in use as a var, grp, or type in the
127
     * parent group (i.e. the group that grp is in). */
128
0
    if ((retval = nc4_check_dup_name(grp->parent, norm_name)))
129
0
        return retval;
130
131
    /* If it's not in define mode, switch to define mode. */
132
0
    if (!(h5->flags & NC_INDEF))
133
0
        if ((retval = NC4_redef(grpid)))
134
0
            return retval;
135
136
    /* Rename the group, if it exists in the file */
137
0
    if (hdf5_grp->hdf_grpid)
138
0
    {
139
0
        NC_HDF5_GRP_INFO_T *parent_hdf5_grp;
140
0
        parent_hdf5_grp = (NC_HDF5_GRP_INFO_T *)grp->parent->format_grp_info;
141
142
        /* Close the group */
143
0
        if (H5Gclose(hdf5_grp->hdf_grpid) < 0)
144
0
            return NC_EHDFERR;
145
0
        hdf5_grp->hdf_grpid = 0;
146
147
        /* Attempt to rename & re-open the group, if the parent group is open */
148
0
        if (parent_hdf5_grp->hdf_grpid)
149
0
        {
150
            /* Rename the group. */
151
0
            if (H5Lmove(parent_hdf5_grp->hdf_grpid, grp->hdr.name,
152
0
                        parent_hdf5_grp->hdf_grpid, name, H5P_DEFAULT,
153
0
                        H5P_DEFAULT) < 0)
154
0
                return NC_EHDFERR;
155
156
            /* Reopen the group, with the new name. */
157
0
            if ((hdf5_grp->hdf_grpid = H5Gopen2(parent_hdf5_grp->hdf_grpid, name,
158
0
                                                H5P_DEFAULT)) < 0)
159
0
                return NC_EHDFERR;
160
0
        }
161
0
    }
162
163
    /* Give the group its new name in metadata. UTF8 normalization
164
     * has been done. */
165
0
    free(grp->hdr.name);
166
0
    if (!(grp->hdr.name = strdup(norm_name)))
167
0
        return NC_ENOMEM;
168
169
    /* Update the hash and rebuild index. */
170
0
    grp->hdr.hashkey = NC_hashmapkey(grp->hdr.name,strlen(grp->hdr.name));
171
0
    if(!ncindexrebuild(grp->parent->children))
172
0
        return NC_EINTERNAL;
173
174
0
    return NC_NOERR;
175
0
}