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