Coverage Report

Created: 2023-05-28 06:42

/src/netcdf-c/libnczarr/zgrp.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright 2005-2018, University Corporation for Atmospheric
2
 * Research. See COPYRIGHT file for copying and redistribution
3
 * conditions. */
4
5
/**
6
 * @file @internal This file is part of netcdf-4, a netCDF-like
7
 * interface for NCZ, or a ZARR backend for netCDF, depending on your
8
 * point of view.
9
 *
10
 * This file handles ZARR groups.
11
 *
12
 * @author Dennis Heimbigner, Ed Hartnett
13
 */
14
15
#include "zincludes.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 Dennis Heimbigner, Ed Hartnett
30
 */
31
int
32
NCZ_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 stat;
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 ((stat = nc4_find_grp_h5(parent_ncid, &grp, &h5)))
43
0
        return stat;
44
0
    assert(h5);
45
46
    /* Check and normalize the name. */
47
0
    if ((stat = nc4_check_name(name, norm_name)))
48
0
        return stat;
49
50
    /* Check that this name is not in use as a var, grp, or type. */
51
0
    if ((stat = nc4_check_dup_name(grp, norm_name)))
52
0
        return stat;
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 ((stat = NCZ_redef(parent_ncid)))
61
0
            return stat;
62
63
    /* Update internal lists to reflect new group. The actual NCZ
64
     * group creation will be done when metadata is written by a
65
     * sync. */
66
0
    if ((stat = nc4_grp_list_add(h5, grp, norm_name, &g)))
67
0
        return stat;
68
0
    if (!(g->format_grp_info = calloc(1, sizeof(NCZ_GRP_INFO_T))))
69
0
        return NC_ENOMEM;
70
0
    ((NCZ_GRP_INFO_T*)g->format_grp_info)->common.file = h5;
71
72
    /* For new groups, there are no atts to read from file. */
73
0
    g->atts_read = 1;
74
75
    /* Return the ncid to the user. */
76
0
    if (new_ncid)
77
0
        *new_ncid = grp->nc4_info->controller->ext_ncid | g->hdr.id;
78
79
0
    return NC_NOERR;
80
0
}
81
82
/**
83
 * @internal Rename a group.
84
 *
85
 * @param grpid Group ID.
86
 * @param name New name for group.
87
 *
88
 * @return ::NC_NOERR No error.
89
 * @return ::NC_EBADID Bad ncid.
90
 * @return ::NC_ENOTNC4 Not a netCDF-4 file.
91
 * @return ::NC_EPERM File opened read-only.
92
 * @return ::NC_EBADGRPID Renaming root forbidden.
93
 * @return ::NC_EHDFERR ZARR function returned error.
94
 * @return ::NC_ENOMEM Out of memory.
95
 * @author Dennis Heimbigner, Ed Hartnett
96
 */
97
int
98
NCZ_rename_grp(int grpid, const char *name)
99
0
{
100
0
    NC_GRP_INFO_T *grp;
101
0
    NC_FILE_INFO_T *h5;
102
0
    char norm_name[NC_MAX_NAME + 1];
103
0
    int stat;
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 ((stat = nc4_find_grp_h5(grpid, &grp, &h5)))
109
0
        return stat;
110
0
    assert(h5 && grp && grp->format_grp_info);
111
112
0
    if (h5->no_write)
113
0
        return NC_EPERM; /* attempt to write to a read-only file */
114
115
    /* Do not allow renaming the root group */
116
0
    if (grp->parent == NULL)
117
0
        return NC_EBADGRPID;
118
119
    /* Check and normalize the name. */
120
0
    if ((stat = nc4_check_name(name, norm_name)))
121
0
        return stat;
122
123
    /* Check that this name is not in use as a var, grp, or type in the
124
     * parent group (i.e. the group that grp is in). */
125
0
    if ((stat = nc4_check_dup_name(grp->parent, norm_name)))
126
0
        return stat;
127
128
    /* If it's not in define mode, switch to define mode. */
129
0
    if (!(h5->flags & NC_INDEF))
130
0
        if ((stat = NCZ_redef(grpid)))
131
0
            return stat;
132
133
#ifdef LOOK
134
    /* Rename the group, if it exists in the file */
135
    if (zgrp->hdf_grpid)
136
    {
137
        ZGRP_INFO_T *parent_zgrp;
138
        parent_zgrp = (ZGRP_INFO_T *)grp->parent->format_grp_info;
139
140
        /* Close the group */
141
        if (H5Gclose(zgrp->hdf_grpid) < 0)
142
            return NC_EHDFERR;
143
        zgrp->hdf_grpid = 0;
144
145
        /* Attempt to rename & re-open the group, if the parent group is open */
146
        if (parent_zgrp->hdf_grpid)
147
        {
148
            /* Rename the group. */
149
            if (H5Lmove(parent_zgrp->hdf_grpid, grp->hdr.name,
150
                        parent_zgrp->hdf_grpid, name, H5P_DEFAULT,
151
                        H5P_DEFAULT) < 0)
152
                return NC_EHDFERR;
153
154
            /* Reopen the group, with the new name. */
155
            if ((zgrp->hdf_grpid = H5Gopen2(parent_zgrp->hdf_grpid, name,
156
                                                H5P_DEFAULT)) < 0)
157
                return NC_EHDFERR;
158
        }
159
    }
160
#endif
161
162
    /* Give the group its new name in metadata. UTF8 normalization
163
     * has been done. */
164
0
    free(grp->hdr.name);
165
0
    if (!(grp->hdr.name = strdup(norm_name)))
166
0
        return NC_ENOMEM;
167
168
    /* rebuild index. */
169
0
    if(!ncindexrebuild(grp->parent->children))
170
0
        return NC_EINTERNAL;
171
172
0
    return NC_NOERR;
173
0
}