/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 | } |